Skip to content

Instantly share code, notes, and snippets.

@tobiashm
Last active January 8, 2019 13:01
Show Gist options
  • Save tobiashm/879b3264b4d5a4f677f68b97c9d976a4 to your computer and use it in GitHub Desktop.
Save tobiashm/879b3264b4d5a4f677f68b97c9d976a4 to your computer and use it in GitHub Desktop.
Load commands from all PSR-4 Autoload namespaces
<?php
namespace App\Console;
use Illuminate\Console\Application as Artisan;
use Illuminate\Console\Command;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use ReflectionClass;
use Symfony\Component\Finder\Finder;
class Kernel extends ConsoleKernel
{
public function commands()
{
$this->autoload([
base_path('project/Commands')
]);
}
/**
* @throws \ReflectionException
*/
private function autoload($paths)
{
$paths = array_unique(is_array($paths) ? $paths : [$paths]);
$paths = array_filter($paths, 'is_dir');
if (empty($paths)) {
return;
}
$autoloadNamespaces = $this->getAutoloadNamespaces();
foreach ((new Finder())->in($paths)->files() as $file) {
$path = $file->getRealPath();
foreach ($autoloadNamespaces as $basePath => $namespace) {
if (substr($path, 0, strlen($basePath)) !== $basePath) {
continue;
}
$class = $namespace . str_replace(['/', '.php'], ['\\', ''], substr($path, strlen($basePath)));
if (is_subclass_of($class, Command::class) && !(new ReflectionClass($class))->isAbstract()) {
Artisan::starting(function ($artisan) use ($class) {
$artisan->resolve($class);
});
}
}
}
}
private function getAutoloadNamespaces(): array
{
$result = [app_path() . DIRECTORY_SEPARATOR => app()->getNamespace()];
$composer = json_decode(file_get_contents(base_path('composer.json')), true);
foreach ((array) data_get($composer, 'autoload.psr-4') as $namespace => $path) {
$path = realpath(base_path($path)) ?: realpath($path);
if ($path) {
$result[$path . DIRECTORY_SEPARATOR] = $namespace;
}
}
return $result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment