diff --git a/src/Field/SqlExpressionField.php b/src/Field/SqlExpressionField.php index 53b9650b2..f5005ac7b 100644 --- a/src/Field/SqlExpressionField.php +++ b/src/Field/SqlExpressionField.php @@ -17,7 +17,7 @@ class SqlExpressionField extends Field init as private _init; } - /** @var \Closure|string|Expressionable Used expression. */ + /** @var \Closure(Model, Expression): (string|Expressionable)|string|Expressionable Used expression. */ public $expr; /** @var bool Expressions are always read_only. */ @@ -83,7 +83,7 @@ public function getDsqlExpression(Expression $expression): Expression // Otherwise call it from expression itself return $expression->expr('([])', [$expression->expr($expr)]); - } elseif ($expr instanceof Expressionable && !$expr instanceof Expression) { + } elseif ($expr instanceof Expressionable && !$expr instanceof Expression) { // @phpstan-ignore-line return $expression->expr('[]', [$expr]); } diff --git a/src/Model/UserAction.php b/src/Model/UserAction.php index 9d86bfe79..390245b2a 100644 --- a/src/Model/UserAction.php +++ b/src/Model/UserAction.php @@ -32,7 +32,7 @@ class UserAction public const APPLIES_TO_MULTIPLE_RECORDS = 'multiple'; // e.g. delete public const APPLIES_TO_ALL_RECORDS = 'all'; // e.g. truncate - /** @var string by default - action is for a single-record */ + /** @var string by default action is for a single record */ public $appliesTo = self::APPLIES_TO_SINGLE_RECORD; /** Defining action modifier */ @@ -41,28 +41,25 @@ class UserAction public const MODIFIER_DELETE = 'delete'; // delete record(s) public const MODIFIER_READ = 'read'; // just read, does not modify record(s) - /** @var string How this action interact with record. default = 'read' */ - public $modifier = self::MODIFIER_READ; + /** @var string How this action interact with record */ + public $modifier; - /** @var \Closure|string code to execute. By default will call method with same name */ + /** @var \Closure(Model, mixed ...$args): mixed|string code to execute. By default will call entity method with same name */ public $callback; - /** @var \Closure|string code, identical to callback, but would generate preview of action without permanent effect */ + /** @var \Closure(Model, mixed ...$args): mixed|string identical to callback, but would generate preview of action without permanent effect */ public $preview; /** @var string|null caption to put on the button */ public $caption; - /** @var string|\Closure|null a longer description of this action. Closure must return string. */ + /** @var string|\Closure(static): string|null a longer description of this action. */ public $description; - /** @var bool Specifies that the action is dangerous. Should be displayed in red. */ - public $dangerous = false; - - /** @var bool|string|\Closure Set this to "true", string or return the value from the callback. Will ask user to confirm. */ + /** @var bool|string|\Closure(static): string Will ask user to confirm. */ public $confirmation = false; - /** @var bool|\Closure setting this to false will disable action. Callback will be executed with ($m) and must return bool */ + /** @var bool|\Closure(Model): bool setting this to false will disable action. */ public $enabled = true; /** @var bool system action will be hidden from UI, but can still be explicitly triggered */ @@ -130,28 +127,23 @@ public function getActionForEntity(Model $entity): self */ public function execute(...$args) { + if ($this->callback === null) { + $fx = \Closure::fromCallable([$this->getEntity(), $this->shortName]); + } elseif (is_string($this->callback)) { + $fx = \Closure::fromCallable([$this->getEntity(), $this->callback]); + } else { + array_unshift($args, $this->getEntity()); + $fx = $this->callback; + } + // todo - ACL tests must allow + try { $this->validateBeforeExecute(); - $run = function () use ($args) { - if ($this->callback === null) { - $fx = [$this->getEntity(), $this->shortName]; - } elseif (is_string($this->callback)) { - $fx = [$this->getEntity(), $this->callback]; - } else { - array_unshift($args, $this->getEntity()); - $fx = $this->callback; - } - - return $fx(...$args); - }; - - if ($this->atomic) { - return $this->getModel()->atomic($run); - } - - return $run(); + return $this->atomic === false + ? $fx(...$args) + : $this->getModel()->atomic(static fn () => $fx(...$args)); } catch (CoreException $e) { $e->addMoreInfo('action', $this); diff --git a/src/Persistence/Sql/Mssql/ExpressionTrait.php b/src/Persistence/Sql/Mssql/ExpressionTrait.php index 3bc41de1b..26a360faf 100644 --- a/src/Persistence/Sql/Mssql/ExpressionTrait.php +++ b/src/Persistence/Sql/Mssql/ExpressionTrait.php @@ -87,8 +87,8 @@ public function execute(object $connection = null): DbalResult $eDriver = $e->getPrevious(); if ($eDriver !== null && $eDriver instanceof DriverException && $eDriver->getCode() === 544) { try { - return $executeFx('set IDENTITY_INSERT [table_noalias] on;' - . "\n" . 'insert[option] into [table_noalias] ([set_fields]) values ([set_values]);'); + return $executeFx('set IDENTITY_INSERT [table_noalias] on;' . "\n" + . 'insert[option] into [table_noalias] ([set_fields]) values ([set_values]);'); } finally { $executeFx('set IDENTITY_INSERT [table_noalias] off;'); } diff --git a/src/Reference.php b/src/Reference.php index 15f5a0a7e..964edfb58 100644 --- a/src/Reference.php +++ b/src/Reference.php @@ -52,7 +52,7 @@ class Reference * then used inside getModel() to fully populate and associate with * persistence. * - * @var Model|\Closure|array + * @var Model|\Closure(Model, static, array): Model|array */ public $model; @@ -117,7 +117,7 @@ final protected function getOurFieldValue(Model $ourEntity) public function getTheirFieldName(): string { - return $this->their_field ?? $this->model->id_field; + return $this->their_field ?? Model::assertInstanceOf($this->model)->id_field; } protected function onHookToOurModel(Model $model, string $spot, \Closure $fx, array $args = [], int $priority = 5): int diff --git a/tests/ConditionSqlTest.php b/tests/ConditionSqlTest.php index 7d574252d..e6a4c1938 100644 --- a/tests/ConditionSqlTest.php +++ b/tests/ConditionSqlTest.php @@ -239,7 +239,8 @@ public function testExpressionJoin(): void 1 => ['id' => 1, 'name' => 'John', 'surname' => 'Smith', 'gender' => 'M', 'contact_id' => 1], 2 => ['id' => 2, 'name' => 'Sue', 'surname' => 'Sue', 'gender' => 'F', 'contact_id' => 2], 3 => ['id' => 3, 'name' => 'Peter', 'surname' => 'Smith', 'gender' => 'M', 'contact_id' => 1], - ], 'contact' => [ + ], + 'contact' => [ 1 => ['id' => 1, 'contact_phone' => '+123 smiths'], 2 => ['id' => 2, 'contact_phone' => '+321 sues'], ], diff --git a/tests/JoinArrayTest.php b/tests/JoinArrayTest.php index bf8ef27c2..51cfc5c1d 100644 --- a/tests/JoinArrayTest.php +++ b/tests/JoinArrayTest.php @@ -92,7 +92,8 @@ public function testJoinSaving1(): void 'user' => [ 1 => ['name' => 'John', 'contact_id' => 1], 2 => ['name' => 'Peter', 'contact_id' => 1], - ], 'contact' => [ + ], + 'contact' => [ 1 => ['contact_phone' => '+123'], ], ], $this->getInternalPersistenceData($db)); @@ -108,7 +109,8 @@ public function testJoinSaving1(): void 1 => ['name' => 'John', 'contact_id' => 1], 2 => ['name' => 'Peter', 'contact_id' => 1], 3 => ['name' => 'Joe', 'contact_id' => 2], - ], 'contact' => [ + ], + 'contact' => [ 1 => ['contact_phone' => '+123'], 2 => ['contact_phone' => '+321'], ], @@ -142,7 +144,8 @@ public function testJoinSaving2(): void 'user' => [ 1 => ['name' => 'John'], 2 => ['name' => 'Peter'], - ], 'contact' => [ + ], + 'contact' => [ 1 => ['test_id' => 1, 'contact_phone' => '+123'], 2 => ['test_id' => 2, 'contact_phone' => null], ], @@ -162,7 +165,8 @@ public function testJoinSaving2(): void 1 => ['name' => 'John'], 2 => ['name' => 'Peter'], 3 => ['name' => 'Sue'], - ], 'contact' => [ + ], + 'contact' => [ 1 => ['test_id' => 1, 'contact_phone' => '+123'], 3 => ['test_id' => 3, 'contact_phone' => '+444'], ], @@ -219,7 +223,8 @@ public function testJoinLoading(): void 1 => ['name' => 'John', 'contact_id' => 1], 2 => ['name' => 'Peter', 'contact_id' => 1], 3 => ['name' => 'Joe', 'contact_id' => 2], - ], 'contact' => [ + ], + 'contact' => [ 1 => ['contact_phone' => '+123'], 2 => ['contact_phone' => '+321'], ], @@ -253,7 +258,8 @@ public function testJoinUpdate(): void 1 => ['name' => 'John', 'contact_id' => 1], 2 => ['name' => 'Peter', 'contact_id' => 1], 3 => ['name' => 'Joe', 'contact_id' => 2], - ], 'contact' => [ + ], + 'contact' => [ 1 => ['contact_phone' => '+123'], 2 => ['contact_phone' => '+321'], ], @@ -274,7 +280,8 @@ public function testJoinUpdate(): void 1 => ['name' => 'John 2', 'contact_id' => 1], 2 => ['name' => 'Peter', 'contact_id' => 1], 3 => ['name' => 'Joe', 'contact_id' => 2], - ], 'contact' => [ + ], + 'contact' => [ 1 => ['contact_phone' => '+555'], 2 => ['contact_phone' => '+321'], ], @@ -290,7 +297,8 @@ public function testJoinUpdate(): void 1 => ['name' => 'John 2', 'contact_id' => 1], 2 => ['name' => 'Peter', 'contact_id' => 1], 3 => ['name' => 'XX', 'contact_id' => 2], - ], 'contact' => [ + ], + 'contact' => [ 1 => ['contact_phone' => '+555'], 2 => ['contact_phone' => '+999'], ], @@ -307,7 +315,8 @@ public function testJoinUpdate(): void 2 => ['name' => 'Peter', 'contact_id' => 1], 3 => ['name' => 'XX', 'contact_id' => 2], 4 => ['name' => 'YYY', 'contact_id' => 3], - ], 'contact' => [ + ], + 'contact' => [ 1 => ['contact_phone' => '+555'], 2 => ['contact_phone' => '+999'], 3 => ['contact_phone' => '+777'], @@ -323,7 +332,8 @@ public function testJoinDelete(): void 2 => ['name' => 'Peter', 'contact_id' => 1], 3 => ['name' => 'XX', 'contact_id' => 2], 4 => ['name' => 'YYY', 'contact_id' => 3], - ], 'contact' => [ + ], + 'contact' => [ 1 => ['contact_phone' => '+555'], 2 => ['contact_phone' => '+999'], 3 => ['contact_phone' => '+777'], @@ -343,7 +353,8 @@ public function testJoinDelete(): void 2 => ['name' => 'Peter', 'contact_id' => 1], 3 => ['name' => 'XX', 'contact_id' => 2], 4 => ['name' => 'YYY', 'contact_id' => 3], - ], 'contact' => [ + ], + 'contact' => [ 2 => ['contact_phone' => '+999'], 3 => ['contact_phone' => '+777'], ], @@ -357,7 +368,8 @@ public function testLoadMissing(): void 2 => ['name' => 'Peter', 'contact_id' => 1], 3 => ['name' => 'XX', 'contact_id' => 2], 4 => ['name' => 'YYY', 'contact_id' => 3], - ], 'contact' => [ + ], + 'contact' => [ 2 => ['contact_phone' => '+999'], 3 => ['contact_phone' => '+777'], ], diff --git a/tests/JoinSqlTest.php b/tests/JoinSqlTest.php index dae0dbc8d..496c4e5b0 100644 --- a/tests/JoinSqlTest.php +++ b/tests/JoinSqlTest.php @@ -50,7 +50,8 @@ public function testJoinSaving1(): void $this->setDb([ 'user' => [ '_' => ['id' => 1, 'name' => 'John', 'contact_id' => 1], - ], 'contact' => [ + ], + 'contact' => [ '_' => ['id' => 1, 'contact_phone' => '+123'], ], ]); @@ -80,7 +81,8 @@ public function testJoinSaving1(): void 'user' => [ 1 => ['id' => 1, 'name' => 'John', 'contact_id' => 1], 2 => ['id' => 2, 'name' => 'Joe', 'contact_id' => 2], - ], 'contact' => [ + ], + 'contact' => [ 1 => ['id' => 1, 'contact_phone' => '+123'], 2 => ['id' => 2, 'contact_phone' => '+321'], ], @@ -93,7 +95,8 @@ public function testJoinSaving2(): void $this->setDb([ 'user' => [ '_' => ['id' => 1, 'name' => 'John'], - ], 'contact' => [ + ], + 'contact' => [ '_' => ['id' => 1, 'contact_phone' => '+123', 'test_id' => 0], ], ]); @@ -119,7 +122,8 @@ public function testJoinSaving2(): void 'user' => [ 1 => ['id' => 1, 'name' => 'John'], 2 => ['id' => 2, 'name' => 'Peter'], - ], 'contact' => [ + ], + 'contact' => [ 1 => ['id' => 1, 'test_id' => 1, 'contact_phone' => '+123'], 2 => ['id' => 2, 'test_id' => 2, 'contact_phone' => null], ], @@ -137,7 +141,8 @@ public function testJoinSaving2(): void 1 => ['id' => 1, 'name' => 'John'], 2 => ['id' => 2, 'name' => 'Peter'], 3 => ['id' => 3, 'name' => 'Sue'], - ], 'contact' => [ + ], + 'contact' => [ 1 => ['id' => 1, 'test_id' => 1, 'contact_phone' => '+123'], 3 => ['id' => 3, 'test_id' => 3, 'contact_phone' => '+444'], ], @@ -150,7 +155,8 @@ public function testJoinSaving3(): void $this->setDb([ 'user' => [ '_' => ['id' => 1, 'name' => 'John', 'test_id' => 0], - ], 'contact' => [ + ], + 'contact' => [ '_' => ['id' => 1, 'contact_phone' => '+123'], ], ]); @@ -178,7 +184,8 @@ public function testJoinLoading(): void 1 => ['id' => 1, 'name' => 'John', 'contact_id' => 1], 2 => ['id' => 2, 'name' => 'Peter', 'contact_id' => 1], 3 => ['id' => 3, 'name' => 'Joe', 'contact_id' => 2], - ], 'contact' => [ + ], + 'contact' => [ 1 => ['id' => 1, 'contact_phone' => '+123'], 2 => ['id' => 2, 'contact_phone' => '+321'], ], @@ -212,7 +219,8 @@ public function testJoinUpdate(): void 1 => ['id' => 1, 'name' => 'John', 'contact_id' => 1], 2 => ['id' => 2, 'name' => 'Peter', 'contact_id' => 1], 3 => ['id' => 3, 'name' => 'Joe', 'contact_id' => 2], - ], 'contact' => [ + ], + 'contact' => [ 1 => ['id' => 1, 'contact_phone' => '+123'], 2 => ['id' => 2, 'contact_phone' => '+321'], ], @@ -229,19 +237,17 @@ public function testJoinUpdate(): void $m_u2->set('contact_phone', '+555'); $m_u2->save(); - $this->assertEquals( - [ - 'user' => [ - 1 => ['id' => 1, 'name' => 'John 2', 'contact_id' => 1], - 2 => ['id' => 2, 'name' => 'Peter', 'contact_id' => 1], - 3 => ['id' => 3, 'name' => 'Joe', 'contact_id' => 2], - ], 'contact' => [ - 1 => ['id' => 1, 'contact_phone' => '+555'], - 2 => ['id' => 2, 'contact_phone' => '+321'], - ], + $this->assertEquals([ + 'user' => [ + 1 => ['id' => 1, 'name' => 'John 2', 'contact_id' => 1], + 2 => ['id' => 2, 'name' => 'Peter', 'contact_id' => 1], + 3 => ['id' => 3, 'name' => 'Joe', 'contact_id' => 2], ], - $this->getDb() - ); + 'contact' => [ + 1 => ['id' => 1, 'contact_phone' => '+555'], + 2 => ['id' => 2, 'contact_phone' => '+321'], + ], + ], $this->getDb()); $m_u2 = $m_u->load(1); $m_u2->set('name', 'XX'); @@ -250,57 +256,51 @@ public function testJoinUpdate(): void $m_u2->set('name', 'XX'); $m_u2->save(); - $this->assertEquals( - [ - 'user' => [ - 1 => ['id' => 1, 'name' => 'John 2', 'contact_id' => 1], - 2 => ['id' => 2, 'name' => 'Peter', 'contact_id' => 1], - 3 => ['id' => 3, 'name' => 'XX', 'contact_id' => 2], - ], 'contact' => [ - 1 => ['id' => 1, 'contact_phone' => '+555'], - 2 => ['id' => 2, 'contact_phone' => '+321'], - ], + $this->assertEquals([ + 'user' => [ + 1 => ['id' => 1, 'name' => 'John 2', 'contact_id' => 1], + 2 => ['id' => 2, 'name' => 'Peter', 'contact_id' => 1], + 3 => ['id' => 3, 'name' => 'XX', 'contact_id' => 2], + ], + 'contact' => [ + 1 => ['id' => 1, 'contact_phone' => '+555'], + 2 => ['id' => 2, 'contact_phone' => '+321'], ], - $this->getDb() - ); + ], $this->getDb()); $m_u2->set('contact_phone', '+999'); $m_u2->save(); - $this->assertEquals( - [ - 'user' => [ - 1 => ['id' => 1, 'name' => 'John 2', 'contact_id' => 1], - 2 => ['id' => 2, 'name' => 'Peter', 'contact_id' => 1], - 3 => ['id' => 3, 'name' => 'XX', 'contact_id' => 2], - ], 'contact' => [ - 1 => ['id' => 1, 'contact_phone' => '+555'], - 2 => ['id' => 2, 'contact_phone' => '+999'], - ], + $this->assertEquals([ + 'user' => [ + 1 => ['id' => 1, 'name' => 'John 2', 'contact_id' => 1], + 2 => ['id' => 2, 'name' => 'Peter', 'contact_id' => 1], + 3 => ['id' => 3, 'name' => 'XX', 'contact_id' => 2], ], - $this->getDb() - ); + 'contact' => [ + 1 => ['id' => 1, 'contact_phone' => '+555'], + 2 => ['id' => 2, 'contact_phone' => '+999'], + ], + ], $this->getDb()); $m_u2 = $m_u->tryLoad(4); $m_u2->set('name', 'YYY'); $m_u2->set('contact_phone', '+777'); $m_u2->save(); - $this->assertEquals( - [ - 'user' => [ - 1 => ['id' => 1, 'name' => 'John 2', 'contact_id' => 1], - 2 => ['id' => 2, 'name' => 'Peter', 'contact_id' => 1], - 3 => ['id' => 3, 'name' => 'XX', 'contact_id' => 2], - 4 => ['id' => 4, 'name' => 'YYY', 'contact_id' => 3], - ], 'contact' => [ - 1 => ['id' => 1, 'contact_phone' => '+555'], - 2 => ['id' => 2, 'contact_phone' => '+999'], - 3 => ['id' => 3, 'contact_phone' => '+777'], - ], - ], - $this->getDb() - ); + $this->assertEquals([ + 'user' => [ + 1 => ['id' => 1, 'name' => 'John 2', 'contact_id' => 1], + 2 => ['id' => 2, 'name' => 'Peter', 'contact_id' => 1], + 3 => ['id' => 3, 'name' => 'XX', 'contact_id' => 2], + 4 => ['id' => 4, 'name' => 'YYY', 'contact_id' => 3], + ], + 'contact' => [ + 1 => ['id' => 1, 'contact_phone' => '+555'], + 2 => ['id' => 2, 'contact_phone' => '+999'], + 3 => ['id' => 3, 'contact_phone' => '+777'], + ], + ], $this->getDb()); } public function testJoinDelete(): void @@ -311,7 +311,8 @@ public function testJoinDelete(): void 2 => ['id' => 2, 'name' => 'Peter', 'contact_id' => 1], 3 => ['id' => 3, 'name' => 'XX', 'contact_id' => 2], 4 => ['id' => 4, 'name' => 'YYY', 'contact_id' => 3], - ], 'contact' => [ + ], + 'contact' => [ 1 => ['id' => 1, 'contact_phone' => '+555'], 2 => ['id' => 2, 'contact_phone' => '+999'], 3 => ['id' => 3, 'contact_phone' => '+777'], @@ -327,19 +328,17 @@ public function testJoinDelete(): void $m_u = $m_u->load(1); $m_u->delete(); - $this->assertEquals( - [ - 'user' => [ - 2 => ['id' => 2, 'name' => 'Peter', 'contact_id' => 1], - 3 => ['id' => 3, 'name' => 'XX', 'contact_id' => 2], - 4 => ['id' => 4, 'name' => 'YYY', 'contact_id' => 3], - ], 'contact' => [ - 2 => ['id' => 2, 'contact_phone' => '+999'], - 3 => ['id' => 3, 'contact_phone' => '+777'], - ], - ], - $this->getDb() - ); + $this->assertEquals([ + 'user' => [ + 2 => ['id' => 2, 'name' => 'Peter', 'contact_id' => 1], + 3 => ['id' => 3, 'name' => 'XX', 'contact_id' => 2], + 4 => ['id' => 4, 'name' => 'YYY', 'contact_id' => 3], + ], + 'contact' => [ + 2 => ['id' => 2, 'contact_phone' => '+999'], + 3 => ['id' => 3, 'contact_phone' => '+777'], + ], + ], $this->getDb()); } public function testDoubleSaveHook(): void @@ -348,7 +347,8 @@ public function testDoubleSaveHook(): void $this->setDb([ 'user' => [ '_' => ['id' => 1, 'name' => 'John'], - ], 'contact' => [ + ], + 'contact' => [ '_' => ['id' => 1, 'contact_phone' => '+123', 'test_id' => 0], ], ]); @@ -380,11 +380,13 @@ public function testDoubleJoin(): void 20 => ['id' => 20, 'name' => 'Peter', 'contact_id' => 100], 30 => ['id' => 30, 'name' => 'XX', 'contact_id' => 200], 40 => ['id' => 40, 'name' => 'YYY', 'contact_id' => 300], - ], 'contact' => [ + ], + 'contact' => [ 100 => ['id' => 100, 'contact_phone' => '+555', 'country_id' => 1], 200 => ['id' => 200, 'contact_phone' => '+999', 'country_id' => 2], 300 => ['id' => 300, 'contact_phone' => '+777', 'country_id' => 5], - ], 'country' => [ + ], + 'country' => [ 1 => ['id' => 1, 'name' => 'UK'], 2 => ['id' => 2, 'name' => 'US'], 3 => ['id' => 3, 'name' => 'India'], @@ -414,25 +416,24 @@ public function testDoubleJoin(): void $m_u->createEntity()->save(['name' => 'new', 'contact_phone' => '+000', 'country_name' => 'LV']); - $this->assertEquals( - [ - 'user' => [ - 20 => ['id' => 20, 'name' => 'Peter', 'contact_id' => 100], - 30 => ['id' => 30, 'name' => 'XX', 'contact_id' => 200], - 40 => ['id' => 40, 'name' => 'YYY', 'contact_id' => 300], - 41 => ['id' => 41, 'name' => 'new', 'contact_id' => 301], - ], 'contact' => [ - 200 => ['id' => 200, 'contact_phone' => '+999', 'country_id' => 2], - 300 => ['id' => 300, 'contact_phone' => '+777', 'country_id' => 5], - 301 => ['id' => 301, 'contact_phone' => '+000', 'country_id' => 4], - ], 'country' => [ - 2 => ['id' => 2, 'name' => 'USA'], - 3 => ['id' => 3, 'name' => 'India'], - 4 => ['id' => 4, 'name' => 'LV'], - ], - ], - $this->getDb() - ); + $this->assertEquals([ + 'user' => [ + 20 => ['id' => 20, 'name' => 'Peter', 'contact_id' => 100], + 30 => ['id' => 30, 'name' => 'XX', 'contact_id' => 200], + 40 => ['id' => 40, 'name' => 'YYY', 'contact_id' => 300], + 41 => ['id' => 41, 'name' => 'new', 'contact_id' => 301], + ], + 'contact' => [ + 200 => ['id' => 200, 'contact_phone' => '+999', 'country_id' => 2], + 300 => ['id' => 300, 'contact_phone' => '+777', 'country_id' => 5], + 301 => ['id' => 301, 'contact_phone' => '+000', 'country_id' => 4], + ], + 'country' => [ + 2 => ['id' => 2, 'name' => 'USA'], + 3 => ['id' => 3, 'name' => 'India'], + 4 => ['id' => 4, 'name' => 'LV'], + ], + ], $this->getDb()); } public function testDoubleReverseJoin(): void @@ -443,11 +444,13 @@ public function testDoubleReverseJoin(): void 20 => ['id' => 20, 'name' => 'Peter', 'contact_id' => 100], 30 => ['id' => 30, 'name' => 'XX', 'contact_id' => 200], 40 => ['id' => 40, 'name' => 'YYY', 'contact_id' => 300], - ], 'contact' => [ + ], + 'contact' => [ 100 => ['id' => 100, 'contact_phone' => '+555', 'country_id' => 1], 200 => ['id' => 200, 'contact_phone' => '+999', 'country_id' => 2], 300 => ['id' => 300, 'contact_phone' => '+777', 'country_id' => 5], - ], 'country' => [ + ], + 'country' => [ 1 => ['id' => 1, 'name' => 'UK'], 2 => ['id' => 2, 'name' => 'US'], 3 => ['id' => 3, 'name' => 'India'], @@ -468,22 +471,21 @@ public function testDoubleReverseJoin(): void $m_u = $m_u->loadBy('country_name', 'US'); $this->assertEquals(30, $m_u->getId()); - $this->assertEquals( - [ - 'user' => [ - 20 => ['id' => 20, 'name' => 'Peter', 'contact_id' => 100], - 30 => ['id' => 30, 'name' => 'XX', 'contact_id' => 200], - 40 => ['id' => 40, 'name' => 'YYY', 'contact_id' => 300], - ], 'contact' => [ - 200 => ['id' => 200, 'contact_phone' => '+999', 'country_id' => 2], - 300 => ['id' => 300, 'contact_phone' => '+777', 'country_id' => 5], - ], 'country' => [ - 2 => ['id' => 2, 'name' => 'US'], - 3 => ['id' => 3, 'name' => 'India'], - ], - ], - $this->getDb() - ); + $this->assertEquals([ + 'user' => [ + 20 => ['id' => 20, 'name' => 'Peter', 'contact_id' => 100], + 30 => ['id' => 30, 'name' => 'XX', 'contact_id' => 200], + 40 => ['id' => 40, 'name' => 'YYY', 'contact_id' => 300], + ], + 'contact' => [ + 200 => ['id' => 200, 'contact_phone' => '+999', 'country_id' => 2], + 300 => ['id' => 300, 'contact_phone' => '+777', 'country_id' => 5], + ], + 'country' => [ + 2 => ['id' => 2, 'name' => 'US'], + 3 => ['id' => 3, 'name' => 'India'], + ], + ], $this->getDb()); } /** @@ -565,7 +567,8 @@ public function testJoinReverseOneOnOne(): void 'user' => [ 10 => ['id' => 10, 'name' => 'John'], 20 => ['id' => 20, 'name' => 'Peter'], - ], 'detail' => [ + ], + 'detail' => [ 100 => ['id' => 100, 'my_user_id' => 10, 'notes' => 'first note'], 200 => ['id' => 200, 'my_user_id' => 20, 'notes' => 'second note'], ], @@ -637,10 +640,12 @@ public function testJoinActualFieldNamesAndPrefix(): void 1 => ['id' => 1, 'first_name' => 'John', 'cid' => 1], 2 => ['id' => 2, 'first_name' => 'Peter', 'cid' => 1], 3 => ['id' => 3, 'first_name' => 'Joe', 'cid' => 2], - ], 'contact' => [ + ], + 'contact' => [ 1 => ['id' => 1, 'contact_phone' => '+123'], 2 => ['id' => 2, 'contact_phone' => '+321'], - ], 'salaries' => [ + ], + 'salaries' => [ 1 => ['id' => 1, 'amount' => 123, 'uid' => 1], 2 => ['id' => 2, 'amount' => 456, 'uid' => 2], ], @@ -663,22 +668,21 @@ public function testJoinActualFieldNamesAndPrefix(): void $m_u2->set('j2_salary', 111); $m_u2->save(); - $this->assertEquals( - [ - 'user' => [ - 1 => ['id' => 1, 'first_name' => 'John 2', 'cid' => 1], - 2 => ['id' => 2, 'first_name' => 'Peter', 'cid' => 1], - 3 => ['id' => 3, 'first_name' => 'Joe', 'cid' => 2], - ], 'contact' => [ - 1 => ['id' => 1, 'contact_phone' => '+555'], - 2 => ['id' => 2, 'contact_phone' => '+321'], - ], 'salaries' => [ - 1 => ['id' => 1, 'amount' => 111, 'uid' => 1], - 2 => ['id' => 2, 'amount' => 456, 'uid' => 2], - ], - ], - $this->getDb() - ); + $this->assertEquals([ + 'user' => [ + 1 => ['id' => 1, 'first_name' => 'John 2', 'cid' => 1], + 2 => ['id' => 2, 'first_name' => 'Peter', 'cid' => 1], + 3 => ['id' => 3, 'first_name' => 'Joe', 'cid' => 2], + ], + 'contact' => [ + 1 => ['id' => 1, 'contact_phone' => '+555'], + 2 => ['id' => 2, 'contact_phone' => '+321'], + ], + 'salaries' => [ + 1 => ['id' => 1, 'amount' => 111, 'uid' => 1], + 2 => ['id' => 2, 'amount' => 456, 'uid' => 2], + ], + ], $this->getDb()); // insert $m_u3 = $m_u->createEntity()->unload(); @@ -687,24 +691,23 @@ public function testJoinActualFieldNamesAndPrefix(): void $m_u3->set('j2_salary', 222); $m_u3->save(); - $this->assertEquals( - [ - 'user' => [ - 1 => ['id' => 1, 'first_name' => 'John 2', 'cid' => 1], - 2 => ['id' => 2, 'first_name' => 'Peter', 'cid' => 1], - 3 => ['id' => 3, 'first_name' => 'Joe', 'cid' => 2], - 4 => ['id' => 4, 'first_name' => 'Marvin', 'cid' => 3], - ], 'contact' => [ - 1 => ['id' => 1, 'contact_phone' => '+555'], - 2 => ['id' => 2, 'contact_phone' => '+321'], - 3 => ['id' => 3, 'contact_phone' => '+999'], - ], 'salaries' => [ - 1 => ['id' => 1, 'amount' => 111, 'uid' => 1], - 2 => ['id' => 2, 'amount' => 456, 'uid' => 2], - 3 => ['id' => 3, 'amount' => 222, 'uid' => 4], - ], - ], - $this->getDb() - ); + $this->assertEquals([ + 'user' => [ + 1 => ['id' => 1, 'first_name' => 'John 2', 'cid' => 1], + 2 => ['id' => 2, 'first_name' => 'Peter', 'cid' => 1], + 3 => ['id' => 3, 'first_name' => 'Joe', 'cid' => 2], + 4 => ['id' => 4, 'first_name' => 'Marvin', 'cid' => 3], + ], + 'contact' => [ + 1 => ['id' => 1, 'contact_phone' => '+555'], + 2 => ['id' => 2, 'contact_phone' => '+321'], + 3 => ['id' => 3, 'contact_phone' => '+999'], + ], + 'salaries' => [ + 1 => ['id' => 1, 'amount' => 111, 'uid' => 1], + 2 => ['id' => 2, 'amount' => 456, 'uid' => 2], + 3 => ['id' => 3, 'amount' => 222, 'uid' => 4], + ], + ], $this->getDb()); } } diff --git a/tests/ReferenceSqlTest.php b/tests/ReferenceSqlTest.php index c4dc0337c..f5ae586b6 100644 --- a/tests/ReferenceSqlTest.php +++ b/tests/ReferenceSqlTest.php @@ -23,7 +23,8 @@ public function testBasic(): void 1 => ['id' => 1, 'name' => 'John'], 2 => ['id' => 2, 'name' => 'Peter'], 3 => ['id' => 3, 'name' => 'Joe'], - ], 'order' => [ + ], + 'order' => [ ['amount' => '20', 'user_id' => 1], ['amount' => '15', 'user_id' => 2], ['amount' => '5', 'user_id' => 1], @@ -84,7 +85,8 @@ public function testBasic2(): void ['name' => 'John', 'currency' => 'EUR'], ['name' => 'Peter', 'currency' => 'GBP'], ['name' => 'Joe', 'currency' => 'EUR'], - ], 'currency' => [ + ], + 'currency' => [ ['currency' => 'EUR', 'name' => 'Euro'], ['currency' => 'USD', 'name' => 'Dollar'], ['currency' => 'GBP', 'name' => 'Pound'], @@ -129,7 +131,8 @@ public function testBasicOne(): void 1 => ['id' => 1, 'name' => 'John'], 2 => ['id' => 2, 'name' => 'Peter'], 3 => ['id' => 3, 'name' => 'Joe'], - ], 'order' => [ + ], + 'order' => [ ['amount' => '20', 'user_id' => 1], ['amount' => '15', 'user_id' => 2], ['amount' => '5', 'user_id' => 1], @@ -167,7 +170,8 @@ public function testAddOneField(): void 1 => ['id' => 1, 'name' => 'John', 'date' => '2001-01-02'], 2 => ['id' => 2, 'name' => 'Peter', 'date' => '2004-08-20'], 3 => ['id' => 3, 'name' => 'Joe', 'date' => '2005-08-20'], - ], 'order' => [ + ], + 'order' => [ ['amount' => '20', 'user_id' => 1], ['amount' => '15', 'user_id' => 2], ['amount' => '5', 'user_id' => 1], @@ -208,7 +212,8 @@ public function testRelatedExpression(): void 1 => ['id' => 1, 'ref_no' => 'INV203'], 2 => ['id' => 2, 'ref_no' => 'INV204'], 3 => ['id' => 3, 'ref_no' => 'INV205'], - ], 'invoice_line' => [ + ], + 'invoice_line' => [ ['total_net' => ($n = 10), 'total_vat' => ($n * $vat), 'total_gross' => ($n * ($vat + 1)), 'invoice_id' => 1], ['total_net' => ($n = 30), 'total_vat' => ($n * $vat), 'total_gross' => ($n * ($vat + 1)), 'invoice_id' => 1], ['total_net' => ($n = 100), 'total_vat' => ($n * $vat), 'total_gross' => ($n * ($vat + 1)), 'invoice_id' => 2], @@ -238,7 +243,8 @@ public function testAggregateHasMany(): void 1 => ['id' => 1, 'ref_no' => 'INV203'], 2 => ['id' => 2, 'ref_no' => 'INV204'], 3 => ['id' => 3, 'ref_no' => 'INV205'], - ], 'invoice_line' => [ + ], + 'invoice_line' => [ ['total_net' => ($n = 10), 'total_vat' => ($n * $vat), 'total_gross' => ($n * ($vat + 1)), 'invoice_id' => 1], ['total_net' => ($n = 30), 'total_vat' => ($n * $vat), 'total_gross' => ($n * ($vat + 1)), 'invoice_id' => 1], ['total_net' => ($n = 100), 'total_vat' => ($n * $vat), 'total_gross' => ($n * ($vat + 1)), 'invoice_id' => 2], @@ -301,7 +307,8 @@ public function testOtherAggregates(): void 1 => ['id' => 1, 'name' => 'Meat'], 2 => ['id' => 2, 'name' => 'Veg'], 3 => ['id' => 3, 'name' => 'Fruit'], - ], 'item' => [ + ], + 'item' => [ ['name' => 'Apple', 'code' => 'ABC', 'list_id' => 3], ['name' => 'Banana', 'code' => 'DEF', 'list_id' => 3], ['name' => 'Pork', 'code' => 'GHI', 'list_id' => 1], @@ -394,22 +401,17 @@ public function testReferenceHasOneTraversing(): void $firstUserOrders = $user->ref('Company')->ref('Orders'); $firstUserOrders->setOrder('id'); - $this->assertEquals([ - ['id' => '1', 'company_id' => 1, 'description' => 'Vinny Company Order 1', 'amount' => 50.0], - ['id' => '3', 'company_id' => 1, 'description' => 'Vinny Company Order 2', 'amount' => 15.0], + $this->assertSameExportUnordered([ + ['id' => 1, 'company_id' => '1', 'description' => 'Vinny Company Order 1', 'amount' => 50.0], + ['id' => 3, 'company_id' => '1', 'description' => 'Vinny Company Order 2', 'amount' => 15.0], ], $firstUserOrders->export()); $user->unload(); - $this->assertEquals([ - ['id' => '1', 'company_id' => 1, 'description' => 'Vinny Company Order 1', 'amount' => 50.0], - ['id' => '3', 'company_id' => 1, 'description' => 'Vinny Company Order 2', 'amount' => 15.0], - ], $firstUserOrders->export()); - - $this->assertEquals([ - ['id' => '1', 'company_id' => 1, 'description' => 'Vinny Company Order 1', 'amount' => 50.0], - ['id' => '2', 'company_id' => 2, 'description' => 'Zoe Company Order', 'amount' => 10.0], - ['id' => '3', 'company_id' => 1, 'description' => 'Vinny Company Order 2', 'amount' => 15.0], + $this->assertSameExportUnordered([ + ['id' => 1, 'company_id' => '1', 'description' => 'Vinny Company Order 1', 'amount' => 50.0], + ['id' => 2, 'company_id' => '2', 'description' => 'Zoe Company Order', 'amount' => 10.0], + ['id' => 3, 'company_id' => '1', 'description' => 'Vinny Company Order 2', 'amount' => 15.0], ], $user->ref('Company')->ref('Orders')->setOrder('id')->export()); } @@ -420,7 +422,8 @@ public function testReferenceHook(): void ['name' => 'John', 'contact_id' => 2], ['name' => 'Peter', 'contact_id' => null], ['name' => 'Joe', 'contact_id' => 3], - ], 'contact' => [ + ], + 'contact' => [ ['address' => 'Sue contact'], ['address' => 'John contact'], ['address' => 'Joe contact'], @@ -504,7 +507,8 @@ public function testAddTitle(): void $this->setDb([ 'user' => [ 1 => ['id' => 1, 'name' => 'John'], - ], 'order' => [ + ], + 'order' => [ ['amount' => '20', 'user_id' => 1], ['amount' => '15', 'user_id' => 2], ], @@ -542,7 +546,8 @@ public function testHasOneTitleSet(): void 1 => ['id' => 1, 'name' => 'John', 'last_name' => 'Doe'], 2 => ['id' => 2, 'name' => 'Peter', 'last_name' => 'Foo'], 3 => ['id' => 3, 'name' => 'Goofy', 'last_name' => 'Goo'], - ], 'order' => [ + ], + 'order' => [ 1 => ['id' => 1, 'user_id' => 1], 2 => ['id' => 2, 'user_id' => 2], 3 => ['id' => 3, 'user_id' => 1], @@ -667,25 +672,22 @@ public function testHasOneReferenceCaption(): void public function testHasOneReferenceType(): void { // restore DB - $this->setDb( - [ - 'user' => [ - 1 => [ - 'id' => 1, - 'name' => 'John', - 'last_name' => 'Doe', - 'some_number' => 3, - 'some_other_number' => 4, - ], - ], - 'order' => [ - 1 => ['id' => 1, 'user_id' => 1], + $this->setDb([ + 'user' => [ + 1 => [ + 'id' => 1, + 'name' => 'John', + 'last_name' => 'Doe', + 'some_number' => 3, + 'some_other_number' => 4, ], - ] - ); - $user = (new Model($this->db, ['table' => 'user']))->addFields( - ['name', 'last_name', 'some_number', 'some_other_number'] - ); + ], + 'order' => [ + 1 => ['id' => 1, 'user_id' => 1], + ], + ]); + $user = (new Model($this->db, ['table' => 'user'])) + ->addFields(['name', 'last_name', 'some_number', 'some_other_number']); $user->getField('some_number')->type = 'integer'; $user->getField('some_other_number')->type = 'integer'; $order = (new Model($this->db, ['table' => 'order'])); diff --git a/tests/WithTest.php b/tests/WithTest.php index 14db20558..278341c24 100644 --- a/tests/WithTest.php +++ b/tests/WithTest.php @@ -17,7 +17,8 @@ public function testWith(): void 'user' => [ 10 => ['id' => 10, 'name' => 'John', 'salary' => 2500], 20 => ['id' => 20, 'name' => 'Peter', 'salary' => 4000], - ], 'invoice' => [ + ], + 'invoice' => [ 1 => ['id' => 1, 'net' => 500, 'user_id' => 10], 2 => ['id' => 2, 'net' => 200, 'user_id' => 20], 3 => ['id' => 3, 'net' => 100, 'user_id' => 20],