Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge 3.x => 3.next #1023

Merged
merged 19 commits into from
Dec 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
d9bbe8e
Update version for 5.1.0
markstory Sep 14, 2024
02a449b
add note to remove method hooks in generated template if not needed
LordSimal Oct 4, 2024
1f1a4d0
Merge pull request #1005 from cakephp/3.x-plugin-class-template
markstory Oct 4, 2024
04b86ae
Add `standalone-path` option for plugin commmand.
ADmad Oct 6, 2024
b6ced75
Merge pull request #1007 from cakephp/feature/plugin-vendor
markstory Oct 7, 2024
be167ce
Update CakePHP version in URLs
ADmad Oct 8, 2024
8be277c
Add getDescription() to command template
ADmad Oct 8, 2024
dc3ec51
Merge pull request #1009 from cakephp/chore/version-update
markstory Oct 8, 2024
ccb0c78
Merge pull request #1008 from cakephp/feat/command
markstory Oct 8, 2024
5b61eb4
update stan
LordSimal Nov 17, 2024
9ea800f
Merge pull request #1013 from cakephp/3.x-update-stan
ADmad Nov 17, 2024
0fc3664
3.x-bake-model-relations
dereuromark Nov 21, 2024
4a4a1ff
Allow all --everything to run through using force mode.
dereuromark Nov 27, 2024
cc4d496
Allow all --everything to run through using force mode.
dereuromark Nov 27, 2024
5cd63bb
Merge pull request #1019 from cakephp/3.x-bake-all-force
markstory Nov 27, 2024
0f28cba
Make sure custom relations work out with new alias strictness. (#1015)
dereuromark Nov 28, 2024
59219f4
ignore shadow translations tables *_translations
dereuromark Nov 28, 2024
f615076
Merge pull request #1020 from cakephp/3.x-i18n
markstory Nov 29, 2024
8673a0d
Merge pull request #1014 from cakephp/dereuromark-patch-1
dereuromark Dec 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .phive/phars.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<phive xmlns="https://phar.io/phive">
<phar name="phpstan" version="1.11.9" installed="1.11.9" location="./tools/phpstan" copy="false"/>
<phar name="psalm" version="5.25.0" installed="5.25.0" location="./tools/psalm" copy="false"/>
<phar name="phpstan" version="2.0.1" installed="2.0.1" location="./tools/phpstan" copy="false"/>
<phar name="psalm" version="5.26.1" installed="5.26.1" location="./tools/psalm" copy="false"/>
</phive>
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"require": {
"php": ">=8.1",
"brick/varexporter": "^0.5.0",
"cakephp/cakephp": "dev-5.next as 5.1.0",
"cakephp/cakephp": "^5.1",
"cakephp/twig-view": "^2.0.0",
"nikic/php-parser": "^5.0.0"
},
Expand Down
4 changes: 2 additions & 2 deletions docs/en/development.rst
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ looks like this::
/**
* Hook method for defining this command's option parser.
*
* @see https://book.cakephp.org/4/en/console-commands/commands.html#defining-arguments-and-options
* @see https://book.cakephp.org/5/en/console-commands/commands.html#defining-arguments-and-options
* @param \Cake\Console\ConsoleOptionParser $parser The parser to be defined
* @return \Cake\Console\ConsoleOptionParser The built parser.
*/
Expand Down Expand Up @@ -172,7 +172,7 @@ And the resultant baked class (**src/Command/FooCommand.php**) looks like this::
/**
* Hook method for defining this command's option parser.
*
* @see https://book.cakephp.org/4/en/console-commands/commands.html#defining-arguments-and-options
* @see https://book.cakephp.org/5/en/console-commands/commands.html#defining-arguments-and-options
* @param \Cake\Console\ConsoleOptionParser $parser The parser to be defined
* @return \Cake\Console\ConsoleOptionParser The built parser.
*/
Expand Down
12 changes: 12 additions & 0 deletions docs/en/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ You can get the list of available bake command by running ``bin/cake bake --help
To run a command, type `cake command_name [args|options]`
To get help on a specific command, type `cake command_name --help`

Bake Models
===========

Models are generically baked from the existing DB tables.
The conventions here apply, so it will detect relations based on ``thing_id`` foreign keys to ``things`` tables with their ``id`` primary keys.

For non-conventional relations, you can use references in the constraints / foreign key definitions for Bake to detect the relations, e.g.::

->addForeignKey('billing_country_id', 'countries') // defaults to `id`
->addForeignKey('shipping_country_id', 'countries', 'cid')


Bake Themes
===========

Expand Down
4 changes: 2 additions & 2 deletions docs/fr/development.rst
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ ressemble à ceci::
/**
* Méthode hook pour définir le parseur d'option de cette commande.
*
* @see https://book.cakephp.org/4/fr/console-commands/commands.html#defining-arguments-and-options
* @see https://book.cakephp.org/5/fr/console-commands/commands.html#defining-arguments-and-options
* @param \Cake\Console\ConsoleOptionParser $parser Le parseur à définir
* @return \Cake\Console\ConsoleOptionParser Le parseur construit.
*/
Expand Down Expand Up @@ -181,7 +181,7 @@ ressemble à ceci::
/**
* Méthode hook pour définir le parseur d'option de cette commande.
*
* @see https://book.cakephp.org/4/fr/console-commands/commands.html#defining-arguments-and-options
* @see https://book.cakephp.org/5/fr/console-commands/commands.html#defining-arguments-and-options
* @param \Cake\Console\ConsoleOptionParser $parser Le parseur à définir
* @return \Cake\Console\ConsoleOptionParser Le parseur construit.
*/
Expand Down
12 changes: 10 additions & 2 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
parameters:
ignoreErrors:
-
message: "#^Instanceof between mixed and Cake\\\\Chronos\\\\Chronos will always evaluate to false\\.$#"
message: '#^Method Bake\\BakePlugin\:\:bootstrap\(\) has parameter \$app with generic interface Cake\\Core\\PluginApplicationInterface but does not specify its types\: TSubject$#'
identifier: missingType.generics
count: 1
path: src/BakePlugin.php

-
message: '#^Instanceof between mixed and Cake\\Chronos\\Chronos will always evaluate to false\.$#'
identifier: instanceof.alwaysFalse
count: 1
path: src/Command/FixtureCommand.php

-
message: "#^Dead catch \\- UnexpectedValueException is never thrown in the try block\\.$#"
message: '#^Dead catch \- UnexpectedValueException is never thrown in the try block\.$#'
identifier: catch.neverThrown
count: 1
path: src/Command/TestCommand.php
7 changes: 2 additions & 5 deletions src/BakePlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ class BakePlugin extends BasePlugin
/**
* Load the TwigView plugin.
*
* @phpstan-ignore-next-line
* @param \Cake\Core\PluginApplicationInterface $app The host application
* @return void
*/
Expand Down Expand Up @@ -138,22 +137,20 @@ protected function findInPath(string $namespace, string $path): array
if ($item->isDot() || $item->isDir()) {
continue;
}
/** @psalm-var class-string<\Bake\Command\BakeCommand> $class */
$class = $namespace . $item->getBasename('.php');

if (!$hasSubfolder) {
try {
$reflection = new ReflectionClass($class);
/** @phpstan-ignore-next-line */
} catch (ReflectionException $e) {
} catch (ReflectionException) {
continue;
}
/** @psalm-suppress TypeDoesNotContainType */
if (!$reflection->isInstantiable() || !$reflection->isSubclassOf(BakeCommand::class)) {
continue;
}
}

/** @var class-string<\Bake\Command\BakeCommand> $class */
$candidates[$class::defaultName()] = $class;
}

