PageRenderTime 42ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/Mad/Support/Object.php

http://github.com/maintainable/framework
PHP | 301 lines | 87 code | 15 blank | 199 comment | 13 complexity | 0cec92fd428c879d4b7e9172bdbe4882 MD5 | raw file
  1. <?php
  2. /**
  3. * @category Mad
  4. * @package Mad_Support
  5. * @copyright (c) 2007-2009 Maintainable Software, LLC
  6. * @license http://opensource.org/licenses/bsd-license.php BSD
  7. */
  8. /**
  9. * @category Mad
  10. * @package Mad_Support
  11. * @copyright (c) 2007-2009 Maintainable Software, LLC
  12. * @license http://opensource.org/licenses/bsd-license.php BSD
  13. */
  14. class Mad_Support_Object
  15. {
  16. /**
  17. * List of attributes available for reading
  18. * @var array
  19. */
  20. protected $_attrReaders = array();
  21. /**
  22. * List of attribute available for writing
  23. * @var array
  24. */
  25. protected $_attrWriters = array();
  26. /**
  27. * anonymous attribute values
  28. * @var array
  29. */
  30. protected $_attrValues = array();
  31. /**
  32. * Dynamically get value for an attribute.
  33. *
  34. * @param string $name
  35. * @return string
  36. * @throws Mad_Support_Exception
  37. */
  38. public function __get($name)
  39. {
  40. // attribute-reader value
  41. if (in_array($name, $this->_attrReaders)) {
  42. return $this->_getAttribute($name);
  43. }
  44. // call overloading for subclass
  45. if (method_exists($this, '_get')) {
  46. return $this->_get($name);
  47. }
  48. throw new Mad_Support_Exception("Unrecognized attribute '$name'");
  49. }
  50. /**
  51. * Dynamically set value for an attribute. Attributes cannot be set once an
  52. * object has been destroyed. Primary Key cannot be changed if the data was
  53. * loaded from a database row
  54. *
  55. * @param string $name
  56. * @param mixed $value
  57. * @throws Mad_Support_Exception
  58. */
  59. public function __set($name, $value)
  60. {
  61. // attribute-writer value
  62. if (in_array($name, $this->_attrWriters)) {
  63. return $this->_setAttribute($name, $value);
  64. }
  65. // call overloading for subclass
  66. if (method_exists($this, '_set')) {
  67. return $this->_set($name, $value);
  68. }
  69. throw new Mad_Support_Exception("Unrecognized attribute '$name'");
  70. }
  71. // check if items are set
  72. public function __isset($name)
  73. {
  74. // attribute-reader value
  75. if (in_array($name, $this->_attrReaders)) {
  76. $value = $this->_getAttribute($name);
  77. return !empty($value);
  78. }
  79. // call overloading for subclass
  80. if (method_exists($this, '_isset')) {
  81. return $this->_isset($name);
  82. }
  83. }
  84. /*##########################################################################
  85. # Attributes
  86. ##########################################################################*/
  87. /**
  88. * Add list of attribute readers for this object.
  89. *
  90. * Multiple readers can be set at once.
  91. *
  92. * {{code: php
  93. * class User extends Mad_Model_Base
  94. * {
  95. * protected $_foo = null;
  96. * protected $_bar = null;
  97. * protected $_baz = null;
  98. *
  99. * public function _initialize()
  100. * {
  101. * $this->attrReader('foo', 'bar', 'baz');
  102. * }
  103. *
  104. * // this overrides retrieving default value from the property
  105. * // and allows us to split the value when it is retrieved
  106. * public function getFoo($name)
  107. * {
  108. * return explode(', ', 'foo');
  109. * }
  110. * }
  111. * }}
  112. *
  113. * When readers are accessed, they will attempt to first
  114. * read a public method prefixed with `get`. If this method
  115. * is missing, we'll fall back to a generic hash.
  116. *
  117. * {{code: php
  118. * $user = new User;
  119. *
  120. * // our attribute reader called "getFoo" will be executed
  121. * print $user->foo; // => 'foo'
  122. *
  123. * // when no proxy method is defined, we just return $_bar's value
  124. * print $user->bar; // => null
  125. * }}
  126. *
  127. * @param varargs $attributes
  128. */
  129. public function attrReader($attributes)
  130. {
  131. $names = func_get_args();
  132. $this->_attrReaders = array_unique(
  133. array_merge($this->_attrReaders, $names));
  134. }
  135. /**
  136. * Add list of attribute writers for this object.
  137. *
  138. * Multiple writers can be set at once.
  139. *
  140. * {{code: php
  141. * class User extends Mad_Model_Base
  142. * {
  143. * protected $_foo = null;
  144. * protected $_bar = null;
  145. * protected $_baz = null;
  146. *
  147. * public function _initialize()
  148. * {
  149. * $this->attrWriter('foo', 'bar', 'baz');
  150. * $this->attrReader('foo');
  151. * }
  152. *
  153. * // this overrides setting default value from $_foo and
  154. * // allows us to join the array value before it is assigned
  155. * public function setFoo($value)
  156. * {
  157. * $this->_foo = join(', ', $value);
  158. * }
  159. * }
  160. * }}
  161. *
  162. * When writers are accessed, they will attempt to first
  163. * use a public method prefixed with `set`. If this method
  164. * is missing, we'll fall back to a generic hash.
  165. *
  166. * {{code: php
  167. * // we pass in the "foo" attribute as an array
  168. * $user = new User;
  169. * $user->foo = array('derek', 'mike');
  170. *
  171. * // our attribute writer called "setFoo" to join it to a string
  172. * print $user->foo; // => "derek, mike"
  173. *
  174. * // when no proxy method is defined, we just set $_bar's value
  175. * $user->bar = 'test';
  176. * }}
  177. *
  178. * @param varargs $attributes
  179. */
  180. public function attrWriter($attributes)
  181. {
  182. $names = func_get_args();
  183. $this->_attrWriters = array_unique(
  184. array_merge($this->_attrWriters, $names));
  185. }
  186. /**
  187. * Add list of attribute reader/writers for this object.
  188. *
  189. * Multiple accessors can be set at once.
  190. *
  191. * {{code: php
  192. * class User extends Mad_Model_Base
  193. * {
  194. * protected $_foo => null;
  195. * protected $_bar => null;
  196. *
  197. * public function _initialize()
  198. * {
  199. * $this->attrAccessor('foo', 'bar');
  200. * }
  201. *
  202. * // enclose entire string in quotes
  203. * public function getFoo()
  204. * {
  205. * return '"'.$this->_foo.'"';
  206. * }
  207. *
  208. * // strip out commas from value
  209. * public function setFoo($value)
  210. * {
  211. * $this->_foo = str_replace(',', '', $value);
  212. * }
  213. * }
  214. * }}
  215. *
  216. * When accessors are accessed, they will attempt to first
  217. * read a public method prefixed with `get` or `set`. If these method
  218. * are missing, we'll fall back to the protected property value.
  219. *
  220. * {{code: php
  221. * // This allows us to set/get the "foo" property
  222. * $user = new User;
  223. * $user->foo = 'hey, there'
  224. *
  225. * print $user->foo; // => '"hey there"'
  226. *
  227. * // when no proxy method is defined, we just return $_bar's value
  228. * $user->bar = 'test';
  229. * print $user->bar; // => 'test'
  230. * }}
  231. *
  232. * @param varargs $attributes
  233. */
  234. public function attrAccessor($attributes)
  235. {
  236. $names = func_get_args();
  237. $this->_attrReaders = array_unique(
  238. array_merge($this->_attrReaders, $names));
  239. $this->_attrWriters = array_unique(
  240. array_merge($this->_attrWriters, $names));
  241. }
  242. /**
  243. * Get the value for an attribute in this object.
  244. *
  245. * @param string $name
  246. * @return string
  247. */
  248. protected function _getAttribute($name)
  249. {
  250. // check for reader proxy method
  251. $underscore = Mad_Support_Inflector::underscore("get_$name");
  252. $methodName = Mad_Support_Inflector::camelize($underscore, 'lower');
  253. if (method_exists($this, $methodName)) {
  254. return $this->$methodName();
  255. } else {
  256. $property = "_$name";
  257. if (property_exists($this, $property)) {
  258. return $this->$property;
  259. }
  260. return isset($this->_attrValues[$name]) ? $this->_attrValues[$name] : null;
  261. }
  262. return null;
  263. }
  264. /**
  265. * Set the value for an attribute in this object.
  266. *
  267. * @param string $name
  268. * @param mixed $value
  269. */
  270. protected function _setAttribute($name, $value)
  271. {
  272. // check for writer proxy method
  273. $underscore = Mad_Support_Inflector::underscore("set_$name");
  274. $methodName = Mad_Support_Inflector::camelize($underscore, 'lower');
  275. if (method_exists($this, $methodName)) {
  276. $this->$methodName($value);
  277. } else {
  278. $property = "_$name";
  279. if (property_exists($this, $property)) {
  280. $this->$property = $value;
  281. } else {
  282. $this->_attrValues[$name] = $value;
  283. }
  284. }
  285. }
  286. }