1. sfUser.class.php
  2. /** * * sfUser wraps a client session and provides accessor methods for user * attributes. It also makes storing and retrieving multiple page form data * rather easy by allowing user attributes to be stored in namespaces, which * help organize data. * * @package symfony * @subpackage user * @author Fabien Potencier * @author Sean Kerr * @version SVN: $Id: sfUser.class.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $ */
  3. class sfUser implements ArrayAccess
  4. {
  5. /**
  6. * The namespace under which attributes will be stored.
  7. */
  8. const ATTRIBUTE_NAMESPACE = 'symfony/user/sfUser/attributes';
  9. const CULTURE_NAMESPACE = 'symfony/user/sfUser/culture';
  10. protected
  11. $options = array(),
  12. $attributeHolder = null,
  13. $culture = null,
  14. $storage = null,
  15. $dispatcher = null;
  16. /**
  17. * Class constructor.
  18. *
  19. * @see initialize()
  20. */
  21. public function __construct(sfEventDispatcher $dispatcher, sfStorage $storage, $options = array())
  22. {
  23. $this->initialize($dispatcher, $storage, $options);
  24. if ($this->options['auto_shutdown'])
  25. {
  26. register_shutdown_function(array($this, 'shutdown'));
  27. }
  28. }
  29. /**
  30. * Initializes this sfUser.
  31. *
  32. * Available options:
  33. *
  34. * * auto_shutdown: Whether to automatically save the changes to the session (true by default)
  35. * * culture: The user culture
  36. * * default_culture: The default user culture (en by default)
  37. * * use_flash: Whether to enable flash usage (false by default)
  38. * * logging: Whether to enable logging (false by default)
  39. *
  40. * @param sfEventDispatcher $dispatcher An sfEventDispatcher instance.
  41. * @param sfStorage $storage An sfStorage instance.
  42. * @param array $options An associative array of options.
  43. *
  44. * @return Boolean true, if initialization completes successfully, otherwise false.
  45. */
  46. public function initialize(sfEventDispatcher $dispatcher, sfStorage $storage, $options = array())
  47. {
  48. $this->dispatcher = $dispatcher;
  49. $this->storage = $storage;
  50. $this->options = array_merge(array(
  51. 'auto_shutdown' => true,
  52. 'culture' => null,
  53. 'default_culture' => 'en',
  54. 'use_flash' => false,
  55. 'logging' => false,
  56. ), $options);
  57. $this->attributeHolder = new sfNamespacedParameterHolder(self::ATTRIBUTE_NAMESPACE);
  58. // read attributes from storage
  59. $attributes = $storage->read(self::ATTRIBUTE_NAMESPACE);
  60. if (is_array($attributes))
  61. {
  62. foreach ($attributes as $namespace => $values)
  63. {
  64. $this->attributeHolder->add($values, $namespace);
  65. }
  66. }
  67. // set the user culture to sf_culture parameter if present in the request
  68. // otherwise
  69. // - use the culture defined in the user session
  70. // - use the default culture set in settings.yml
  71. $currentCulture = $storage->read(self::CULTURE_NAMESPACE);
  72. $this->setCulture(null !== $this->options['culture'] ? $this->options['culture'] : (null !== $currentCulture ? $currentCulture : $this->options['default_culture']));
  73. // flag current flash to be removed at shutdown
  74. if ($this->options['use_flash'] && $names = $this->attributeHolder->getNames('symfony/user/sfUser/flash'))
  75. {
  76. if ($this->options['logging'])
  77. {
  78. $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Flag old flash messages ("%s")', implode('", "', $names)))));
  79. }
  80. foreach ($names as $name)
  81. {
  82. $this->attributeHolder->set($name, true, 'symfony/user/sfUser/flash/remove');
  83. }
  84. }
  85. }
  86. /**
  87. * Returns the initialization options
  88. *
  89. * @return array The options used to initialize sfUser
  90. */
  91. public function getOptions()
  92. {
  93. return $this->options;
  94. }
  95. /**
  96. * Sets the user culture.
  97. *
  98. * @param string $culture
  99. */
  100. public function setCulture($culture)
  101. {
  102. if ($this->culture != $culture)
  103. {
  104. $this->culture = $culture;
  105. $this->dispatcher->notify(new sfEvent($this, 'user.change_culture', array('culture' => $culture)));
  106. }
  107. }
  108. /**
  109. * Sets a flash variable that will be passed to the very next action.
  110. *
  111. * @param string $name The name of the flash variable
  112. * @param string $value The value of the flash variable
  113. * @param bool $persist true if the flash have to persist for the following request (true by default)
  114. */
  115. public function setFlash($name, $value, $persist = true)
  116. {
  117. if (!$this->options['use_flash'])
  118. {
  119. return;
  120. }
  121. $this->setAttribute($name, $value, 'symfony/user/sfUser/flash');
  122. if ($persist)
  123. {
  124. // clear removal flag
  125. $this->attributeHolder->remove($name, null, 'symfony/user/sfUser/flash/remove');
  126. }
  127. else
  128. {
  129. $this->setAttribute($name, true, 'symfony/user/sfUser/flash/remove');
  130. }
  131. }
  132. /**
  133. * Gets a flash variable.
  134. *
  135. * @param string $name The name of the flash variable
  136. * @param string $default The default value returned when named variable does not exist.
  137. *
  138. * @return mixed The value of the flash variable
  139. */
  140. public function getFlash($name, $default = null)
  141. {
  142. if (!$this->options['use_flash'])
  143. {
  144. return $default;
  145. }
  146. return $this->getAttribute($name, $default, 'symfony/user/sfUser/flash');
  147. }
  148. /**
  149. * Returns true if a flash variable of the specified name exists.
  150. *
  151. * @param string $name The name of the flash variable
  152. *
  153. * @return bool true if the variable exists, false otherwise
  154. */
  155. public function hasFlash($name)
  156. {
  157. if (!$this->options['use_flash'])
  158. {
  159. return false;
  160. }
  161. return $this->hasAttribute($name, 'symfony/user/sfUser/flash');
  162. }
  163. /**
  164. * Gets culture.
  165. *
  166. * @return string
  167. */
  168. public function getCulture()
  169. {
  170. return $this->culture;
  171. }
  172. /**
  173. * Returns true if the user attribute exists (implements the ArrayAccess interface).
  174. *
  175. * @param string $name The name of the user attribute
  176. *
  177. * @return Boolean true if the user attribute exists, false otherwise
  178. */
  179. public function offsetExists($name)
  180. {
  181. return $this->hasAttribute($name);
  182. }
  183. /**
  184. * Returns the user attribute associated with the name (implements the ArrayAccess interface).
  185. *
  186. * @param string $name The offset of the value to get
  187. *
  188. * @return mixed The user attribute if exists, null otherwise
  189. */
  190. public function offsetGet($name)
  191. {
  192. return $this->getAttribute($name, false);
  193. }
  194. /**
  195. * Sets the user attribute associated with the offset (implements the ArrayAccess interface).
  196. *
  197. * @param string $offset The parameter name
  198. * @param string $value The parameter value
  199. */
  200. public function offsetSet($offset, $value)
  201. {
  202. $this->setAttribute($offset, $value);
  203. }
  204. /**
  205. * Unsets the user attribute associated with the offset (implements the ArrayAccess interface).
  206. *
  207. * @param string $offset The parameter name
  208. */
  209. public function offsetUnset($offset)
  210. {
  211. $this->getAttributeHolder()->remove($offset);
  212. }
  213. public function getAttributeHolder()
  214. {
  215. return $this->attributeHolder;
  216. }
  217. public function getAttribute($name, $default = null, $ns = null)
  218. {
  219. return $this->attributeHolder->get($name, $default, $ns);
  220. }
  221. public function hasAttribute($name, $ns = null)
  222. {
  223. return $this->attributeHolder->has($name, $ns);
  224. }
  225. public function setAttribute($name, $value, $ns = null)
  226. {
  227. return $this->attributeHolder->set($name, $value, $ns);
  228. }
  229. /**
  230. * Executes the shutdown procedure.
  231. */
  232. public function shutdown()
  233. {
  234. // remove flash that are tagged to be removed
  235. if ($this->options['use_flash'] && $names = $this->attributeHolder->getNames('symfony/user/sfUser/flash/remove'))
  236. {
  237. if ($this->options['logging'])
  238. {
  239. $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Remove old flash messages ("%s")', implode('", "', $names)))));
  240. }
  241. foreach ($names as $name)
  242. {
  243. $this->attributeHolder->remove($name, null, 'symfony/user/sfUser/flash');
  244. $this->attributeHolder->remove($name, null, 'symfony/user/sfUser/flash/remove');
  245. }
  246. }
  247. $attributes = array();
  248. foreach ($this->attributeHolder->getNamespaces() as $namespace)
  249. {
  250. $attributes[$namespace] = $this->attributeHolder->getAll($namespace);
  251. }
  252. // write attributes to the storage
  253. $this->storage->write(self::ATTRIBUTE_NAMESPACE, $attributes);
  254. // write culture to the storage
  255. $this->storage->write(self::CULTURE_NAMESPACE, $this->culture);
  256. }
  257. /**
  258. * Calls methods defined via sfEventDispatcher.
  259. *
  260. * @param string $method The method name
  261. * @param array $arguments The method arguments
  262. *
  263. * @return mixed The returned value of the called method
  264. *
  265. * @throws sfException If the calls fails
  266. */
  267. public function __call($method, $arguments)
  268. {
  269. $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'user.method_not_found', array('method' => $method, 'arguments' => $arguments)));
  270. if (!$event->isProcessed())
  271. {
  272. throw new sfException(sprintf('Call to undefined method %s::%s.', get_class($this), $method));
  273. }
  274. return $event->getReturnValue();
  275. }
  276. }

Debug toolbar