From a1c385df70fb625f16eb0f1ca68fd8406d74f00e Mon Sep 17 00:00:00 2001 From: mringler Date: Sun, 13 Nov 2022 18:56:21 +0100 Subject: [PATCH] fixed input type of findBy hints --- .../Generator/Builder/Om/QueryBuilder.php | 181 +++++------------- .../Generator/Manager/AbstractManager.php | 4 +- src/Propel/Generator/Model/Table.php | 4 +- .../Generator/Reverse/SqliteSchemaParser.php | 6 +- src/Propel/Generator/Util/QuickBuilder.php | 4 +- src/Propel/Generator/Util/VfsTrait.php | 4 +- .../Runtime/Connection/ConnectionFactory.php | 2 +- templates/Builder/Om/baseQueryClassHeader.php | 92 +++++++++ 8 files changed, 152 insertions(+), 145 deletions(-) create mode 100644 templates/Builder/Om/baseQueryClassHeader.php diff --git a/src/Propel/Generator/Builder/Om/QueryBuilder.php b/src/Propel/Generator/Builder/Om/QueryBuilder.php index 9d6fde3590..0ed7d6c36d 100644 --- a/src/Propel/Generator/Builder/Om/QueryBuilder.php +++ b/src/Propel/Generator/Builder/Om/QueryBuilder.php @@ -8,6 +8,7 @@ namespace Propel\Generator\Builder\Om; +use Propel\Generator\Builder\Util\PropelTemplate; use Propel\Generator\Model\Column; use Propel\Generator\Model\CrossForeignKeys; use Propel\Generator\Model\ForeignKey; @@ -89,151 +90,61 @@ public function getParentClass(): string protected function addClassOpen(string &$script): void { $table = $this->getTable(); - $tableName = $table->getName(); - $tableDesc = $table->getDescription(); - $queryClass = $this->getQueryClassName(); - $modelClass = $this->getObjectClassName(); - $parentClass = $this->getParentClass(); - $script .= " -/** - * Base class that represents a query for the '$tableName' table. - * - * $tableDesc - *"; - if ($this->getBuildProperty('generator.objectModel.addTimeStamp')) { - $now = strftime('%c'); - $script .= " - * This class was autogenerated by Propel " . $this->getBuildProperty('general.version') . " on: - * - * $now - *"; - } - - // magic orderBy() methods, for IDE completion - foreach ($this->getTable()->getColumns() as $column) { - $script .= " - * @method $queryClass orderBy" . $column->getPhpName() . '($order = Criteria::ASC) Order by the ' . $column->getName() . ' column'; - } - $script .= " - *"; - - // magic groupBy() methods, for IDE completion - foreach ($this->getTable()->getColumns() as $column) { - $script .= " - * @method $queryClass groupBy" . $column->getPhpName() . '() Group by the ' . $column->getName() . ' column'; - } - - // override the signature of ModelCriteria::left-, right- and innerJoin to specify the class of the returned object, for IDE completion - $script .= " - * - * @method $queryClass leftJoin(\$relation) Adds a LEFT JOIN clause to the query - * @method $queryClass rightJoin(\$relation) Adds a RIGHT JOIN clause to the query - * @method $queryClass innerJoin(\$relation) Adds a INNER JOIN clause to the query - *"; - - $script .= " - * @method $queryClass leftJoinWith(\$relation) Adds a LEFT JOIN clause and with to the query - * @method $queryClass rightJoinWith(\$relation) Adds a RIGHT JOIN clause and with to the query - * @method $queryClass innerJoinWith(\$relation) Adds a INNER JOIN clause and with to the query - *"; - - $relationQueryClasses = []; - - // magic XXXjoinYYY() methods, for IDE completion - foreach ($this->getTable()->getForeignKeys() as $fk) { - $relationName = $this->getFKPhpNameAffix($fk); - - $script .= " - * @method $queryClass leftJoin" . $relationName . '($relationAlias = null) Adds a LEFT JOIN clause to the query using the ' . $relationName . " relation - * @method $queryClass rightJoin" . $relationName . '($relationAlias = null) Adds a RIGHT JOIN clause to the query using the ' . $relationName . " relation - * @method $queryClass innerJoin" . $relationName . '($relationAlias = null) Adds a INNER JOIN clause to the query using the ' . $relationName . " relation - *"; - - $script .= " - * @method $queryClass joinWith" . $relationName . '($joinType = Criteria::INNER_JOIN) Adds a join clause and with to the query using the ' . $relationName . " relation - *"; - - $script .= " - * @method $queryClass leftJoinWith" . $relationName . '() Adds a LEFT JOIN clause and with to the query using the ' . $relationName . " relation - * @method $queryClass rightJoinWith" . $relationName . '() Adds a RIGHT JOIN clause and with to the query using the ' . $relationName . " relation - * @method $queryClass innerJoinWith" . $relationName . '() Adds a INNER JOIN clause and with to the query using the ' . $relationName . " relation - *"; - - $relationQueryClasses[$this->getNewStubQueryBuilder($fk->getForeignTable())->getQueryClassName(true)] = true; - } - foreach ($this->getTable()->getReferrers() as $refFK) { - $relationName = $this->getRefFKPhpNameAffix($refFK); - - $script .= " - * @method $queryClass leftJoin" . $relationName . '($relationAlias = null) Adds a LEFT JOIN clause to the query using the ' . $relationName . " relation - * @method $queryClass rightJoin" . $relationName . '($relationAlias = null) Adds a RIGHT JOIN clause to the query using the ' . $relationName . " relation - * @method $queryClass innerJoin" . $relationName . '($relationAlias = null) Adds a INNER JOIN clause to the query using the ' . $relationName . " relation - *"; - $script .= " - * @method $queryClass joinWith" . $relationName . '($joinType = Criteria::INNER_JOIN) Adds a join clause and with to the query using the ' . $relationName . " relation - *"; + $vars = [ + 'tableName' => $table->getName(), + 'tableDesc' => $table->getDescription(), + 'queryClass' => $this->getQueryClassName(), + 'modelClass' => $this->getObjectClassName(), + 'parentClass' => $this->getParentClass(), + 'entityNotFoundExceptionClass' => $this->getEntityNotFoundExceptionClass(), + 'unqualifiedClassName' => $this->getUnqualifiedClassName(), - $script .= " - * @method $queryClass leftJoinWith" . $relationName . '() Adds a LEFT JOIN clause and with to the query using the ' . $relationName . " relation - * @method $queryClass rightJoinWith" . $relationName . '() Adds a RIGHT JOIN clause and with to the query using the ' . $relationName . " relation - * @method $queryClass innerJoinWith" . $relationName . '() Adds a INNER JOIN clause and with to the query using the ' . $relationName . " relation - *"; + 'addTimestamp' => $this->getBuildProperty('generator.objectModel.addTimeStamp'), + 'propelVersion' => $this->getBuildProperty('general.version'), - $relationQueryClasses[$this->getNewStubQueryBuilder($refFK->getTable())->getQueryClassName(true)] = true; - } + 'columns' => $table->getColumns(), - if ($relationQueryClasses) { - $relationQueryClasses = implode('|', array_keys($relationQueryClasses)); - $script .= " - * @method $relationQueryClasses endUse() Finalizes a secondary criteria and merges it with its primary Criteria - *"; - } + 'relationNames' => $this->getRelationNames(), + 'relatedTableQueryClassNames' => $this->getRelatedTableQueryClassNames(), + ]; - // override the signature of ModelCriteria::findOne() to specify the class of the returned object, for IDE completion - $script .= " - * @method $modelClass|null findOne(?ConnectionInterface \$con = null) Return the first $modelClass matching the query - * @method $modelClass findOneOrCreate(?ConnectionInterface \$con = null) Return the first $modelClass matching the query, or a new $modelClass object populated from the query conditions when no match is found - *"; + $templatePath = $this->getTemplatePath(__DIR__); - // magic findBy() methods, for IDE completion - foreach ($this->getTable()->getColumns() as $column) { - $script .= " - * @method $modelClass|null findOneBy" . $column->getPhpName() . '(' . $column->getPhpType() . ' $' . $column->getName() . ") Return the first $modelClass filtered by the " . $column->getName() . ' column'; - } + $template = new PropelTemplate(); + $filePath = $templatePath . 'baseQueryClassHeader.php'; + $template->setTemplateFile($filePath); - $script .= " * \n"; + $script .= $template->render($vars); + } - // override the signature of ModelCriteria::require*() to specify the class of the returned object, for IDE completion - $script .= " - * @method $modelClass requirePk(\$key, ?ConnectionInterface \$con = null) Return the $modelClass by primary key and throws {$this->getEntityNotFoundExceptionClass()} when not found - * @method $modelClass requireOne(?ConnectionInterface \$con = null) Return the first $modelClass matching the query and throws {$this->getEntityNotFoundExceptionClass()} when not found - *"; + /** + * Get names of all foreign key relations to and from this table. + * + * @return array + */ + protected function getRelationNames(): array + { + $table = $this->getTable(); + $fkRelationNames = array_map([$this, 'getFKPhpNameAffix'], $table->getForeignKeys()); + $refFkRelationNames = array_filter(array_map([$this, 'getRefFKPhpNameAffix'], $table->getReferrers())); - // magic requireOneBy() methods, for IDE completion - foreach ($this->getTable()->getColumns() as $column) { - $script .= " - * @method $modelClass requireOneBy" . $column->getPhpName() . '(' . $column->getPhpType() . ' $' . $column->getName() . ") Return the first $modelClass filtered by the " . $column->getName() . " column and throws {$this->getEntityNotFoundExceptionClass()} when not found"; - } + return array_merge($fkRelationNames, $refFkRelationNames); + } - $script .= " - * - * @method {$modelClass}[]|Collection find(?ConnectionInterface \$con = null) Return $modelClass objects based on current ModelCriteria - * @psalm-method Collection&\Traversable<{$modelClass}> find(?ConnectionInterface \$con = null) Return $modelClass objects based on current ModelCriteria"; - foreach ($this->getTable()->getColumns() as $column) { - $script .= " - * @method {$modelClass}[]|Collection findBy" . $column->getPhpName() . '(' . $column->getPhpType() . ' $' . $column->getName() . ") Return $modelClass objects filtered by the " . $column->getName() . ' column' . " - * @psalm-method Collection&\Traversable<{$modelClass}> findBy" . $column->getPhpName() . '(' . $column->getPhpType() . ' $' . $column->getName() . ") Return $modelClass objects filtered by the " . $column->getName() . ' column'; - } + /** + * Get query class names of all tables connected to this table with a foreign key relation. + * + * @return array + */ + protected function getRelatedTableQueryClassNames(): array + { + $table = $this->getTable(); + $fkTables = array_map(fn ($fk) => $fk->getForeignTable(), $table->getForeignKeys()); + $refFkTables = array_map(fn ($fk) => $fk->getTable(), $table->getReferrers()); + $relationTables = array_merge($fkTables, $refFkTables); - $script .= " - * @method {$modelClass}[]|\\Propel\\Runtime\\Util\\PropelModelPager paginate(\$page = 1, \$maxPerPage = 10, ?ConnectionInterface \$con = null) Issue a SELECT query based on the current ModelCriteria and uses a page and a maximum number of results per page to compute an offset and a limit - * @psalm-method \\Propel\\Runtime\\Util\\PropelModelPager&\Traversable<{$modelClass}> paginate(\$page = 1, \$maxPerPage = 10, ?ConnectionInterface \$con = null) Issue a SELECT query based on the current ModelCriteria and uses a page and a maximum number of results per page to compute an offset and a limit - * - */ -abstract class " . $this->getUnqualifiedClassName() . ' extends ' . $parentClass . " -{ - "; + return array_map(fn ($table) => $this->getNewStubQueryBuilder($table)->getQueryClassName(true), $relationTables); } /** @@ -327,7 +238,7 @@ protected function addClassBody(string &$script): void */ protected function addEntityNotFoundExceptionClass(string &$script): void { - $script .= "protected \$entityNotFoundExceptionClass = '" . addslashes($this->getEntityNotFoundExceptionClass()) . "';\n"; + $script .= " protected \$entityNotFoundExceptionClass = '" . addslashes($this->getEntityNotFoundExceptionClass()) . "';\n"; } /** diff --git a/src/Propel/Generator/Manager/AbstractManager.php b/src/Propel/Generator/Manager/AbstractManager.php index e03f07f974..9bb723df96 100644 --- a/src/Propel/Generator/Manager/AbstractManager.php +++ b/src/Propel/Generator/Manager/AbstractManager.php @@ -17,7 +17,7 @@ use Propel\Generator\Exception\EngineException; use Propel\Generator\Model\Database; use Propel\Generator\Model\Schema; -use XsltProcessor; +use XSLTProcessor; /** * An abstract base Propel manager to perform work related to the XML schema @@ -323,7 +323,7 @@ protected function loadDataModels(): void // normalize the document using normalizer stylesheet $xslDom = new DOMDocument('1.0', 'UTF-8'); $xslDom->load($this->xsl->getAbsolutePath()); - $xsl = new XsltProcessor(); + $xsl = new XSLTProcessor(); $xsl->importStyleSheet($xslDom); $dom = $xsl->transformToDoc($dom); } diff --git a/src/Propel/Generator/Model/Table.php b/src/Propel/Generator/Model/Table.php index b023f3f44e..0b29d5472a 100644 --- a/src/Propel/Generator/Model/Table.php +++ b/src/Propel/Generator/Model/Table.php @@ -1,13 +1,13 @@ + +/** + * Base class that represents a query for the table. + * + + * + * + + + * This class was autogenerated by Propel on: + * + * + * + + + * @method orderBygetPhpName() ?>($order = Criteria::ASC) Order by the getName() ?> column + + * + + * @method groupBygetPhpName() ?>() Group by the getName() ?> column'; + + * + * @method leftJoin($relation) Adds a LEFT JOIN clause to the query + * @method rightJoin($relation) Adds a RIGHT JOIN clause to the query + * @method innerJoin($relation) Adds a INNER JOIN clause to the query + * + * @method leftJoinWith($relation) Adds a LEFT JOIN clause and with to the query + * @method rightJoinWith($relation) Adds a RIGHT JOIN clause and with to the query + * @method innerJoinWith($relation) Adds a INNER JOIN clause and with to the query + * + + * @method leftJoin($relationAlias = null) Adds a LEFT JOIN clause to the query using the relation + * @method rightJoin($relationAlias = null) Adds a RIGHT JOIN clause to the query using the relation + * @method innerJoin($relationAlias = null) Adds a INNER JOIN clause to the query using the relation + * + * @method joinWith($joinType = Criteria::INNER_JOIN) Adds a join clause and with to the query using the ' . $relationName . " relation + * + * @method leftJoinWith() Adds a LEFT JOIN clause and with to the query using the relation + * @method rightJoinWith() Adds a RIGHT JOIN clause and with to the query using the relation + * @method innerJoinWith() Adds a INNER JOIN clause and with to the query using the relation + * + + + * @method endUse() Finalizes a secondary criteria and merges it with its primary Criteria + * + + * @method |null findOne(?ConnectionInterface $con = null) Return the first matching the query + * @method findOneOrCreate(?ConnectionInterface $con = null) Return the first matching the query, or a new object populated from the query conditions when no match is found + * + + * @method |null findOneBygetPhpName() ?>(getPhpType() ?> $getName() ?>) Return the first filtered by the getName() ?> column + + * + * @method requirePk($key, ?ConnectionInterface $con = null) Return the by primary key and throws when not found + * @method requireOne(?ConnectionInterface $con = null) Return the first matching the query and throws when not found + * + + * @method requireOneBygetPhpName() ?>(getPhpType() ?> $getName() ?>) Return the first filtered by the $name column and throws when not found + + * + * @method []|Collection find(?ConnectionInterface $con = null) Return objects based on current ModelCriteria + * @psalm-method Collection&\Traversable<> find(?ConnectionInterface $con = null) Return objects based on current ModelCriteria + * + + * @method []|Collection findBygetPhpName() ?>(getPhpType() ?>|array<getPhpType() ?>> $getName() ?>) Return objects filtered by the getName() ?> column + * @psalm-method Collection&\Traversable<> findBygetPhpName() ?>(getPhpType() ?>|array<getPhpType() ?>> $getName() ?>) Return objects filtered by the getName() ?> column + + * + * @method []|\Propel\Runtime\Util\PropelModelPager paginate($page = 1, $maxPerPage = 10, ?ConnectionInterface $con = null) Issue a SELECT query based on the current ModelCriteria and uses a page and a maximum number of results per page to compute an offset and a limit + * @psalm-method \Propel\Runtime\Util\PropelModelPager&\Traversable<> paginate($page = 1, $maxPerPage = 10, ?ConnectionInterface $con = null) Issue a SELECT query based on the current ModelCriteria and uses a page and a maximum number of results per page to compute an offset and a limit + */ +abstract class extends +{