Page Menu
Home
DevCentral
Search
Configure Global Search
Log In
Files
F3775592
D2507.id6323.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
6 KB
Referenced Files
None
Subscribers
None
D2507.id6323.diff
View Options
diff --git a/src/IO/Directory.php b/src/IO/Directory.php
--- a/src/IO/Directory.php
+++ b/src/IO/Directory.php
@@ -75,4 +75,15 @@
);
}
+ /**
+ * @return Directory[]
+ */
+ public function getSubdirectories () : array {
+ return array_map(
+ function ($dir) {
+ return new Directory($dir);
+ }, glob("$this->path/*", GLOB_ONLYDIR)
+ );
+ }
+
}
diff --git a/src/Registration/PSR4/PSR4Namespace.php b/src/Registration/PSR4/PSR4Namespace.php
new file mode 100644
--- /dev/null
+++ b/src/Registration/PSR4/PSR4Namespace.php
@@ -0,0 +1,75 @@
+<?php
+
+namespace Keruald\OmniTools\Registration\PSR4;
+
+use Keruald\OmniTools\IO\Directory;
+use Keruald\OmniTools\IO\File;
+
+class PSR4Namespace {
+
+ public function __construct (
+ public string $namespacePrefix,
+ public string $baseDirectory,
+ ) {
+ }
+
+ ///
+ /// Auto-discovery
+ ///
+
+ /**
+ * Discover classes in the namespace folder following PSR-4 convention,
+ * directly at top-level, ignoring subdirectories.
+ *
+ * @see discoverRecursive
+ * @return string[]
+ */
+ public function discover () : array {
+ $files = (new Directory($this->baseDirectory))
+ ->glob("*.php");
+
+ return array_map(function (File $file) {
+ return $this->namespacePrefix
+ . "\\" . $file->getFileNameWithoutExtension();
+ }, $files);
+ }
+
+ /**
+ * Discover classes in the namespace folder following PSR-4 convention,
+ * including all subfolders.
+ *
+ * @return string[]
+ */
+ public function discoverRecursive () : array {
+ $classes = $this->discover();
+
+ $subDirectories = (new Directory($this->baseDirectory))
+ ->getSubdirectories();
+
+ foreach ($subDirectories as $dir) {
+ $ns = new PSR4Namespace(
+ $this->namespacePrefix . "\\" . $dir->getDirectoryName(),
+ $dir->getPath(),
+ );
+
+ array_push($classes, ...$ns->discoverRecursive());
+ }
+
+ return $classes;
+ }
+
+ /**
+ * Discover classes for a specific namespace in a specific folder,
+ * following the PSR-4 convention, including all subfolders.
+ *
+ * @return string[]
+ */
+ public static function discoverAllClasses (
+ string $namespacePrefix,
+ string $baseDirectory
+ ) : array {
+ $ns = new PSR4Namespace($namespacePrefix, $baseDirectory);
+ return $ns->discoverRecursive();
+ }
+
+}
diff --git a/tests/Registration/PSR4/PSR4NamespaceTest.php b/tests/Registration/PSR4/PSR4NamespaceTest.php
new file mode 100644
--- /dev/null
+++ b/tests/Registration/PSR4/PSR4NamespaceTest.php
@@ -0,0 +1,83 @@
+<?php
+
+namespace Keruald\OmniTools\Tests\Registration\PSR4;
+
+use Keruald\OmniTools\Registration\PSR4\PSR4Namespace;
+
+use Keruald\OmniTools\Tests\WithData;
+use PHPUnit\Framework\TestCase;
+
+class PSR4NamespaceTest extends TestCase {
+
+ use WithData;
+
+ ///
+ /// Discovery tests
+ ///
+
+ const ALL_CLASSES = [
+ "Acme\\SolarSystemLib\\Sun",
+ "Acme\\SolarSystemLib\\Planets\\Pluton",
+ "Acme\\SolarSystemLib\\Planets\\Inner\\Mercure",
+ "Acme\\SolarSystemLib\\Planets\\Inner\\Venus",
+ ];
+
+ /**
+ * @dataProvider provideClasses
+ */
+ public function testDiscover (
+ string $path, string $prefix, array $expected
+ ) : void {
+ $ns = new PSR4Namespace($prefix, $this->getDataPath($path));
+
+ $this->assertEquals($expected, $ns->discover());
+ }
+
+ public function testDiscoverRecursive () : void {
+ $baseDirectory = $this->getDataPath("SolarSystemLib");
+ $ns = new PSR4Namespace("Acme\\SolarSystemLib", $baseDirectory);
+
+ $this->assertEquals(self::ALL_CLASSES, $ns->discoverRecursive());
+ }
+
+ public function testDiscoverAllClasses () : void {
+ $actual = PSR4Namespace::discoverAllClasses(
+ "Acme\\SolarSystemLib",
+ $this->getDataPath("SolarSystemLib"),
+ );
+
+ $this->assertEquals(self::ALL_CLASSES, $actual);
+
+ }
+
+ ///
+ /// Data providers
+ ///
+
+ public function provideClasses () : iterable {
+ // [string $path, string $prefix, string[] $expectedClasses]
+ yield ["MockLib", "Acme\\MockLib", [
+ "Acme\\MockLib\\Bar",
+ "Acme\\MockLib\\Foo",
+ ]];
+
+ yield ["SolarSystemLib", "Acme\\SolarSystemLib", [
+ "Acme\\SolarSystemLib\\Sun",
+ ]];
+
+ yield ["SolarSystemLib/Planets", "Acme\\SolarSystemLib\\Planets", [
+ "Acme\\SolarSystemLib\\Planets\\Pluton",
+ ]];
+
+ yield [
+ "SolarSystemLib/Planets/Inner",
+ "Acme\\SolarSystemLib\\Planets\\Inner",
+ [
+ "Acme\\SolarSystemLib\\Planets\\Inner\\Mercure",
+ "Acme\\SolarSystemLib\\Planets\\Inner\\Venus",
+ ]
+ ];
+
+ yield ["NotExisting", "AnyPrefix", []];
+ }
+}
diff --git a/tests/data/SolarSystemLib/Planets/Inner/Mercure.php b/tests/data/SolarSystemLib/Planets/Inner/Mercure.php
new file mode 100644
--- /dev/null
+++ b/tests/data/SolarSystemLib/Planets/Inner/Mercure.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace Acme\SolarSystemLib\Planets\Inner;
+
+class Mercure {
+
+}
diff --git a/tests/data/SolarSystemLib/Planets/Inner/Venus.php b/tests/data/SolarSystemLib/Planets/Inner/Venus.php
new file mode 100644
--- /dev/null
+++ b/tests/data/SolarSystemLib/Planets/Inner/Venus.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace Acme\SolarSystemLib\Planets\Inner;
+
+class Venus {
+
+}
diff --git a/tests/data/SolarSystemLib/Planets/Pluton.php b/tests/data/SolarSystemLib/Planets/Pluton.php
new file mode 100644
--- /dev/null
+++ b/tests/data/SolarSystemLib/Planets/Pluton.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace Acme\SolarSystemLib\Planets;
+
+class Pluton {
+
+}
diff --git a/tests/data/SolarSystemLib/Sun.php b/tests/data/SolarSystemLib/Sun.php
new file mode 100644
--- /dev/null
+++ b/tests/data/SolarSystemLib/Sun.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace Acme\SolarSystemLib;
+
+class Sun {
+
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Nov 25, 19:02 (5 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2263019
Default Alt Text
D2507.id6323.diff (6 KB)
Attached To
Mode
D2507: Allow to discover classes in a PSR-4 folder
Attached
Detach File
Event Timeline
Log In to Comment