Skip to content

Commit

Permalink
refactor: move DownloadIconifyIconsCommand logic to IconLoader class
Browse files Browse the repository at this point in the history
  • Loading branch information
JeRabix committed Sep 8, 2024
1 parent 45c4213 commit a0d0b72
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 186 deletions.
198 changes: 16 additions & 182 deletions src/Commands/DownloadIconifyIconsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,9 @@

namespace JeRabix\MoonshineIconify\Commands;

use Exception;
use Illuminate\Support\Facades\Http;
use JeRabix\MoonshineIconify\Detectors\DetectorContract;
use RegexIterator;
use PhpParser\NodeFinder;
use PhpParser\ParserFactory;
use PhpParser\NodeTraverser;
use RecursiveIteratorIterator;
use JeRabix\MoonshineIconify\IconLoaders\Iconify\IconifyIconLoader;
use Illuminate\Console\Command;
use RecursiveDirectoryIterator;
use Illuminate\Support\Facades\File;
use PhpParser\NodeVisitor\NameResolver;
use JeRabix\MoonshineIconify\Detectors\MenuItemDetector;
use JeRabix\MoonshineIconify\Detectors\MenuGroupDetector;
use JeRabix\MoonshineIconify\Detectors\UrlComponentDetector;
use JeRabix\MoonshineIconify\Detectors\WithIconTraitDetector;
use JeRabix\MoonshineIconify\Detectors\IconComponentDetector;
use JeRabix\MoonshineIconify\Detectors\IconAttributeDetector;
use SplFileInfo;

class DownloadIconifyIconsCommand extends Command
{
Expand All @@ -40,174 +24,24 @@ class DownloadIconifyIconsCommand extends Command
*/
protected $description = 'Download all uses in project icons';

/** @var string[] */
protected array $analyzeFiles = [];

/**
* @var string[]
*/
protected array $foundIcons = [];

/** @var string[] */
protected array $alreadyDownloadedIcons = [];

/** @var string[] */
protected array $needDownloadIcons = [];

public function handle(): void
{
$isForce = boolval($this->option('force'));

$this->scanSources(config('moonshine-iconify.detect_icons_path', app_path()));

$this->findUsedIcons();

$this->findCurrentDownloadedIcons();

if ($isForce) {
$this->needDownloadIcons = $this->foundIcons;
} else {
$this->needDownloadIcons = array_diff(
$this->foundIcons,
$this->alreadyDownloadedIcons,
);
}

$this->downloadIcons();

if (config('moonshine-iconify.delete_not_used_icons', true)) {
$this->deleteNotUsedIcons();
}
}

protected function scanSources(string $source): void
{
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source));
$files = new RegexIterator($files, '/\.php$/');

foreach ($files as $file) {
$this->analyzeFiles[] = $file->getPathname();
}
$scanPath = config('moonshine-iconify.detect_icons_path', app_path());
$isDeleteNotUsedIcons = config('moonshine-iconify.delete_not_used_icons', true);
/**
* @var class-string<DetectorContract>[] $additionalDetectors
*/
$additionalDetectors = config('moonshine-iconify.additional_detectors', []);

$loader = new IconifyIconLoader(
$scanPath,
$isForce,
$isDeleteNotUsedIcons,
$additionalDetectors,
);

$loader->run();
}

private function findUsedIcons(): void
{
$parser = (new ParserFactory)->createForNewestSupportedVersion();
$nodeFinder = new NodeFinder;
$traverser = new NodeTraverser;

$traverser->addVisitor(new NameResolver);

$icons = [];

foreach ($this->analyzeFiles as $fileWithIcon) {
$fileCode = $parser->parse(file_get_contents($fileWithIcon));

$fileCode = $traverser->traverse($fileCode);

$icons = array_merge(
$icons,
(new MenuGroupDetector($nodeFinder))->detect($fileCode),
(new MenuItemDetector($nodeFinder))->detect($fileCode),
(new WithIconTraitDetector($nodeFinder))->detect($fileCode),
(new UrlComponentDetector($nodeFinder))->detect($fileCode),
(new IconComponentDetector($nodeFinder))->detect($fileCode),
(new IconAttributeDetector($nodeFinder))->detect($fileCode),
);

/**
* @var class-string<DetectorContract>[] $additionalDetectors
*/
$additionalDetectors = config('moonshine-iconify.additional_detectors', []);

foreach ($additionalDetectors as $detector) {
$icons = array_merge(
$icons,
(new $detector($nodeFinder))->detect($fileCode),
);
}
}

$icons = array_unique($icons);

$icons = array_filter($icons, function (string $icon) {
return explode(':', $icon)[1] ?? false;
});

$icons = array_values($icons);

$this->foundIcons = $icons;
}

private function findCurrentDownloadedIcons(): void
{
$source = resource_path('views/vendor/moonshine/ui/icons/iconify');
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source));
$files = new RegexIterator($files, '/\.blade\.php$/');

foreach ($files as $file) {
/** @var SplFileInfo $file */

$iconSet = last(explode('/', $file->getPath()));

if ($iconSet === 'iconify') {
continue;
}

$iconName = explode('.', $file->getFilename())[0] ?? null;

if (!$iconName || !$iconSet) {
continue;
}

$this->alreadyDownloadedIcons[] = $iconSet . ':' . $iconName;
}
}

private function downloadIcons(): void
{
$baseUrl = 'https://api.iconify.design';

foreach ($this->foundIcons as $icon) {
$iconData = explode(':', $icon);

$iconSet = $iconData[0];
$iconName = $iconData[1];

$apiUrl = $baseUrl . '/' . $iconSet . '/' . $iconName . '.svg';

$path = resource_path("views/vendor/moonshine/ui/icons/iconify/$iconSet");

if (!File::isDirectory($path)) {
File::makeDirectory($path, recursive: true);
}

$iconContent = Http::get($apiUrl)->body();

if ($iconContent === '404') {
throw new Exception("Cannot download icon: $icon. By API url: $apiUrl");
}

file_put_contents("$path/$iconName.blade.php", $iconContent);
}
}

private function deleteNotUsedIcons(): void
{
$notUsedIcons = array_diff($this->alreadyDownloadedIcons, $this->foundIcons);

$notUsedIconsPaths = array_map(function (string $icon) {
$iconData = explode(':', $icon);
$iconSet = $iconData[0];
$iconName = $iconData[1];

return resource_path("views/vendor/moonshine/ui/icons/iconify/$iconSet/$iconName.blade.php");
}, $notUsedIcons);

foreach ($notUsedIconsPaths as $path) {
if (File::exists($path)) {
File::delete($path);
}
}
}
}
2 changes: 1 addition & 1 deletion src/Detectors/BaseStaticMakeMethodDetector.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function __construct(
}
}

public function detect(array $stmt): array
public function findIcons(array $stmt): array
{
// static call ::make
$this->nodeFinder->find($stmt, function ($node) {
Expand Down
2 changes: 1 addition & 1 deletion src/Detectors/DetectorContract.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ interface DetectorContract
*
* @return string[]
*/
public function detect(array $stmt): array;
public function findIcons(array $stmt): array;
}
2 changes: 1 addition & 1 deletion src/Detectors/IconAttributeDetector.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class IconAttributeDetector extends AbstractDetector
/**
* @inheritdoc
*/
public function detect(array $stmt): array
public function findIcons(array $stmt): array
{
// ->icon() method
$this->nodeFinder->find($stmt, function ($node) {
Expand Down
2 changes: 1 addition & 1 deletion src/Detectors/WithIconTraitDetector.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class WithIconTraitDetector extends AbstractDetector
/**
* @inheritdoc
*/
public function detect(array $stmt): array
public function findIcons(array $stmt): array
{
// ->icon() method
$this->nodeFinder->find($stmt, function ($node) {
Expand Down
Loading

0 comments on commit a0d0b72

Please sign in to comment.