diff --git a/system/Commands/Utilities/Publish.php b/system/Commands/Utilities/Publish.php index 3e19685cba81..13ffa96eafc6 100644 --- a/system/Commands/Utilities/Publish.php +++ b/system/Commands/Utilities/Publish.php @@ -67,17 +67,24 @@ class Publish extends BaseCommand * * @var array */ - protected $options = []; + protected $options = [ + '--namespace' => 'The namespace from which to search for files to publish. By default, all namespaces are analysed.', + ]; /** * Displays the help for the spark cli script itself. */ public function run(array $params) { - $directory = array_shift($params) ?? 'Publishers'; + $directory = $params[0] ?? 'Publishers'; + $namespace = $params['namespace'] ?? ''; - if ([] === $publishers = Publisher::discover($directory)) { - CLI::write(lang('Publisher.publishMissing', [$directory])); + if ([] === $publishers = Publisher::discover($directory, $namespace)) { + if ($namespace === '') { + CLI::write(lang('Publisher.publishMissing', [$directory])); + } else { + CLI::write(lang('Publisher.publishMissingNamespace', [$directory, $namespace])); + } return; } diff --git a/system/Language/en/Publisher.php b/system/Language/en/Publisher.php index eb18dfebd555..c2d6d51ec900 100644 --- a/system/Language/en/Publisher.php +++ b/system/Language/en/Publisher.php @@ -18,7 +18,8 @@ 'fileNotAllowed' => '"{0}" fails the following restriction for "{1}": {2}', // Publish Command - 'publishMissing' => 'No Publisher classes detected in {0} across all namespaces.', - 'publishSuccess' => '"{0}" published {1} file(s) to "{2}".', - 'publishFailure' => '"{0}" failed to publish to "{1}".', + 'publishMissing' => 'No Publisher classes detected in {0} across all namespaces.', + 'publishMissingNamespace' => 'No Publisher classes detected in {0} in the {1} namespace.', + 'publishSuccess' => '"{0}" published {1} file(s) to "{2}".', + 'publishFailure' => '"{0}" failed to publish to "{1}".', ]; diff --git a/system/Publisher/Publisher.php b/system/Publisher/Publisher.php index bf81f6079b60..d65765947db1 100644 --- a/system/Publisher/Publisher.php +++ b/system/Publisher/Publisher.php @@ -99,18 +99,24 @@ class Publisher extends FileCollection * * @return list */ - final public static function discover(string $directory = 'Publishers'): array + final public static function discover(string $directory = 'Publishers', string $namespace = ''): array { - if (isset(self::$discovered[$directory])) { - return self::$discovered[$directory]; + $key = implode('.', [$namespace, $directory]); + + if (isset(self::$discovered[$key])) { + return self::$discovered[$key]; } - self::$discovered[$directory] = []; + self::$discovered[$key] = []; /** @var FileLocatorInterface $locator */ $locator = service('locator'); - if ([] === $files = $locator->listFiles($directory)) { + $files = $namespace === '' + ? $locator->listFiles($directory) + : $locator->listNamespaceFiles($namespace, $directory); + + if ([] === $files) { return []; } @@ -119,13 +125,13 @@ final public static function discover(string $directory = 'Publishers'): array $className = $locator->findQualifiedNameFromPath($file); if ($className !== false && class_exists($className) && is_a($className, self::class, true)) { - self::$discovered[$directory][] = new $className(); + self::$discovered[$key][] = new $className(); } } - sort(self::$discovered[$directory]); + sort(self::$discovered[$key]); - return self::$discovered[$directory]; + return self::$discovered[$key]; } /** diff --git a/tests/system/Publisher/PublisherSupportTest.php b/tests/system/Publisher/PublisherSupportTest.php index 5854e1c516d9..e92bdd0c69c3 100644 --- a/tests/system/Publisher/PublisherSupportTest.php +++ b/tests/system/Publisher/PublisherSupportTest.php @@ -61,6 +61,20 @@ public function testDiscoverNothing(): void $this->assertSame([], $result); } + public function testDiscoverInNamespace(): void + { + $result = Publisher::discover('Publishers', 'Tests\Support'); + $this->assertCount(1, $result); + $this->assertInstanceOf(TestPublisher::class, $result[0]); + } + + public function testDiscoverInUnknowNamespace(): void + { + $result = Publisher::discover('Publishers', 'Nothing\App'); + + $this->assertSame([], $result); + } + public function testDiscoverStores(): void { $publisher = Publisher::discover()[0]; diff --git a/user_guide_src/source/changelogs/v4.6.0.rst b/user_guide_src/source/changelogs/v4.6.0.rst index d3dc4529d512..0432a20e3cac 100644 --- a/user_guide_src/source/changelogs/v4.6.0.rst +++ b/user_guide_src/source/changelogs/v4.6.0.rst @@ -160,6 +160,11 @@ Removed Deprecated Items Enhancements ************ +Publisher +========= + +- ``Publisher::discover()`` now accepts a second parameter (``namespace``) specifying the namespace in which publishers should be searched. See :ref:`discovery-in-a-specific-namespace` for the details. + Exceptions ========== diff --git a/user_guide_src/source/libraries/publisher.rst b/user_guide_src/source/libraries/publisher.rst index 99531eacca5b..69b5df6c9f0c 100644 --- a/user_guide_src/source/libraries/publisher.rst +++ b/user_guide_src/source/libraries/publisher.rst @@ -75,6 +75,31 @@ Most of the time you will not need to handle your own discovery, just use the pr By default on your class extension ``publish()`` will add all files from your ``$source`` and merge them out to your destination, overwriting on collision. +.. _discovery-in-a-specific-namespace: + +Discovery in a specific namespace +--------------------------------- + +.. versionadded:: 4.6.0 + +Since v4.6.0, you can also scan a specific namespace. This not only reduces the number of files to be scanned, +but also avoids the need to rerun a Publisher. All you need to do is specify the desired root namespace in the +second parameter of the ``discover()`` method. + +.. literalinclude:: publisher/016.php + +The specified namespace must be known to CodeIgniter. You can check the list of all namespaces using the "spark namespaces" command: + +.. code-block:: console + + php spark namespaces + +The "publish" command also offers the ``--namespace`` option to define the namespace when searching for Publishers that might come from a library. + +.. code-block:: console + + php spark publish --namespace Namespace\Vendor\Package + Security ======== diff --git a/user_guide_src/source/libraries/publisher/016.php b/user_guide_src/source/libraries/publisher/016.php new file mode 100644 index 000000000000..54f2beca5701 --- /dev/null +++ b/user_guide_src/source/libraries/publisher/016.php @@ -0,0 +1,5 @@ +