Expand Down
35 changes: 26 additions & 9 deletions src/Command/AllCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Cake\Console\ConsoleIo;
use Cake\Console\ConsoleOptionParser;
use Cake\Datasource\ConnectionManager;
use Throwable;

/**
* Command for `bake all`
Expand Down Expand Up @@ -49,7 +50,7 @@ public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionPar
$parser = $this->_setCommonOptions($parser);

$parser = $parser->setDescription(
'Generate the model, controller, template, tests and fixture for a table.'
'Generate the model, controller, template, tests and fixture for a table.',
)->addArgument('name', [
'help' => 'Name of the table to generate code for.',
])->addOption('everything', [
Expand Down Expand Up @@ -83,20 +84,21 @@ public function execute(Arguments $args, ConsoleIo $io): ?int
/** @var \Cake\Database\Connection $connection */
$connection = ConnectionManager::get($this->connection);
$scanner = new TableScanner($connection);
if (empty($name) && !$args->getOption('everything')) {
$tables = $scanner->removeShadowTranslationTables($scanner->listUnskipped());

if (!$name && !$args->getOption('everything')) {
$io->out('Choose a table to generate from the following:');
foreach ($scanner->listUnskipped() as $table) {
foreach ($tables as $table) {
$io->out('- ' . $this->_camelize($table));
}

return static::CODE_SUCCESS;
}
if ($args->getOption('everything')) {
$tables = $scanner->listUnskipped();
} else {
if (!$args->getOption('everything')) {
$tables = [$name];
}

$errors = 0;
foreach ($this->commands as $commandName) {
/** @var \Cake\Command\Command $command */
$command = new $commandName();
Expand All @@ -113,12 +115,27 @@ public function execute(Arguments $args, ConsoleIo $io): ?int
foreach ($tables as $table) {
$parser = $command->getOptionParser();
$subArgs = new Arguments([$table], $options, $parser->argumentNames());
$command->execute($subArgs, $io);

try {
$command->execute($subArgs, $io);
} catch (Throwable $e) {
if (!$args->getOption('everything') || !$args->getOption('force')) {
throw $e;
}

$message = sprintf('Error generating %s for %s: %s', $commandName, $table, $e->getMessage());
$io->err('<error>' . $message . '</error>');
$errors++;
}
}
}

$io->out('<success>Bake All complete.</success>', 1, ConsoleIo::NORMAL);
if ($errors) {
$io->out(sprintf('<warning>Bake All completed, but with %s errors.</warning>', $errors), 1, ConsoleIo::NORMAL);
} else {
$io->out('<success>Bake All complete.</success>', 1, ConsoleIo::NORMAL);
}

return static::CODE_SUCCESS;
return $errors ? static::CODE_ERROR : static::CODE_SUCCESS;
}
}
4 changes: 3 additions & 1 deletion src/Command/FixtureAllCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ public function execute(Arguments $args, ConsoleIo $io): ?int
$connection = ConnectionManager::get($args->getOption('connection') ?? 'default');
$scanner = new TableScanner($connection);
$fixture = new FixtureCommand();
foreach ($scanner->listUnskipped() as $table) {

$tables = $scanner->removeShadowTranslationTables($scanner->listUnskipped());
foreach ($tables as $table) {
$fixtureArgs = new Arguments([$table], $args->getOptions(), ['name']);
$fixture->execute($fixtureArgs, $io);
}
Expand Down
3 changes: 2 additions & 1 deletion src/Command/ModelAllCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ public function execute(Arguments $args, ConsoleIo $io): ?int
/** @var \Cake\Database\Connection $connection */
$connection = ConnectionManager::get($this->connection);
$scanner = new TableScanner($connection);
foreach ($scanner->listUnskipped() as $table) {
$tables = $scanner->removeShadowTranslationTables($scanner->listUnskipped());
foreach ($tables as $table) {
$this->getTableLocator()->clear();
$modelArgs = new Arguments([$table], $args->getOptions(), ['name']);
$this->modelCommand->execute($modelArgs, $io);
Expand Down
53 changes: 50 additions & 3 deletions src/Command/ModelCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,8 @@ public function getAssociations(Table $table, Arguments $args, ConsoleIo $io): a
$associations = $this->findHasMany($table, $associations);
$associations = $this->findBelongsToMany($table, $associations);

$associations = $this->ensureAliasUniqueness($associations);

return $associations;
}

Expand All @@ -275,6 +277,7 @@ public function applyAssociations(Table $model, array $associations): void
if (get_class($model) !== Table::class) {
return;
}

foreach ($associations as $type => $assocs) {
foreach ($assocs as $assoc) {
$alias = $assoc['alias'];
Expand Down Expand Up @@ -349,6 +352,7 @@ public function findBelongsTo(Table $model, array $associations, ?Arguments $arg
continue;
}

$className = null;
if ($fieldName === 'parent_id') {
$className = $this->plugin ? $this->plugin . '.' . $model->getAlias() : $model->getAlias();
$assoc = [
Expand All @@ -375,7 +379,7 @@ public function findBelongsTo(Table $model, array $associations, ?Arguments $arg
$allowAliasRelations = $args && $args->getOption('skip-relation-check');
$found = $this->findTableReferencedBy($schema, $fieldName);
if ($found) {
$tmpModelName = Inflector::camelize($found);
$className = ($this->plugin ? $this->plugin . '.' : '') . Inflector::camelize($found);
} elseif (!$allowAliasRelations) {
continue;
}
Expand All @@ -384,6 +388,9 @@ public function findBelongsTo(Table $model, array $associations, ?Arguments $arg
'alias' => $tmpModelName,
'foreignKey' => $fieldName,
];
if ($className && $className !== $tmpModelName) {
$assoc['className'] = $className;
}
if ($schema->getColumn($fieldName)['null'] === false) {
$assoc['joinType'] = 'INNER';
}
Expand All @@ -392,6 +399,7 @@ public function findBelongsTo(Table $model, array $associations, ?Arguments $arg
if ($this->plugin && empty($assoc['className'])) {
$assoc['className'] = $this->plugin . '.' . $assoc['alias'];
}

$associations['belongsTo'][] = $assoc;
}

Expand Down Expand Up @@ -1243,7 +1251,7 @@ public function bakeTable(Table $model, array $data, Arguments $args, ConsoleIo
}

/**
* Outputs the a list of possible models or controllers from database
* Outputs the list of possible models or controllers from database
*
* @return array<string>
*/
Expand All @@ -1262,7 +1270,7 @@ public function listAll(): array
}

/**
* Outputs the a list of unskipped models or controllers from database
* Outputs the list of unskipped models or controllers from database
*
* @return array<string>
*/
Expand Down Expand Up @@ -1546,4 +1554,43 @@ protected function bakeEnums(Table $model, array $data, Arguments $args, Console
$enumCommand->execute($args, $io);
}
}

/**
* @param array<string, array<string, mixed>> $associations
* @return array<string, array<string, mixed>>
*/
protected function ensureAliasUniqueness(array $associations): array
{
$existing = [];
foreach ($associations as $type => $associationsPerType) {
foreach ($associationsPerType as $k => $association) {
$alias = $association['alias'];
if (in_array($alias, $existing, true)) {
$alias = $this->createAssociationAlias($association);
}
$existing[] = $alias;
if (empty($association['className'])) {
$className = $this->plugin ? $this->plugin . '.' . $association['alias'] : $association['alias'];
if ($className !== $alias) {
$association['className'] = $className;
}
}
$association['alias'] = $alias;
$associations[$type][$k] = $association;
}
}

return $associations;
}

/**
* @param array<string, mixed> $association
* @return string
*/
protected function createAssociationAlias(array $association): string
{
$foreignKey = $association['foreignKey'];

return $this->_modelNameFromKey($foreignKey);
}
}
Loading
Loading