diff --git a/system/Commands/Generators/ModelGenerator.php b/system/Commands/Generators/ModelGenerator.php index 5450bda79b4c..30b7422238fd 100644 --- a/system/Commands/Generators/ModelGenerator.php +++ b/system/Commands/Generators/ModelGenerator.php @@ -114,18 +114,23 @@ protected function prepare(string $class): string } if ($return === 'entity') { - $return = str_replace('Models', 'Entities', $class); + // Build the fully-qualified entity class from the model class so + // that the generated Entity keeps any sub-namespaces (eg. Admin). + $entityClass = str_replace('Models', 'Entities', $class); - if (preg_match('/^(\S+)Model$/i', $return, $match) === 1) { - $return = $match[1]; + if (preg_match('/^(\S+)Model$/i', $entityClass, $match) === 1) { + $entityClass = $match[1]; if ($this->getOption('suffix')) { - $return .= 'Entity'; + $entityClass .= 'Entity'; } } - $return = '\\' . trim($return, '\\') . '::class'; - $this->call('make:entity', array_merge([$baseClass], $this->params)); + // Call the entity generator with the fully-qualified class name so + // it ends up under the correct sub-namespace/folder (eg. Admin). + $this->call('make:entity', array_merge([trim($entityClass, '\\')], $this->params)); + + $return = '\\' . trim($entityClass, '\\') . '::class'; } else { $return = "'{$return}'"; } diff --git a/tests/system/Commands/Generators/ModelGeneratorTest.php b/tests/system/Commands/Generators/ModelGeneratorTest.php index 520bbbdc7a3b..8dab8b007f19 100644 --- a/tests/system/Commands/Generators/ModelGeneratorTest.php +++ b/tests/system/Commands/Generators/ModelGeneratorTest.php @@ -134,6 +134,33 @@ public function testGenerateModelWithOptionSuffix(): void rmdir(dirname($entity)); } + public function testGenerateModelWithSubNamespaceAndReturnEntity(): void + { + command('make:model admin/class --return entity'); + + $model = APPPATH . 'Models/Admin/Class.php'; + $entity = APPPATH . 'Entities/Admin/Class.php'; + + $this->assertFileExists($model); + $this->assertFileExists($entity); + + if (is_file($model)) { + unlink($model); + } + $modelDir = dirname($model); + if (is_dir($modelDir)) { + rmdir($modelDir); + } + + if (is_file($entity)) { + unlink($entity); + } + $entityDir = dirname($entity); + if (is_dir($entityDir)) { + rmdir($entityDir); + } + } + /** * @see https://github.com/codeigniter4/CodeIgniter4/issues/5050 */ diff --git a/user_guide_src/source/changelogs/v4.7.4.rst b/user_guide_src/source/changelogs/v4.7.4.rst index 87029861aaa0..9f2c440519a2 100644 --- a/user_guide_src/source/changelogs/v4.7.4.rst +++ b/user_guide_src/source/changelogs/v4.7.4.rst @@ -31,6 +31,7 @@ Bugs Fixed ********** - **API:** Fixed a bug in Transformers where the root request's ``fields`` and ``include`` query parameters leaked into nested transformers created inside ``include*()`` methods, causing incorrect field filtering, unexpected includes, or infinite recursion. +- **Commands:** Fixed a bug where ``make:model --return entity`` did not preserve sub-namespaces when generating the related Entity class. - **Commands:** Fixed a bug where ``spark lang:find`` treated translation keys already provided by the framework or another namespace (such as ``Errors.*`` in ``system/Language``) as new, listing them under ``--show-new`` and writing untranslated placeholders into ``app/Language`` that overrode the existing translations. - **Database:** Fixed a bug where ``updateBatch()`` could be called after Query Builder ``where()`` conditions, even though it's not supported. In this situation, now the ``DatabaseException`` is thrown. - **HTTP:** Fixed a bug where the User Agent library reported Safari's WebKit version instead of the browser version from the ``Version`` token.