diff --git a/src/Service/QueryModifier/Easy/Modifier.php b/src/Service/QueryModifier/Easy/Modifier.php index 4e113c5..186e257 100644 --- a/src/Service/QueryModifier/Easy/Modifier.php +++ b/src/Service/QueryModifier/Easy/Modifier.php @@ -112,9 +112,13 @@ private function after() */ private function before(string $dotProperty) { - $this->dotUseQuery = new UseQueryFromDotNotation($this->query, $dotProperty); - $property = $this->dotUseQuery->getProperty(); - $this->query = $this->dotUseQuery->useQuery(); + + $dotProperty = trim($dotProperty, UseQueryFromDotNotation::RELATION_SEP); + $parts = explode(UseQueryFromDotNotation::RELATION_SEP, $dotProperty); + $property = ucfirst(array_pop($parts)); + + $this->dotUseQuery = new UseQueryFromDotNotation($this->query); + $this->query = $this->dotUseQuery->fromArray($parts)->useQuery(); return $property; } diff --git a/src/Service/QueryModifier/UseQuery/UseQueryFromDotNotation.php b/src/Service/QueryModifier/UseQuery/UseQueryFromDotNotation.php index cd09c68..7c53a0d 100644 --- a/src/Service/QueryModifier/UseQuery/UseQueryFromDotNotation.php +++ b/src/Service/QueryModifier/UseQuery/UseQueryFromDotNotation.php @@ -19,10 +19,6 @@ class UseQueryFromDotNotation * @var int */ protected $depth = 0; - /** - * @var string - */ - protected $dotProperty; /** * @var bool */ @@ -31,31 +27,54 @@ class UseQueryFromDotNotation * @var array */ protected $map = []; - /** - * @var string - */ - protected $property; /** * @var ModelCriteria */ protected $query; - public function __construct(ModelCriteria $query, string $dotProperty) + /** + * UseQueryFromDotNotation constructor. + * @param ModelCriteria $query + */ + public function __construct(ModelCriteria $query) { - $cleanDotProperty = trim($dotProperty); - # Remove first dot, in this case this is NO relation, only property - $cleanDotProperty = ltrim($cleanDotProperty, "."); + $this->query = $query; + } + + /** + * @param array $relations + * @return UseQueryFromDotNotation + */ + public function fromArray(array $relations): self + { + if (empty($relations)) { + return $this; + } - $this->map = explode(self::RELATION_SEP, $cleanDotProperty); + $this->map = $relations; + $this->depth = count($this->map); - $this->query = $query; - $this->dotProperty = $cleanDotProperty; - $this->property = array_pop($this->map); - $this->depth = count($this->map); + return $this; + } - if (empty($this->property)) { - throw new \InvalidArgumentException("Property is empty in \"$dotProperty\""); + /** + * @param string $relations + * @return UseQueryFromDotNotation + */ + public function fromString(string $relations): self + { + $relations = trim($relations); + # Remove first dot, in this case this is NO relation, only property + $relations = ltrim($relations, "."); + + if (empty($relations)) { + return $this; } + + $this->map = explode(self::RELATION_SEP, $relations); + $this->depth = count($this->map); + + return $this; } /** @@ -86,14 +105,6 @@ public function getDepth(): int return $this->depth; } - /** - * @return string ucfirst string - */ - public function getProperty(): string - { - return ucfirst($this->property); - } - /** * @return bool */ @@ -103,10 +114,11 @@ public function isInUse(): bool } /** + * @param null $alias * @return ModelCriteria * @throws UseQueryFromDotNotationException */ - public function useQuery(): ModelCriteria + public function useQuery($alias = null): ModelCriteria { if ($this->inUse) { throw new UseQueryFromDotNotationException("A query is already in use and have not be terminated with UseQueryFromDotNotation::endUse()"); @@ -116,9 +128,10 @@ public function useQuery(): ModelCriteria foreach ($this->map as $relation) { $method = sprintf('use%sQuery', ucfirst($relation)); if (!method_exists($this->query, $method)) { - throw new RelationNotFoundException("Relation \"$relation\" Not Found in \"$this->dotProperty\""); + $path = implode(self::RELATION_SEP, $this->map); + throw new RelationNotFoundException("Relation \"$relation\" Not Found in \"$path\""); } - $this->query = call_user_func([$this->query, $method]); + $this->query = call_user_func([$this->query, $method], $alias); } } $this->inUse = true; diff --git a/tests/Service/QueryModifier/UseQuery/UseQueryFromDotNotationTest.php b/tests/Service/QueryModifier/UseQuery/UseQueryFromDotNotationTest.php index 6b998d2..faac358 100644 --- a/tests/Service/QueryModifier/UseQuery/UseQueryFromDotNotationTest.php +++ b/tests/Service/QueryModifier/UseQuery/UseQueryFromDotNotationTest.php @@ -33,28 +33,19 @@ public function testEndUse() { $query = $this->mockQueryInstance(); - $use = new UseQueryFromDotNotation($query, "aName"); - $use->useQuery(); - $this->assertSame(0, $use->getDepth()); - $usedQuery = $use->endUse(); - $this->assertInstanceOf(\AQuery::class, $usedQuery); - $this->assertSame("AName", $use->getProperty()); - $this->assertFalse($use->isInUse()); - $use = new UseQueryFromDotNotation($query, "b.bName"); - $use->useQuery(); + $use = new UseQueryFromDotNotation($query); + $use->fromString("b")->useQuery(); $this->assertSame(1, $use->getDepth()); $usedQuery = $use->endUse(); $this->assertInstanceOf(\AQuery::class, $usedQuery); - $this->assertSame("BName", $use->getProperty()); $this->assertFalse($use->isInUse()); - $use = new UseQueryFromDotNotation($query, "b.c.cName"); - $use->useQuery(); + $use = new UseQueryFromDotNotation($query); + $use->fromString("b.c")->useQuery(); $this->assertSame(2, $use->getDepth()); $usedQuery = $use->endUse(); $this->assertInstanceOf(\AQuery::class, $usedQuery); - $this->assertSame("CName", $use->getProperty()); $this->assertFalse($use->isInUse()); } @@ -64,7 +55,7 @@ public function testEndUse() public function testEndUseBeforeUse() { $query = $this->mockQueryInstance(); - $use = new UseQueryFromDotNotation($query, "zzz.foo"); + $use = new UseQueryFromDotNotation($query); $this->expectException(UseQueryFromDotNotationException::class); $use->endUse(); } @@ -82,21 +73,27 @@ public function testSeparatorValue() */ public function testUseQuery() { - $query = $this->mockQueryInstance(); - $use = new UseQueryFromDotNotation($query, "foo"); - $usedQuery = $use->useQuery(); - $this->assertInstanceOf(\AQuery::class, $usedQuery); - $this->assertTrue(method_exists($usedQuery, "filterByAName")); + // $query = $this->mockQueryInstance(); + // $use = new UseQueryFromDotNotation($query, "foo"); + // $usedQuery = $use->useQuery(); + // $this->assertInstanceOf(\AQuery::class, $usedQuery); + // $this->assertTrue(method_exists($usedQuery, "filterByAName")); $query = $this->mockQueryInstance(); - $use = new UseQueryFromDotNotation($query, "b.foo"); - $usedQuery = $use->useQuery(); + $use = new UseQueryFromDotNotation($query); + $usedQuery = $use->fromString("b")->useQuery(); + $this->assertInstanceOf(\BQuery::class, $usedQuery); + $this->assertTrue(method_exists($usedQuery, "filterByBName")); + + $query = $this->mockQueryInstance(); + $use = new UseQueryFromDotNotation($query); + $usedQuery = $use->fromArray(["b"])->useQuery(); $this->assertInstanceOf(\BQuery::class, $usedQuery); $this->assertTrue(method_exists($usedQuery, "filterByBName")); $query = $this->mockQueryInstance(); - $use = new UseQueryFromDotNotation($query, "b.c.foo"); - $usedQuery = $use->useQuery(); + $use = new UseQueryFromDotNotation($query); + $usedQuery = $use->fromString("b.c")->useQuery(); $this->assertInstanceOf(\CQuery::class, $usedQuery); $this->assertTrue(method_exists($usedQuery, "filterByCName")); } @@ -107,8 +104,8 @@ public function testUseQuery() public function testUseQueryAlreadyInUse() { $query = $this->mockQueryInstance(); - $use = new UseQueryFromDotNotation($query, "b.foo"); - $use->useQuery(); + $use = new UseQueryFromDotNotation($query); + $use->fromString("b")->useQuery(); $this->expectException(UseQueryFromDotNotationException::class); $use->useQuery(); } @@ -119,30 +116,26 @@ public function testUseQueryAlreadyInUse() public function testUseQueryRelationNotFound() { $query = $this->mockQueryInstance(); - $use = new UseQueryFromDotNotation($query, "zzz.foo"); + $use = new UseQueryFromDotNotation($query); $this->expectException(RelationNotFoundException::class); - $use->useQuery(); - } - - public function testUseQueryWithBadProperty() - { - $query = $this->mockQueryInstance(); - $this->expectException(\InvalidArgumentException::class); - new UseQueryFromDotNotation($query, "b."); + $use->fromString("zzz")->useQuery(); } public function testUseQueryWithDotBeforeProperty() { $query = $this->mockQueryInstance(); - $use = new UseQueryFromDotNotation($query, ".b"); - $this->assertSame(0, $use->getDepth()); + $use = new UseQueryFromDotNotation($query); + $use->fromString(".b"); + $this->assertSame(1, $use->getDepth()); } public function testUseQueryWithEmptyProperty() { $query = $this->mockQueryInstance(); - $this->expectException(\InvalidArgumentException::class); - new UseQueryFromDotNotation($query, ""); + $use = new UseQueryFromDotNotation($query); + $use->fromString(""); + $this->assertSame(0, $use->getDepth()); + } /**