From d1396b7dfe91138dcda53df0c0378281e7edb771 Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Wed, 27 Feb 2019 15:12:26 +1300 Subject: [PATCH 1/2] BUG Fix writeBaseRecord with unique indexes Fixes #6819 --- src/ORM/DataObject.php | 12 ++++--- tests/php/ORM/DataObjectSchemaTest.php | 31 +++++++++++++++++++ .../ORM/DataObjectSchemaTest/AllIndexes.php | 5 +++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/ORM/DataObject.php b/src/ORM/DataObject.php index dc8c2c189..682f7b150 100644 --- a/src/ORM/DataObject.php +++ b/src/ORM/DataObject.php @@ -1413,8 +1413,10 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity // Inserts done one the base table are performed in another step, so the manipulation should instead // attempt an update, as though it were a normal update. $manipulation[$table]['command'] = $isNewRecord ? 'insert' : 'update'; - $manipulation[$table]['id'] = $this->record['ID']; $manipulation[$table]['class'] = $class; + if ($this->isInDB()) { + $manipulation[$table]['id'] = $this->record['ID']; + } } /** @@ -1433,10 +1435,10 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity } // Perform an insert on the base table - $insert = new SQLInsert('"' . $baseTable . '"'); - $insert - ->assign('"Created"', $now) - ->execute(); + $manipulation = []; + $this->prepareManipulationTable($baseTable, $now, true, $manipulation, $this->baseClass()); + DB::manipulate($manipulation); + $this->changed['ID'] = self::CHANGE_VALUE; $this->record['ID'] = DB::get_generated_id($baseTable); } diff --git a/tests/php/ORM/DataObjectSchemaTest.php b/tests/php/ORM/DataObjectSchemaTest.php index da2a51d23..e8fa1cb3d 100644 --- a/tests/php/ORM/DataObjectSchemaTest.php +++ b/tests/php/ORM/DataObjectSchemaTest.php @@ -343,4 +343,35 @@ class DataObjectSchemaTest extends SapphireTest 'columns' => ['IndexedMoneyCurrency', 'IndexedMoneyAmount'] ], $indexes['IndexedMoney']); } + + /** + * Ensure that records with unique indexes can be written + */ + public function testWriteUniqueIndexes() + { + // Create default object + $zeroObject = new AllIndexes(); + $zeroObject->Number = 0; + $zeroObject->write(); + + $this->assertListEquals( + [ + ['Number' => 0], + ], + AllIndexes::get() + ); + + // Test a new record can be created without clashing with default value + $validObject = new AllIndexes(); + $validObject->Number = 1; + $validObject->write(); + + $this->assertListEquals( + [ + ['Number' => 0], + ['Number' => 1], + ], + AllIndexes::get() + ); + } } diff --git a/tests/php/ORM/DataObjectSchemaTest/AllIndexes.php b/tests/php/ORM/DataObjectSchemaTest/AllIndexes.php index ae36d951a..9c7f9b1a2 100644 --- a/tests/php/ORM/DataObjectSchemaTest/AllIndexes.php +++ b/tests/php/ORM/DataObjectSchemaTest/AllIndexes.php @@ -5,6 +5,11 @@ use SilverStripe\Dev\TestOnly; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\FieldType\DBIndexable; +/** + * @property int $Number + * @property string $Content + * @property string $Title + */ class AllIndexes extends DataObject implements TestOnly { private static $table_name = 'DataObjectSchemaTest_AllIndexes'; From 7416ce275ba6384fe6e2685078d3cf02d0322218 Mon Sep 17 00:00:00 2001 From: Daniel Hensby Date: Tue, 5 Mar 2019 19:01:12 +0000 Subject: [PATCH 2/2] FIX doInit comparison should be lowercased --- src/Control/RequestHandler.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Control/RequestHandler.php b/src/Control/RequestHandler.php index a8f1cfa69..fb217467c 100644 --- a/src/Control/RequestHandler.php +++ b/src/Control/RequestHandler.php @@ -195,7 +195,7 @@ class RequestHandler extends ViewableData if (!$this->hasAction($action)) { return $this->httpError(404, "Action '$action' isn't available $classMessage."); } - if (!$this->checkAccessAction($action) || in_array(strtolower($action), array('run', 'doInit'))) { + if (!$this->checkAccessAction($action) || in_array(strtolower($action), array('run', 'doinit'))) { return $this->httpError(403, "Action '$action' isn't allowed $classMessage."); } $result = $this->handleAction($request, $action); @@ -410,7 +410,7 @@ class RequestHandler extends ViewableData $actionsWithoutExtra = $this->config()->get('allowed_actions', true); if (!is_array($actions) || !$actionsWithoutExtra) { - if ($action != 'doInit' && $action != 'run' && method_exists($this, $action)) { + if (!in_array(strtolower($action), array('run', 'doinit')) && method_exists($this, $action)) { return true; } }