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
+ }
+ }
+}