···229229 static $delegate = array();
230230231231 /**
232232- * Define customer setters methods for the model.
232232+ * Constructs a model.
233233 *
234234- * You can also use this to define custom setters for attributes as well.
234234+ * When a user instantiates a new object (e.g.: it was not ActiveRecord that instantiated via a find)
235235+ * then @var $attributes will be mapped according to the schema's defaults. Otherwise, the given
236236+ * $attributes will be mapped via set_attributes_via_mass_assignment.
235237 *
236238 * <code>
237237- * class User extends ActiveRecord\Model {
238238- * static $setters = array('password','more','even_more');
239239- *
240240- * # now to define the setter methods. Note you must
241241- * # prepend set_ to your method name:
242242- * function set_password($plaintext) {
243243- * $this->encrypted_password = md5($plaintext);
244244- * }
245245- * }
246246- *
247247- * $user = new User();
248248- * $user->password = 'plaintext'; # will call $user->set_password('plaintext')
239239+ * new Person(array('first_name' => 'Tito', 'last_name' => 'the Grief'));
249240 * </code>
250241 *
251251- * If you define a custom setter with the same name as an attribute then you
252252- * will need to use assign_attribute() to assign the value to the attribute.
253253- * This is necessary due to the way __set() works.
254254- *
255255- * For example, assume 'name' is a field on the table and we're defining a
256256- * custom setter for 'name':
257257- *
258258- * <code>
259259- * class User extends ActiveRecord\Model {
260260- * static $setters = array('name');
261261- *
262262- * # INCORRECT way to do it
263263- * # function set_name($name) {
264264- * # $this->name = strtoupper($name);
265265- * # }
266266- *
267267- * function set_name($name) {
268268- * $this->assign_attribute('name',strtoupper($name));
269269- * }
270270- * }
271271- *
272272- * $user = new User();
273273- * $user->name = 'bob';
274274- * echo $user->name; # => BOB
275275- * </code>
276276- *
277277- * @var array
242242+ * @param array $attributes Hash containing names and values to mass assign to the model
243243+ * @param boolean $guard_attributes Set to true to guard attributes
244244+ * @param boolean $instantiating_via_find Set to true if this model is being created from a find call
245245+ * @param boolean $new_record Set to true if this should be considered a new record
246246+ * @return Model
278247 */
279279- static $setters = array();
248248+ public function __construct(array $attributes=array(), $guard_attributes=true, $instantiating_via_find=false, $new_record=true)
249249+ {
250250+ $this->__new_record = $new_record;
251251+252252+ // initialize attributes applying defaults
253253+ if (!$instantiating_via_find)
254254+ {
255255+ foreach (static::table()->columns as $name => $meta)
256256+ $this->attributes[$meta->inflected_name] = $meta->default;
257257+ }
258258+259259+ $this->set_attributes_via_mass_assignment($attributes, $guard_attributes);
260260+261261+ // since all attribute assignment now goes thru assign_attributes() we want to reset
262262+ // dirty if instantiating via find since nothing is really dirty when doing that
263263+ if ($instantiating_via_find)
264264+ $this->__dirty = array();
265265+266266+ $this->invoke_callback('after_construct',false);
267267+ }
280268281269 /**
282282- * Define customer getter methods for the model.
270270+ * Magic method which delegates to read_attribute(). This handles firing off getter methods,
271271+ * as they are not checked/invoked inside of read_attribute(). This circumvents the problem with
272272+ * a getter being accessed with the same name as an actual attribute.
273273+ *
274274+ * You can also define customer getter methods for the model.
283275 *
276276+ * EXAMPLE:
284277 * <code>
285278 * class User extends ActiveRecord\Model {
286286- * static $getters = array('middle_initial','more','even_more');
287279 *
288288- * # now to define the getter method. Note you must
280280+ * # define custom getter methods. Note you must
289281 * # prepend get_ to your method name:
290282 * function get_middle_initial() {
291283 * return $this->middle_name{0};
···305297 *
306298 * <code>
307299 * class User extends ActiveRecord\Model {
308308- * static $getters = array('name');
309300 *
310301 * # INCORRECT way to do it
311302 * # function get_name() {
···322313 * echo $user->name; # => BOB
323314 * </code>
324315 *
325325- * @var array
326326- */
327327- static $getters = array();
328328-329329- /**
330330- * Constructs a model.
331331- *
332332- * When a user instantiates a new object (e.g.: it was not ActiveRecord that instantiated via a find)
333333- * then @var $attributes will be mapped according to the schema's defaults. Otherwise, the given
334334- * $attributes will be mapped via set_attributes_via_mass_assignment.
335335- *
336336- * <code>
337337- * new Person(array('first_name' => 'Tito', 'last_name' => 'the Grief'));
338338- * </code>
339339- *
340340- * @param array $attributes Hash containing names and values to mass assign to the model
341341- * @param boolean $guard_attributes Set to true to guard attributes
342342- * @param boolean $instantiating_via_find Set to true if this model is being created from a find call
343343- * @param boolean $new_record Set to true if this should be considered a new record
344344- * @return Model
345345- */
346346- public function __construct(array $attributes=array(), $guard_attributes=true, $instantiating_via_find=false, $new_record=true)
347347- {
348348- $this->__new_record = $new_record;
349349-350350- // initialize attributes applying defaults
351351- if (!$instantiating_via_find)
352352- {
353353- foreach (static::table()->columns as $name => $meta)
354354- $this->attributes[$meta->inflected_name] = $meta->default;
355355- }
356356-357357- $this->set_attributes_via_mass_assignment($attributes, $guard_attributes);
358358-359359- // since all attribute assignment now goes thru assign_attributes() we want to reset
360360- // dirty if instantiating via find since nothing is really dirty when doing that
361361- if ($instantiating_via_find)
362362- $this->__dirty = array();
363363-364364- $this->invoke_callback('after_construct',false);
365365- }
366366-367367- /**
368368- * Magic method which delegates to read_attribute(). This handles firing off getter methods,
369369- * as they are not checked/invoked inside of read_attribute(). This circumvents the problem with
370370- * a getter being accessed with the same name as an actual attribute.
371316 *
372317 * @see read_attribute()
373318 * @param string $name Name of an attribute
···376321 public function &__get($name)
377322 {
378323 // check for getter
379379- if (in_array("get_$name",static::$getters))
324324+ if (method_exists($this, "get_$name"))
380325 {
381326 $name = "get_$name";
382327 $value = $this->$name();
···398343 }
399344400345 /**
401401- * Magic allows un-defined attributes to set via $attributes
346346+ * Magic allows un-defined attributes to set via $attributes.
347347+ *
348348+ * You can also define customer setter methods for the model.
349349+ *
350350+ * EXAMPLE:
351351+ * <code>
352352+ * class User extends ActiveRecord\Model {
353353+ *
354354+ * # define custom setter methods. Note you must
355355+ * # prepend set_ to your method name:
356356+ * function set_password($plaintext) {
357357+ * $this->encrypted_password = md5($plaintext);
358358+ * }
359359+ * }
360360+ *
361361+ * $user = new User();
362362+ * $user->password = 'plaintext'; # will call $user->set_password('plaintext')
363363+ * </code>
364364+ *
365365+ * If you define a custom setter with the same name as an attribute then you
366366+ * will need to use assign_attribute() to assign the value to the attribute.
367367+ * This is necessary due to the way __set() works.
368368+ *
369369+ * For example, assume 'name' is a field on the table and we're defining a
370370+ * custom setter for 'name':
371371+ *
372372+ * <code>
373373+ * class User extends ActiveRecord\Model {
374374+ *
375375+ * # INCORRECT way to do it
376376+ * # function set_name($name) {
377377+ * # $this->name = strtoupper($name);
378378+ * # }
379379+ *
380380+ * function set_name($name) {
381381+ * $this->assign_attribute('name',strtoupper($name));
382382+ * }
383383+ * }
384384+ *
385385+ * $user = new User();
386386+ * $user->name = 'bob';
387387+ * echo $user->name; # => BOB
388388+ * </code>
402389 *
403390 * @throws {@link UndefinedPropertyException} if $name does not exist
404391 * @param string $name Name of attribute, relationship or other to set
···410397 if (array_key_exists($name, static::$alias_attribute))
411398 $name = static::$alias_attribute[$name];
412399413413- elseif (in_array("set_$name",static::$setters))
400400+ elseif (method_exists($this,"set_$name"))
414401 {
415402 $name = "set_$name";
416403 return $this->$name($value);
···12501237 $method = str_replace($association_name, 'association', $method);
12511238 $table = static::table();
1252123912531253- if (($association = $table->get_relationship($association_name)) ||
12401240+ if (($association = $table->get_relationship($association_name)) ||
12541241 ($association = $table->get_relationship(($association_name = Utils::pluralize($association_name)))))
12551242 {
12561243 // access association to ensure that the relationship has been loaded
+6-12
lib/php-activerecord/lib/Table.php
···538538 }
539539540540 /**
541541- * Builds the getters/setters array by prepending get_/set_ to the method names.
541541+ * DEPRECATED: Model.php now checks for get|set_ methods via method_exists so there is no need for declaring static g|setters.
542542 */
543543 private function set_setters_and_getters()
544544 {
545545- $build = array('setters', 'getters');
546546-547547- foreach ($build as $type)
548548- {
549549- $methods = array();
550550- $prefix = substr($type,0,3) . "_";
551551-552552- foreach ($this->class->getStaticPropertyValue($type,array()) as $method)
553553- $methods[] = (substr($method,0,4) != $prefix ? "{$prefix}$method" : $method);
545545+ $getters = $this->class->getStaticPropertyValue('getters', array());
546546+ $setters = $this->class->getStaticPropertyValue('setters', array());
554547555555- $this->class->setStaticPropertyValue($type,$methods);
556556- }
548548+ if (!empty($getters) || !empty($setters))
549549+ error_log('DEPRECATION WARNING: static::$getters and static::$setters is deprecated and will be removed in a future version. Please define your setters and getters by declaring methods in your model prefixed with get_ or set_. See
550550+ http://www.phpactiverecord.org/projects/main/wiki/Utilities#attribute-setters and http://www.phpactiverecord.org/projects/main/wiki/Utilities#attribute-getters on how to make use of this option.');
557551 }
558552};
559553?>
+2-3
lib/php-activerecord/test/ActiveRecordTest.php
···383383384384 public function test_setter_with_same_name_as_an_attribute()
385385 {
386386- Author::$setters[] = 'name';
387386 $author = new Author();
388387 $author->name = 'bob';
389388 $this->assert_equals('BOB',$author->name);
···397396398397 public function test_getter_with_same_name_as_an_attribute()
399398 {
400400- Book::$getters[] = 'name';
399399+ Book::$use_custom_get_name_getter = true;
401400 $book = new Book;
402401 $book->name = 'bob';
403402 $this->assert_equals('BOB', $book->name);
404404- Book::$getters = array();
403403+ Book::$use_custom_get_name_getter = false;
405404 }
406405407406 public function test_setting_invalid_date_should_set_date_to_null()