-
-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
147136e
commit 4772933
Showing
2 changed files
with
255 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
<?php | ||
|
||
namespace Apiato\Core\Utilities; | ||
|
||
use Illuminate\Support\Facades\File; | ||
|
||
final readonly class PathHelper | ||
{ | ||
private const CONTAINERS_DIRECTORY_NAME = 'Containers'; | ||
|
||
public static function getShipDirectory(): string | ||
{ | ||
return app_path('Ship'); | ||
} | ||
|
||
public static function getShipFolderNames(): array | ||
{ | ||
$names = []; | ||
|
||
foreach (self::getShipSubDirectories() as $directory) { | ||
$names[] = basename($directory); | ||
} | ||
|
||
return $names; | ||
} | ||
|
||
public static function getShipSubDirectories(): array | ||
{ | ||
return File::directories(self::getShipDirectory()); | ||
} | ||
|
||
public static function getSectionContainerNames(string $sectionName): array | ||
{ | ||
$names = []; | ||
foreach (File::directories(self::getSectionPath($sectionName)) as $name) { | ||
$names[] = basename($name); | ||
} | ||
|
||
return $names; | ||
} | ||
|
||
private static function getSectionPath(string $sectionName): string | ||
{ | ||
return app_path(self::CONTAINERS_DIRECTORY_NAME . DIRECTORY_SEPARATOR . $sectionName); | ||
} | ||
|
||
/** | ||
* Get the full name (name \ namespace) of a class from its file path | ||
* result example: (string) "I\Am\The\Namespace\Of\This\Class". | ||
*/ | ||
public static function getFQCNFromFile(string $filePathName): string | ||
{ | ||
return self::getClassNamespaceFromFile($filePathName) . '\\' . self::getClassNameFromFile($filePathName); | ||
} | ||
|
||
protected static function getClassNamespaceFromFile(string $filePathName): string|null | ||
{ | ||
$src = file_get_contents($filePathName); | ||
|
||
$tokens = token_get_all($src); | ||
$count = count($tokens); | ||
$i = 0; | ||
$namespace = ''; | ||
$isValidNameSpace = false; | ||
while ($i < $count) { | ||
$token = $tokens[$i]; | ||
if (is_array($token) && T_NAMESPACE === $token[0]) { | ||
// Found namespace declaration | ||
while (++$i < $count) { | ||
if (';' === $tokens[$i]) { | ||
$isValidNameSpace = true; | ||
$namespace = trim($namespace); | ||
|
||
break; | ||
} | ||
$namespace .= is_array($tokens[$i]) ? $tokens[$i][1] : $tokens[$i]; | ||
} | ||
|
||
break; | ||
} | ||
++$i; | ||
} | ||
if (!$isValidNameSpace) { | ||
return null; | ||
} | ||
|
||
return $namespace; | ||
} | ||
|
||
protected static function getClassNameFromFile(string $filePathName): mixed | ||
{ | ||
$phpCode = file_get_contents($filePathName); | ||
|
||
$classes = []; | ||
$tokens = token_get_all($phpCode); | ||
$count = count($tokens); | ||
for ($i = 2; $i < $count; ++$i) { | ||
if (T_CLASS == $tokens[$i - 2][0] | ||
&& T_WHITESPACE == $tokens[$i - 1][0] | ||
&& T_STRING == $tokens[$i][0] | ||
) { | ||
$className = $tokens[$i][1]; | ||
$classes[] = $className; | ||
} | ||
} | ||
|
||
return $classes[0]; | ||
} | ||
|
||
/** | ||
* Get the last part of a camel case string. | ||
* Example input = helloDearWorld | returns = World. | ||
*/ | ||
public static function getClassType(string $className): mixed | ||
{ | ||
$array = preg_split('/(?=[A-Z])/', $className); | ||
|
||
return end($array); | ||
} | ||
|
||
public static function getContainerNames(): array | ||
{ | ||
$names = []; | ||
|
||
foreach (self::getContainerPaths() as $path) { | ||
$names[] = basename($path); | ||
} | ||
|
||
return $names; | ||
} | ||
|
||
public static function getContainerPaths(): array | ||
{ | ||
$sectionNames = self::getSectionNames(); | ||
$containerPaths = []; | ||
foreach ($sectionNames as $name) { | ||
$sectionContainerPaths = self::getSectionContainersPaths($name); | ||
foreach ($sectionContainerPaths as $containerPath) { | ||
$containerPaths[] = $containerPath; | ||
} | ||
} | ||
|
||
return $containerPaths; | ||
} | ||
|
||
public static function getSectionNames(): array | ||
{ | ||
$names = []; | ||
|
||
foreach (self::getSectionPaths() as $path) { | ||
$names[] = basename($path); | ||
} | ||
|
||
return $names; | ||
} | ||
|
||
public static function getSectionPaths(): array | ||
{ | ||
return File::directories(app_path(self::CONTAINERS_DIRECTORY_NAME)); | ||
} | ||
|
||
public static function getSectionContainersPaths(string $sectionName): array | ||
{ | ||
return File::directories(app_path(self::CONTAINERS_DIRECTORY_NAME . DIRECTORY_SEPARATOR . $sectionName)); | ||
} | ||
|
||
/** | ||
* @param string $subDirectory The subdirectory to append to the container path. Without leading slash. | ||
* | ||
* @return string[] Array of container directories paths. | ||
*/ | ||
public static function getContainersSubDirectories(string $subDirectory): array | ||
{ | ||
return array_map(static fn (string $path) => $path . DIRECTORY_SEPARATOR . $subDirectory, self::getContainerPaths()); | ||
} | ||
|
||
/** | ||
* @param string $subDirectory The subdirectory to append to the ship path. Without leading slash. | ||
*/ | ||
public static function getShipSubDirectory(string $subDirectory): string | ||
{ | ||
return self::getShipDirectory() . DIRECTORY_SEPARATOR . $subDirectory; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
<?php | ||
|
||
namespace Apiato\Core\Tests\Unit\Utilities; | ||
|
||
use Apiato\Core\Tests\Infrastructure\Dummies\UselessClass; | ||
use Apiato\Core\Tests\UnitTestCase; | ||
use Apiato\Core\Utilities\PathHelper; | ||
use Illuminate\Support\Facades\File; | ||
use PHPUnit\Framework\Attributes\CoversClass; | ||
|
||
#[CoversClass(PathHelper::class)] | ||
class PathHelperTest extends UnitTestCase | ||
{ | ||
public function testGetShipFoldersNamesReturnsCorrectNames(): void | ||
{ | ||
File::shouldReceive('directories') | ||
->with(PathHelper::getShipDirectory()) | ||
->andReturn(['/path/to/ship1', '/path/to/ship2']); | ||
|
||
$result = PathHelper::getShipFolderNames(); | ||
|
||
$this->assertEquals(['ship1', 'ship2'], $result); | ||
} | ||
|
||
public function testGetSectionContainerNamesReturnsCorrectNames(): void | ||
{ | ||
File::shouldReceive('directories') | ||
->with(app_path('Containers' . DIRECTORY_SEPARATOR . 'Section1')) | ||
->andReturn(['/path/to/container1', '/path/to/container2']); | ||
|
||
$result = PathHelper::getSectionContainerNames('Section1'); | ||
|
||
$this->assertEquals(['container1', 'container2'], $result); | ||
} | ||
|
||
public function testGetClassFullNameFromFileReturnsCorrectFullName(): void | ||
{ | ||
$filePath = realpath(__DIR__ . '/../../Infrastructure/Dummies/UselessClass.php'); | ||
File::shouldReceive('get') | ||
->with($filePath) | ||
->andReturn(); | ||
|
||
$result = PathHelper::getFQCNFromFile($filePath); | ||
|
||
$this->assertEquals(UselessClass::class, $result); | ||
} | ||
|
||
public function testGetClassTypeReturnsCorrectType(): void | ||
{ | ||
$result = PathHelper::getClassType('HelloDearWorld'); | ||
|
||
$this->assertEquals('World', $result); | ||
} | ||
|
||
public function testGetAllContainerNamesReturnsCorrectNames(): void | ||
{ | ||
File::shouldReceive('directories') | ||
->with(app_path('Containers')) | ||
->andReturn(['/path/to/Section1', '/path/to/Section2']); | ||
File::shouldReceive('directories') | ||
->with(app_path('Containers' . DIRECTORY_SEPARATOR . 'Section1')) | ||
->andReturn(['/path/to/Section1/Container1', '/path/to/Section1/Container2']); | ||
File::shouldReceive('directories') | ||
->with(app_path('Containers' . DIRECTORY_SEPARATOR . 'Section2')) | ||
->andReturn(['/path/to/Section2/Container1', '/path/to/Section2/Container2']); | ||
|
||
$result = PathHelper::getContainerNames(); | ||
|
||
$this->assertEquals(['Container1', 'Container2', 'Container1', 'Container2'], $result); | ||
} | ||
} |