From 82dc4741e1178c58886aec2ceefd34ebe575025d Mon Sep 17 00:00:00 2001 From: David Sveningsson Date: Thu, 9 Jun 2016 21:30:11 +0200 Subject: [PATCH 1/5] support passing extra fields to update_attributes --- BasicObject.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/BasicObject.php b/BasicObject.php index a0ddc01..5a6c824 100644 --- a/BasicObject.php +++ b/BasicObject.php @@ -1124,13 +1124,15 @@ private static function handle_params($params, &$joins, &$wheres, &$order, &$tab * permit: Array with keys to permit to update. * create: If true new objects can be created if ID is missing or null, otherwise null * will be returned when the object should've been created. + * extra_fields Array with extra fields to set on the object (using __set) */ - public static function update_attributes($array, $options=array()) { + public static function update_attributes(array $array, $options=[]) { $defaults = array( 'empty_to_null' => true, 'commit' => false, 'permit' => false, 'create' => true, + 'extra_fields' => [], ); $options = array_merge($defaults, $options); if ( $options['empty_to_null'] == true || is_array($options['empty_to_null']) ){ @@ -1176,6 +1178,12 @@ public static function update_attributes($array, $options=array()) { return null; } + foreach ( $options['extra_fields'] as $key ){ + if ( array_key_exists($key, $array) ){ + $obj->$key = $array[$key]; + } + } + if(!isset($options["commit"]) || $options["commit"] == true) { $obj->commit(); } From 90aa55a0be7343d971561879ad4c5c2b367ccffc Mon Sep 17 00:00:00 2001 From: David Sveningsson Date: Sun, 26 Jun 2016 20:29:39 +0200 Subject: [PATCH 2/5] dash compat. --- tests/tests.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/tests.sh b/tests/tests.sh index 83aeaf0..2ff9ead 100755 --- a/tests/tests.sh +++ b/tests/tests.sh @@ -3,9 +3,14 @@ set +e cd `dirname $0` -echo -e "Running tests without cache\n" +echo "Running tests without cache" +echo ./phpunit --bootstrap "no_cache.php" --exclude-group cache $@ -echo -e "\n----------------------\n" -echo -e "Running tests with cache\n" +echo +echo "----------------------" +echo +echo "Running tests with cache" +echo + ./phpunit --bootstrap "with_cache.php" $@ From c48f6a1c97491e17053c4ea1fd6cf2013beec7f1 Mon Sep 17 00:00:00 2001 From: David Sveningsson Date: Sun, 26 Jun 2016 20:36:43 +0200 Subject: [PATCH 3/5] tests typo --- tests/tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests.sh b/tests/tests.sh index 2ff9ead..75db250 100755 --- a/tests/tests.sh +++ b/tests/tests.sh @@ -1,6 +1,6 @@ #!/bin/sh -set +e +set -e cd `dirname $0` echo "Running tests without cache" From fee2f0870cfdc800d703dd55eebf8f2f5ef6678e Mon Sep 17 00:00:00 2001 From: David Sveningsson Date: Sun, 26 Jun 2016 20:42:52 +0200 Subject: [PATCH 4/5] use function to list allowed extra fields for model --- BasicObject.php | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/BasicObject.php b/BasicObject.php index 5a6c824..e5426d6 100644 --- a/BasicObject.php +++ b/BasicObject.php @@ -99,6 +99,17 @@ public static function with_disabled_cache($callback) { */ // abstract protected static function table_name(); + /** + * Array with names of extra fields supported by this model. + * When using `update_attributes` all fields from this array will be + * set on the instance it present in data. Useful when combied with + * `__set`, e.g. setting `bar` affects `foo` but `bar` isn't present + * in the database table. + */ + protected static function extra_fields(){ + return []; + } + /** * Returns the table name associated with this class. * @return The name of the table this class is associated with. @@ -1124,7 +1135,6 @@ private static function handle_params($params, &$joins, &$wheres, &$order, &$tab * permit: Array with keys to permit to update. * create: If true new objects can be created if ID is missing or null, otherwise null * will be returned when the object should've been created. - * extra_fields Array with extra fields to set on the object (using __set) */ public static function update_attributes(array $array, $options=[]) { $defaults = array( @@ -1132,8 +1142,8 @@ public static function update_attributes(array $array, $options=[]) { 'commit' => false, 'permit' => false, 'create' => true, - 'extra_fields' => [], ); + $extra_fields = static::extra_fields(); $options = array_merge($defaults, $options); if ( $options['empty_to_null'] == true || is_array($options['empty_to_null']) ){ $keys = $options['empty_to_null']; @@ -1150,7 +1160,9 @@ public static function update_attributes(array $array, $options=[]) { /* remove unpermitted keys */ if ( is_array($options['permit']) ){ $permit = array_merge($options['permit'], array('id', static::id_name())); - $array = array_intersect_key($array, array_combine($permit, $permit)); + $permit = array_combine($permit, $permit); + $array = array_intersect_key($array, $permit); + $extra_fields = array_intersect($extra_fields, $permit); } $obj = new static($array); @@ -1178,7 +1190,8 @@ public static function update_attributes(array $array, $options=[]) { return null; } - foreach ( $options['extra_fields'] as $key ){ + /* call __set for all extra fields */ + foreach ( $extra_fields as $key ){ if ( array_key_exists($key, $array) ){ $obj->$key = $array[$key]; } From e18aaa86351d87de1840d0f751ea04ffe1203eee Mon Sep 17 00:00:00 2001 From: David Sveningsson Date: Sun, 26 Jun 2016 20:43:28 +0200 Subject: [PATCH 5/5] unit tests --- tests/models/ModelExtraFields.php | 31 ++++++++++++++++ tests/suites/BasicObject/ExtraFieldsTest.php | 37 ++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 tests/models/ModelExtraFields.php create mode 100644 tests/suites/BasicObject/ExtraFieldsTest.php diff --git a/tests/models/ModelExtraFields.php b/tests/models/ModelExtraFields.php new file mode 100644 index 0000000..03bfb08 --- /dev/null +++ b/tests/models/ModelExtraFields.php @@ -0,0 +1,31 @@ +int1 - 10; + break; + default: + return parent::__get($key); + } + } + + public function __set($key, $value) { + switch ( $key ){ + case 'int2': + $this->int1 = $value + 10; + break; + default: + parent::__set($key, $value); + } + } +}; diff --git a/tests/suites/BasicObject/ExtraFieldsTest.php b/tests/suites/BasicObject/ExtraFieldsTest.php new file mode 100644 index 0000000..05810d8 --- /dev/null +++ b/tests/suites/BasicObject/ExtraFieldsTest.php @@ -0,0 +1,37 @@ + 5]; + $model = ModelExtraFields::update_attributes($data, [ + 'commit' => false, + ]); + $this->assertEquals(15, $model->int1, 'int1 should be set via int2'); + } + + public function testOrder() { + $data = ['int1' => 4, 'int2' => 5]; + $model = ModelExtraFields::update_attributes($data, [ + 'commit' => false, + ]); + $this->assertEquals(15, $model->int1, 'base fields should be set before extra fields'); + } + + public function testPermitNegative() { + $data = ['int1' => 4, 'int2' => 5]; + $model = ModelExtraFields::update_attributes($data, [ + 'commit' => false, + 'permit' => ['int1'], + ]); + $this->assertEquals(4, $model->int1, 'int2 should be ignored if not listed in permit'); + } + + public function testPermitPositive() { + $data = ['int1' => 4, 'int2' => 5]; + $model = ModelExtraFields::update_attributes($data, [ + 'commit' => false, + 'permit' => ['int2'], + ]); + $this->assertEquals(15, $model->int1, 'int2 should be used when listed in permit'); + } +}