diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d0a563d37c..f14cd2714d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,14 +16,16 @@ jobs: matrix: php-version: [ '7.4', '8.2' ] db-type: [ sqlite, mysql, pgsql, agnostic ] - symfony-version: [ '4-min', '4-max', '5-min', '5-max', '6-min', '6-max' ] + symfony-version: [ '5-min', '5-max', '6-min', '6-max', '7-min', '7-max'] exclude: - - symfony-version: '4-min' - php-version: '8.2' - symfony-version: '6-min' php-version: '7.4' - symfony-version: '6-max' php-version: '7.4' + - symfony-version: '7-min' + php-version: '7.4' + - symfony-version: '7-max' + php-version: '7.4' env: DB_NAME: 'propel_tests' DB_USER: 'propel' @@ -125,6 +127,8 @@ jobs: else vendor/bin/phpunit -c tests/${{ matrix.db-type }}.phpunit.xml fi + env: + SYMFONY_VERSION: ${{ matrix.symfony-version }} - name: Code Coverage Report if: success() && matrix.php-version == '7.4' && matrix.symfony-version == '5-max' @@ -166,6 +170,8 @@ jobs: run: composer install --prefer-dist --no-interaction - name: PHPStan + env: + PHPSTAN: 1 run: composer stan - name: Psalm diff --git a/composer.json b/composer.json index 04ce929d84..829f9545c5 100644 --- a/composer.json +++ b/composer.json @@ -18,13 +18,13 @@ "require": { "php": ">=7.4", "psr/log": "^1.0 || ^2.0 || ^3.0", - "symfony/yaml": "^4.4.0 || ^5.0.0 || ^6.0.0", - "symfony/config": "^4.4.0 || ^5.0.0 || ^6.0.0", - "symfony/console": "^4.4.0 || ^5.0.0 || ^6.0.0", - "symfony/filesystem": "^4.4.0 || ^5.0.0 || ^6.0.0", - "symfony/finder": "^4.4.0 || ^5.0.0 || ^6.0.0", - "symfony/translation": "^4.4.0 || ^5.0.0 || ^6.0.0", - "symfony/validator": "^4.4.0 || ^5.0.0 || ^6.0.0" + "symfony/yaml": "^5.0.0 || ^6.0.0 || ^7.0.0", + "symfony/config": "^5.0.0 || ^6.0.0 || ^7.0.0", + "symfony/console": "^5.0.0 || ^6.0.0 || ^7.0.0", + "symfony/filesystem": "^5.0.0 || ^6.0.0 || ^7.0.0", + "symfony/finder": "^5.0.0 || ^6.0.0 || ^7.0.0", + "symfony/translation": "^5.0.0 || ^6.0.0 || ^7.0.0", + "symfony/validator": "^5.0.0 || ^6.0.0 || ^7.0.0" }, "require-dev": { "ext-pdo": "*", diff --git a/src/Propel/Generator/Behavior/Timestampable/TimestampableBehavior.php b/src/Propel/Generator/Behavior/Timestampable/TimestampableBehavior.php index 6c84c225fb..6152ef84cd 100644 --- a/src/Propel/Generator/Behavior/Timestampable/TimestampableBehavior.php +++ b/src/Propel/Generator/Behavior/Timestampable/TimestampableBehavior.php @@ -106,7 +106,7 @@ public function preUpdate(AbstractOMBuilder $builder): string : '\\Propel\\Runtime\\Util\\PropelDateTime::createHighPrecision()'; return 'if ($this->isModified() && !$this->isColumnModified(' . $this->getColumnConstant('update_column', $builder) . ")) { - \$this->" . $this->getColumnSetter('update_column') . "(${valueSource}); + \$this->" . $this->getColumnSetter('update_column') . "({$valueSource}); }"; } @@ -131,7 +131,7 @@ public function preInsert(AbstractOMBuilder $builder): string : '$highPrecision'; $script .= " if (!\$this->isColumnModified(" . $this->getColumnConstant('create_column', $builder) . ")) { - \$this->" . $this->getColumnSetter('create_column') . "(${valueSource}); + \$this->" . $this->getColumnSetter('create_column') . "({$valueSource}); }"; } @@ -141,7 +141,7 @@ public function preInsert(AbstractOMBuilder $builder): string : '$highPrecision'; $script .= " if (!\$this->isColumnModified(" . $this->getColumnConstant('update_column', $builder) . ")) { - \$this->" . $this->getColumnSetter('update_column') . "(${valueSource}); + \$this->" . $this->getColumnSetter('update_column') . "({$valueSource}); }"; } diff --git a/src/Propel/Generator/Builder/Om/AbstractOMBuilder.php b/src/Propel/Generator/Builder/Om/AbstractOMBuilder.php index ee87b51381..441a8ec94f 100644 --- a/src/Propel/Generator/Builder/Om/AbstractOMBuilder.php +++ b/src/Propel/Generator/Builder/Om/AbstractOMBuilder.php @@ -686,34 +686,43 @@ public function getFKPhpNameAffix(ForeignKey $fk, bool $plural = false): string * @return string */ protected function getCrossFKsPhpNameAffix(CrossForeignKeys $crossFKs, bool $plural = true): string + { + $baseName = $this->buildCombineCrossFKsPhpNameAffix($crossFKs, false); + + $existingTable = $this->getDatabase()->getTableByPhpName($baseName); + $isNameCollision = $existingTable && $this->getTable()->isConnectedWithTable($existingTable); + + return ($plural || $isNameCollision) ? $this->buildCombineCrossFKsPhpNameAffix($crossFKs, $plural, $isNameCollision) : $baseName; + } + + /** + * @param \Propel\Generator\Model\CrossForeignKeys $crossFKs + * @param bool $plural + * @param bool $withPrefix + * + * @return string + */ + protected function buildCombineCrossFKsPhpNameAffix(CrossForeignKeys $crossFKs, bool $plural = true, bool $withPrefix = false): string { $names = []; + if ($withPrefix) { + $names[] = 'Cross'; + } + $fks = $crossFKs->getCrossForeignKeys(); + $lastCrossFk = array_pop($fks); + $unclassifiedPrimaryKeys = $crossFKs->getUnclassifiedPrimaryKeys(); + $lastIsPlural = $plural && !$unclassifiedPrimaryKeys; - if ($plural) { - if ($crossFKs->getUnclassifiedPrimaryKeys()) { - //we have a non fk as pk as well, so we need to make pluralisation on our own and can't - //rely on getFKPhpNameAffix's pluralisation - foreach ($crossFKs->getCrossForeignKeys() as $fk) { - $names[] = $this->getFKPhpNameAffix($fk, false); - } - } else { - //we have only fks, so give us names with plural and return those - $lastIdx = count($crossFKs->getCrossForeignKeys()) - 1; - foreach ($crossFKs->getCrossForeignKeys() as $idx => $fk) { - $needPlural = $idx === $lastIdx; //only last fk should be plural - $names[] = $this->getFKPhpNameAffix($fk, $needPlural); - } + foreach ($fks as $fk) { + $names[] = $this->getFKPhpNameAffix($fk, false); + } + $names[] = $this->getFKPhpNameAffix($lastCrossFk, $lastIsPlural); - return implode('', $names); - } - } else { - // no plural, so $plural=false - foreach ($crossFKs->getCrossForeignKeys() as $fk) { - $names[] = $this->getFKPhpNameAffix($fk, false); - } + if (!$unclassifiedPrimaryKeys) { + return implode('', $names); } - foreach ($crossFKs->getUnclassifiedPrimaryKeys() as $pk) { + foreach ($unclassifiedPrimaryKeys as $pk) { $names[] = $pk->getPhpName(); } diff --git a/src/Propel/Generator/Command/MigrationUpCommand.php b/src/Propel/Generator/Command/MigrationUpCommand.php index cc79558bd5..daea8a44e5 100644 --- a/src/Propel/Generator/Command/MigrationUpCommand.php +++ b/src/Propel/Generator/Command/MigrationUpCommand.php @@ -44,7 +44,7 @@ protected function configure() * * @throws \Propel\Runtime\Exception\RuntimeException */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $configOptions = []; diff --git a/src/Propel/Generator/Model/CrossForeignKeys.php b/src/Propel/Generator/Model/CrossForeignKeys.php index c9bd647b60..61a09ff3a8 100644 --- a/src/Propel/Generator/Model/CrossForeignKeys.php +++ b/src/Propel/Generator/Model/CrossForeignKeys.php @@ -132,7 +132,7 @@ public function getIncomingForeignKey(): ?ForeignKey */ public function isAtLeastOneLocalPrimaryKeyNotCovered(ForeignKey $fk): bool { - $primaryKeys = $fk->getLocalPrimaryKeys(); + $primaryKeys = $fk->getLocalColumnObjects(); foreach ($primaryKeys as $primaryKey) { $covered = false; foreach ($this->getCrossForeignKeys() as $crossFK) { diff --git a/src/Propel/Generator/Model/ForeignKey.php b/src/Propel/Generator/Model/ForeignKey.php index ac7c5c25c6..b8da10a94f 100644 --- a/src/Propel/Generator/Model/ForeignKey.php +++ b/src/Propel/Generator/Model/ForeignKey.php @@ -874,7 +874,7 @@ public function isAtLeastOneLocalColumnRequired(): bool */ public function isAtLeastOneLocalPrimaryKeyIsRequired(): bool { - foreach ($this->getLocalPrimaryKeys() as $pk) { + foreach ($this->getLocalColumnObjects() as $pk) { if ($pk->isNotNull() && !$pk->hasDefaultValue()) { return true; } diff --git a/src/Propel/Generator/Model/Table.php b/src/Propel/Generator/Model/Table.php index 568832ec5d..2376ca0ab3 100644 --- a/src/Propel/Generator/Model/Table.php +++ b/src/Propel/Generator/Model/Table.php @@ -2288,4 +2288,18 @@ public function getAdditionalModelClassImports(): ?array return null; } + + /** + * Check if there is a FK rellation between the current table and the given + * table in either direction. + * + * @param \Propel\Generator\Model\Table $table + * + * @return bool + */ + public function isConnectedWithTable(Table $table): bool + { + return $this->getForeignKeysReferencingTable($table->getName()) || + $table->getForeignKeysReferencingTable($this->getName()); + } } diff --git a/src/Propel/Generator/Platform/PgsqlPlatform.php b/src/Propel/Generator/Platform/PgsqlPlatform.php index 67d927742b..9c1bdd8b03 100755 --- a/src/Propel/Generator/Platform/PgsqlPlatform.php +++ b/src/Propel/Generator/Platform/PgsqlPlatform.php @@ -10,6 +10,7 @@ use Propel\Generator\Exception\EngineException; use Propel\Generator\Model\Column; +use Propel\Generator\Model\ColumnDefaultValue; use Propel\Generator\Model\Database; use Propel\Generator\Model\Diff\ColumnDiff; use Propel\Generator\Model\Diff\TableDiff; @@ -515,6 +516,16 @@ public function getColumnDDL(Column $col): string $ddl[] = $sqlType; } + if ( + $col->getDefaultValue() + && $col->getDefaultValue()->isExpression() + && $col->getDefaultValue()->getValue() === 'CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP' + ) { + $col->setDefaultValue( + new ColumnDefaultValue('CURRENT_TIMESTAMP', ColumnDefaultValue::TYPE_EXPR), + ); + } + $default = $this->getColumnDefaultValueDDL($col); if ($default) { $ddl[] = $default; diff --git a/src/Propel/Generator/Platform/SqlitePlatform.php b/src/Propel/Generator/Platform/SqlitePlatform.php index 5484c7abdc..0edb834f41 100644 --- a/src/Propel/Generator/Platform/SqlitePlatform.php +++ b/src/Propel/Generator/Platform/SqlitePlatform.php @@ -492,7 +492,7 @@ public function getColumnDDL(Column $col): string if ( $col->getDefaultValue() && $col->getDefaultValue()->isExpression() - && $col->getDefaultValue()->getValue() === 'CURRENT_TIMESTAMP' + && in_array($col->getDefaultValue()->getValue(), ['CURRENT_TIMESTAMP', 'CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP']) ) { //sqlite use CURRENT_TIMESTAMP different than mysql/pgsql etc //we set it to the more common behavior diff --git a/src/Propel/Generator/Platform/Util/AlterTableStatementMerger.php b/src/Propel/Generator/Platform/Util/AlterTableStatementMerger.php index 1abca18b2f..e7020a325c 100644 --- a/src/Propel/Generator/Platform/Util/AlterTableStatementMerger.php +++ b/src/Propel/Generator/Platform/Util/AlterTableStatementMerger.php @@ -9,6 +9,7 @@ namespace Propel\Generator\Platform\Util; use Propel\Generator\Model\Table; +use Propel\Generator\Util\SqlParser; /** * Merges several ALTER TABLE statements when creating migrations. @@ -66,7 +67,10 @@ public function __construct(Table $table) */ public function mergeStatements(string $sql): string { - $statements = explode(';', $sql); + $sqlParser = new SqlParser(); + $sqlParser->setSQL($sql); + $statements = $sqlParser->explodeIntoStatements(); + $blocks = []; $currentBlock = []; diff --git a/src/Propel/Generator/Reverse/MysqlSchemaParser.php b/src/Propel/Generator/Reverse/MysqlSchemaParser.php index f7e1796b9d..0e1350739b 100644 --- a/src/Propel/Generator/Reverse/MysqlSchemaParser.php +++ b/src/Propel/Generator/Reverse/MysqlSchemaParser.php @@ -295,6 +295,9 @@ public function getColumnFromRow(array $row, Table $table): Column } if (in_array($default, ['CURRENT_TIMESTAMP', 'current_timestamp()'], true)) { $default = 'CURRENT_TIMESTAMP'; + if (strpos(strtolower($row['Extra']), 'on update current_timestamp') !== false) { + $default = 'CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'; + } $type = ColumnDefaultValue::TYPE_EXPR; } else { $type = ColumnDefaultValue::TYPE_VALUE; diff --git a/src/Propel/Generator/Util/SqlParser.php b/src/Propel/Generator/Util/SqlParser.php index b22d8dcc8f..175cc86ff8 100644 --- a/src/Propel/Generator/Util/SqlParser.php +++ b/src/Propel/Generator/Util/SqlParser.php @@ -232,14 +232,37 @@ public function explodeIntoStatements(): array public function getNextStatement(): string { $isAfterBackslash = false; + $isCommentLine = false; $isInString = false; $stringQuotes = ''; $parsedString = ''; $lowercaseString = ''; // helper variable for performance sake while ($this->pos <= $this->len) { $char = $this->sql[$this->pos] ?? ''; + + $newLine = !isset($this->sql[$this->pos - 1]) || $this->sql[$this->pos - 1] === PHP_EOL; + + // Skip comments + if ($isCommentLine === true) { + $this->pos++; + if ($char === PHP_EOL) { + $isCommentLine = false; // end of comments line + } + + continue; + } // check flags for strings or escaper switch ($char) { + case '#': + // detect comment line + if ($newLine === true && $isCommentLine === false) { + $this->pos++; + $isCommentLine = true; + + continue 2; + } + + break; case '\\': $isAfterBackslash = true; @@ -295,8 +318,9 @@ public function getNextStatement(): string // check for end of statement if ($char . $nextChars == $this->delimiter) { $this->pos += $i; // increase position + $parsedTrimmedString = trim($parsedString); - return trim($parsedString); + return $parsedTrimmedString ?: $parsedString; // to check empty line to avoid stop parsing } // avoid using strtolower on the whole parsed string every time new character is added // there is also no point in adding characters which are in the string diff --git a/src/Propel/Runtime/Collection/CollectionIterator.php b/src/Propel/Runtime/Collection/CollectionIterator.php index eb34683898..718972626d 100644 --- a/src/Propel/Runtime/Collection/CollectionIterator.php +++ b/src/Propel/Runtime/Collection/CollectionIterator.php @@ -248,8 +248,9 @@ public function append($value): void /** * @param int $flags Not used * - * @return bool + * @return true */ + #[\ReturnTypeWillChange] public function asort(int $flags = SORT_REGULAR): bool { parent::asort(); @@ -261,8 +262,9 @@ public function asort(int $flags = SORT_REGULAR): bool /** * @param int $flags Not used * - * @return bool + * @return true */ + #[\ReturnTypeWillChange] public function ksort(int $flags = SORT_REGULAR): bool { parent::ksort(); @@ -274,8 +276,9 @@ public function ksort(int $flags = SORT_REGULAR): bool /** * @param callable $callback * - * @return bool + * @return true */ + #[\ReturnTypeWillChange] public function uasort($callback): bool { parent::uasort($callback); @@ -287,8 +290,9 @@ public function uasort($callback): bool /** * @param callable $callback * - * @return bool + * @return true */ + #[\ReturnTypeWillChange] public function uksort($callback): bool { parent::uksort($callback); @@ -298,8 +302,9 @@ public function uksort($callback): bool } /** - * @return bool + * @return true */ + #[\ReturnTypeWillChange] public function natsort(): bool { parent::natsort(); @@ -309,8 +314,9 @@ public function natsort(): bool } /** - * @return bool + * @return true */ + #[\ReturnTypeWillChange] public function natcasesort(): bool { parent::natcasesort(); diff --git a/src/Propel/Runtime/Validator/Constraints/Date.php b/src/Propel/Runtime/Validator/Constraints/Date.php index 35c78fc31a..5c1da3714b 100644 --- a/src/Propel/Runtime/Validator/Constraints/Date.php +++ b/src/Propel/Runtime/Validator/Constraints/Date.php @@ -12,11 +12,6 @@ class Date extends SymfonyDateConstraint { - /** - * @var string - */ - public $message = 'This value is not a valid date.'; - /** * @var string */ diff --git a/tests/Fixtures/bookstore/schema.xml b/tests/Fixtures/bookstore/schema.xml index e9798e9399..d1fd6e58d4 100644 --- a/tests/Fixtures/bookstore/schema.xml +++ b/tests/Fixtures/bookstore/schema.xml @@ -174,6 +174,7 @@ + diff --git a/tests/Propel/Tests/Common/Config/Loader/FileLoaderTest.php b/tests/Propel/Tests/Common/Config/Loader/FileLoaderTest.php index 309c2ff922..efeaba7ba6 100644 --- a/tests/Propel/Tests/Common/Config/Loader/FileLoaderTest.php +++ b/tests/Propel/Tests/Common/Config/Loader/FileLoaderTest.php @@ -362,18 +362,14 @@ public function testCallResolveParamTwiceReturnsEmpty() class TestableFileLoader extends BaseFileLoader { - /** - * @return void - */ - public function load($resource, $type = null) + public function load($resource, $type = null): ?array { + return null; } - /** - * @return void - */ - public function supports($resource, $type = null) + public function supports($resource, $type = null): bool { + return false; } /** diff --git a/tests/Propel/Tests/Generator/Platform/MysqlPlatformMigrationMyISAMTest.php b/tests/Propel/Tests/Generator/Platform/MysqlPlatformMigrationMyISAMTest.php index 4bf6badd1c..845c87ba02 100644 --- a/tests/Propel/Tests/Generator/Platform/MysqlPlatformMigrationMyISAMTest.php +++ b/tests/Propel/Tests/Generator/Platform/MysqlPlatformMigrationMyISAMTest.php @@ -131,7 +131,7 @@ public function testGetModifyTableDDL($tableDiff) CHANGE `bar` `bar1` INTEGER, - CHANGE `baz` `baz` VARCHAR(12), + CHANGE `baz` `baz` VARCHAR(12) DEFAULT 'pdf;jpg;png;doc;docx;xls;xlsx;txt', ADD `baz3` TEXT AFTER `baz`; diff --git a/tests/Propel/Tests/Generator/Platform/MysqlPlatformMigrationTest.php b/tests/Propel/Tests/Generator/Platform/MysqlPlatformMigrationTest.php index 34f3f5a6be..8cefaf3e7f 100644 --- a/tests/Propel/Tests/Generator/Platform/MysqlPlatformMigrationTest.php +++ b/tests/Propel/Tests/Generator/Platform/MysqlPlatformMigrationTest.php @@ -139,7 +139,7 @@ public function testGetModifyTableDDL($tableDiff) CHANGE `bar` `bar1` INTEGER, - CHANGE `baz` `baz` VARCHAR(12), + CHANGE `baz` `baz` VARCHAR(12) DEFAULT 'pdf;jpg;png;doc;docx;xls;xlsx;txt', ADD `baz3` TEXT AFTER `baz`; diff --git a/tests/Propel/Tests/Generator/Platform/OraclePlatformMigrationTest.php b/tests/Propel/Tests/Generator/Platform/OraclePlatformMigrationTest.php index 841a321ef6..b6ca8135d3 100644 --- a/tests/Propel/Tests/Generator/Platform/OraclePlatformMigrationTest.php +++ b/tests/Propel/Tests/Generator/Platform/OraclePlatformMigrationTest.php @@ -105,7 +105,7 @@ public function testGetModifyTableDDL($tableDiff) MODIFY ( - baz NVARCHAR2(12) + baz NVARCHAR2(12) DEFAULT 'pdf;jpg;png;doc;docx;xls;xlsx;txt' ), ADD diff --git a/tests/Propel/Tests/Generator/Platform/PgsqlPlatformMigrationTest.php b/tests/Propel/Tests/Generator/Platform/PgsqlPlatformMigrationTest.php index 3a2838be91..13aa5e3c73 100755 --- a/tests/Propel/Tests/Generator/Platform/PgsqlPlatformMigrationTest.php +++ b/tests/Propel/Tests/Generator/Platform/PgsqlPlatformMigrationTest.php @@ -99,6 +99,8 @@ public function testGetModifyTableDDL($tableDiff) ALTER TABLE "foo" + ALTER COLUMN "baz" SET DEFAULT 'pdf;jpg;png;doc;docx;xls;xlsx;txt', + ALTER COLUMN "baz" DROP NOT NULL, ADD "baz3" TEXT; diff --git a/tests/Propel/Tests/Generator/Platform/PlatformMigrationTestProvider.php b/tests/Propel/Tests/Generator/Platform/PlatformMigrationTestProvider.php index 8c048786ee..6fa891bf29 100644 --- a/tests/Propel/Tests/Generator/Platform/PlatformMigrationTestProvider.php +++ b/tests/Propel/Tests/Generator/Platform/PlatformMigrationTestProvider.php @@ -107,7 +107,7 @@ public function providerForTestGetModifyTableDDL() - + diff --git a/tests/Propel/Tests/Generator/Reverse/MysqlSchemaParserTest.php b/tests/Propel/Tests/Generator/Reverse/MysqlSchemaParserTest.php index 607a51f9f6..cb3e42e6ad 100644 --- a/tests/Propel/Tests/Generator/Reverse/MysqlSchemaParserTest.php +++ b/tests/Propel/Tests/Generator/Reverse/MysqlSchemaParserTest.php @@ -9,6 +9,7 @@ namespace Propel\Tests\Generator\Reverse; use PDO; +use Propel\Generator\Model\ColumnDefaultValue; use Propel\Generator\Reverse\MysqlSchemaParser; use Propel\Tests\Bookstore\Map\BookTableMap; @@ -81,4 +82,15 @@ public function testDescriptionsAreImported(): void $this->assertEquals('Book Table', $bookTable->getDescription()); $this->assertEquals('Book Title', $bookTable->getColumn('title')->getDescription()); } + + /** + * @return void + */ + public function testOnUpdateIsImported(): void + { + $onUpdateTable = $this->parsedDatabase->getTable('bookstore_employee_account'); + $updatedAtColumn = $onUpdateTable->getColumn('updated'); + $this->assertEquals(ColumnDefaultValue::TYPE_EXPR, $updatedAtColumn->getDefaultValue()->getType()); + $this->assertEquals('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP', $updatedAtColumn->getDefaultValue()->getValue()); + } } diff --git a/tests/Propel/Tests/Issues/Issue941Test.php b/tests/Propel/Tests/Issues/Issue941Test.php new file mode 100644 index 0000000000..b581d76a77 --- /dev/null +++ b/tests/Propel/Tests/Issues/Issue941Test.php @@ -0,0 +1,104 @@ + +
+ +
+ + + +
+ + + + + + + + + + + + + + + + + +
+ + + +
+ + + '; + QuickBuilder::buildSchema($schema); + } + } + + /** + * @return void + */ + public function testIssue941() + { + $nature = new Nature(); + $nature->save(); + + $category = new Category(); + $category->save(); + + // RechercheNature + $rechercheNature = new RechercheNature(); + $rechercheNature->setNatureId($nature->getId()); + $rechercheNature->setCategoryId($category->getId()); + + // Collection + $collection = new ObjectCollection(); + $collection->setModel('\RechercheNature'); + $collection->setData([$rechercheNature]); + + // Recherche + $recherche = new Recherche(); + $recherche->setRechercheNatures($collection); + + $countBeforeSave = $recherche->countRechercheNatures(); + + $recherche->save(); + + $countAfterSave = $recherche->countRechercheNatures(); + + $this->assertEquals($countBeforeSave, $countAfterSave); + } +} diff --git a/tests/Propel/Tests/Issues/Issue989Test.php b/tests/Propel/Tests/Issues/Issue989Test.php index d21f839a33..28237c2816 100644 --- a/tests/Propel/Tests/Issues/Issue989Test.php +++ b/tests/Propel/Tests/Issues/Issue989Test.php @@ -38,6 +38,7 @@ protected function setUp(): void + diff --git a/tests/Propel/Tests/Issues/IssueIsCrossRefTest.php b/tests/Propel/Tests/Issues/IssueIsCrossRefTest.php new file mode 100644 index 0000000000..5e810d36e3 --- /dev/null +++ b/tests/Propel/Tests/Issues/IssueIsCrossRefTest.php @@ -0,0 +1,98 @@ + +
+ +
+ + +
+ + +
+ + +
+ + + + + + + + + + +
+ + + + + + + + + + +
+ +EOF; + QuickBuilder::buildSchema($schema); + } + } + + /** + * @return void + */ + public function testGenerateIsCrossRefCode() + { + $testGroupObject = new TestGroupObject(); + $testUserObject = new TestUserObject(); + $testGroupNegative = new TestGroupObjectNegative(); + $testUserNegative = new TestUserObjectNegative(); + + $this->assertTrue( + method_exists($testGroupObject, 'createTestUserObjectsQuery'), + 'Class does not have method createTestUserObjectsQuery' + ); + $this->assertTrue( + method_exists($testUserObject, 'createTestGroupObjectsQuery'), + 'Class does not have method createTestUserObjectsQuery' + ); + $this->assertFalse( + method_exists($testGroupNegative, 'createTestUserObjectNegativesQuery'), + 'Class does not have method createTestUserObjectsQuery' + ); + $this->assertFalse( + method_exists($testUserNegative, 'createTestGroupObjectNegativesQuery'), + 'Class does not have method createTestUserObjectsQuery' + ); + } +} diff --git a/tests/Propel/Tests/Runtime/Connection/PropelPDOTest.php b/tests/Propel/Tests/Runtime/Connection/PropelPDOTest.php index 4ec4ec52d3..31d299753d 100644 --- a/tests/Propel/Tests/Runtime/Connection/PropelPDOTest.php +++ b/tests/Propel/Tests/Runtime/Connection/PropelPDOTest.php @@ -564,7 +564,7 @@ class LastMessageHandler extends AbstractHandler * * @return bool */ - public function handle(array $record): bool + public function handle($record): bool { $this->latestMessage = (string)$record['message']; diff --git a/tests/composer/composer-symfony7-max.json b/tests/composer/composer-symfony7-max.json new file mode 100644 index 0000000000..3aef25cc10 --- /dev/null +++ b/tests/composer/composer-symfony7-max.json @@ -0,0 +1,66 @@ +{ + "name": "propel/propel", + "type": "library", + "description": "Propel2 is an open-source Object-Relational Mapping (ORM) for PHP 5.5 and up.", + "keywords": [ + "ORM", + "persistence", + "Active Record" + ], + "homepage": "http://www.propelorm.org/", + "license": "MIT", + "authors": [ + { + "name": "William Durand", + "email": "william.durand1@gmail.com" + } + ], + "require": { + "php": ">=8.2", + "symfony/yaml": "^7.0.0", + "symfony/config": "^7.0.0", + "symfony/console": "^7.0.0", + "symfony/filesystem": "^7.0.0", + "symfony/finder": "^7.0.0", + "symfony/translation": "^7.0.0", + "symfony/validator": "^7.0.0", + "psr/log": "^1.0 || ^2.0 || ^3.0" + }, + "require-dev": { + "ext-pdo": "*", + "ext-json": "*", + "ext-xml": "*", + "monolog/monolog": "^1.3 || ^2.3 || ^3.0", + "phpstan/phpstan": "^1.2", + "phpunit/phpunit": "^9.5.0", + "spryker/code-sniffer": "^0.17.2", + "psalm/phar": "^4.23", + "mikey179/vfsstream": "^1.6" + }, + "suggest": { + "monolog/monolog": "The recommended logging library to use with Propel." + }, + "autoload": { + "psr-4": { + "Propel\\": "src/Propel/" + } + }, + "bin": [ + "bin/propel" + ], + "scripts": { + "stan": [ + "vendor/bin/phpstan analyze -l 1 -c tests/phpstan.neon src/" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } + } +} diff --git a/tests/composer/composer-symfony7-min.json b/tests/composer/composer-symfony7-min.json new file mode 100644 index 0000000000..400da1df29 --- /dev/null +++ b/tests/composer/composer-symfony7-min.json @@ -0,0 +1,66 @@ +{ + "name": "propel/propel", + "type": "library", + "description": "Propel2 is an open-source Object-Relational Mapping (ORM) for PHP 5.5 and up.", + "keywords": [ + "ORM", + "persistence", + "Active Record" + ], + "homepage": "http://www.propelorm.org/", + "license": "MIT", + "authors": [ + { + "name": "William Durand", + "email": "william.durand1@gmail.com" + } + ], + "require": { + "php": ">=8.2", + "symfony/yaml": "~7.0.0", + "symfony/config": "~7.0.0", + "symfony/console": "~7.0.0", + "symfony/filesystem": "~7.0.0", + "symfony/finder": "~7.0.0", + "symfony/translation": "~7.0.0", + "symfony/validator": "~7.0.0", + "psr/log": "^1.0 || ^2.0 || ^3.0" + }, + "require-dev": { + "ext-pdo": "*", + "ext-json": "*", + "ext-xml": "*", + "monolog/monolog": "^1.3 || ^2.3 || ^3.0", + "phpstan/phpstan": "^1.2", + "phpunit/phpunit": "^9.5.0", + "spryker/code-sniffer": "^0.17.2", + "psalm/phar": "^4.23", + "mikey179/vfsstream": "^1.6" + }, + "suggest": { + "monolog/monolog": "The recommended logging library to use with Propel." + }, + "autoload": { + "psr-4": { + "Propel\\": "src/Propel/" + } + }, + "bin": [ + "bin/propel" + ], + "scripts": { + "stan": [ + "vendor/bin/phpstan analyze -l 1 -c tests/phpstan.neon src/" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } + } +}