diff --git a/lib/classes/persistent.php b/lib/classes/persistent.php index e7b09a2f299..1f936e583a5 100644 --- a/lib/classes/persistent.php +++ b/lib/classes/persistent.php @@ -110,6 +110,8 @@ abstract class persistent { * * @param string $property The property name. * @return $this + * + * @throws coding_exception */ final public function set($property, $value) { if (!static::has_property($property)) { @@ -123,6 +125,21 @@ abstract class persistent { return $this->raw_set($property, $value); } + /** + * Data setter for multiple properties + * + * Internally calls {@see set} on each property + * + * @param array $values Array of property => value elements + * @return $this + */ + final public function set_many(array $values): self { + foreach ($values as $property => $value) { + $this->set($property, $value); + } + return $this; + } + /** * Data getter. * diff --git a/lib/tests/persistent_test.php b/lib/tests/persistent_test.php index 66bdffef994..4da6b0505ee 100644 --- a/lib/tests/persistent_test.php +++ b/lib/tests/persistent_test.php @@ -353,6 +353,29 @@ class core_persistent_testcase extends advanced_testcase { $this->assertTrue($p->is_valid()); // Should always be valid after an update. } + /** + * Test set_many prior to updating the persistent + */ + public function test_set_many_update(): void { + global $DB; + + $persistent = (new core_testable_persistent(0, (object) [ + 'idnumber' => 'test', + 'sortorder' => 2 + ]))->create(); + + // Set multiple properties, and update. + $persistent->set_many([ + 'idnumber' => 'test2', + 'sortorder' => 1, + ])->update(); + + // Confirm our persistent was updated. + $record = $DB->get_record(core_testable_persistent::TABLE, ['id' => $persistent->get('id')], '*', MUST_EXIST); + $this->assertEquals('test2', $record->idnumber); + $this->assertEquals(1, $record->sortorder); + } + public function test_save() { global $DB; $p = new core_testable_persistent(0, (object) array('sortorder' => 123, 'idnumber' => 'abc')); @@ -384,6 +407,77 @@ class core_persistent_testcase extends advanced_testcase { $this->assertTrue($p->is_valid()); // Should always be valid after a save/update. } + /** + * Test set_many prior to saving the persistent + */ + public function test_set_many_save(): void { + global $DB; + + $persistent = (new core_testable_persistent(0, (object) [ + 'idnumber' => 'test', + 'sortorder' => 2 + ])); + + // Set multiple properties, and save. + $persistent->set_many([ + 'idnumber' => 'test2', + 'sortorder' => 1, + ])->save(); + + // Confirm our persistent was saved. + $record = $DB->get_record(core_testable_persistent::TABLE, ['id' => $persistent->get('id')], '*', MUST_EXIST); + $this->assertEquals('test2', $record->idnumber); + $this->assertEquals(1, $record->sortorder); + } + + /** + * Test set_many with empty array should not modify the persistent + */ + public function test_set_many_empty(): void { + global $DB; + + $persistent = (new core_testable_persistent(0, (object) [ + 'idnumber' => 'test', + 'sortorder' => 2 + ]))->create(); + + // Set empty properties, and update. + $persistent->set_many([])->update(); + + // Confirm our persistent was not updated. + $record = $DB->get_record(core_testable_persistent::TABLE, ['id' => $persistent->get('id')], '*', MUST_EXIST); + $this->assertEquals('test', $record->idnumber); + $this->assertEquals(2, $record->sortorder); + } + + /** + * Test set with invalid property + */ + public function test_set_invalid_property(): void { + $persistent = (new core_testable_persistent(0, (object) [ + 'idnumber' => 'test', + 'sortorder' => 2 + ])); + + $this->expectException(coding_exception::class); + $this->expectExceptionMessage('Unexpected property \'invalid\' requested'); + $persistent->set('invalid', 'stuff'); + } + + /** + * Test set_many with invalid property + */ + public function test_set_many_invalid_property(): void { + $persistent = (new core_testable_persistent(0, (object) [ + 'idnumber' => 'test', + 'sortorder' => 2 + ])); + + $this->expectException(coding_exception::class); + $this->expectExceptionMessage('Unexpected property \'invalid\' requested'); + $persistent->set_many(['invalid' => 'stuff']); + } + public function test_read() { $p = new core_testable_persistent(0, (object) array('sortorder' => 123, 'idnumber' => 'abc')); $p->create(); diff --git a/lib/upgrade.txt b/lib/upgrade.txt index 38f10134294..483421c0db9 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -103,6 +103,7 @@ completely removed from Moodle core too. fixed units), to always include a non-breaking space between the number and unit, and to use consistent rounding (always 1 decimal place by default). * The persistent method get() now returns the correct type for each property defined in the persistent class. +* New persistent set_many() helper for setting multiple properties in single method call. * Require pass grade criteria is now part of core. Refer to upgrade.php to see transitioning from similar plugin criteria to core Refer to completion/upgrade.txt for additional information.