Skip to content

Instantly share code, notes, and snippets.

@jdltechworks
Created May 9, 2022 22:38
Show Gist options
  • Save jdltechworks/1e18b2d125b8adcb2d3efe628fff77d2 to your computer and use it in GitHub Desktop.
Save jdltechworks/1e18b2d125b8adcb2d3efe628fff77d2 to your computer and use it in GitHub Desktop.
Package based livewire using Routes instead of using Livewire::component
<?php
return [
'vendor_dir' => './vendor/marketdragon/'
];
<?php
namespace MarketDragon\LivewireExtra;
use Exception;
use ReflectionClass;
use Illuminate\Filesystem\Filesystem;
use Symfony\Component\Finder\SplFileInfo;
use Livewire\Component;
class LivewireComponentsFinder
{
protected $paths;
protected $files;
protected $manifest;
protected $manifestPath;
public function __construct(Filesystem $files, $manifestPath, $paths)
{
$this->files = $files;
$this->paths = $paths;
$this->manifestPath = $manifestPath;
}
public function find($alias)
{
$manifest = $this->getManifest();
return $manifest[$alias] ?? $manifest["{$alias}.index"] ?? null;
}
public function getManifest()
{
if (! is_null($this->manifest)) {
return $this->manifest;
}
if (! file_exists($this->manifestPath)) {
$this->build();
}
return $this->manifest = $this->files->getRequire($this->manifestPath);
}
public function build()
{
$this->manifest = $this->getClassNames()
->mapWithKeys(function ($class) {
return [$class::getName() => $class];
})->toArray();
$this->write($this->manifest);
return $this;
}
protected function write(array $manifest)
{
if (! is_writable(dirname($this->manifestPath))) {
throw new Exception('The '.dirname($this->manifestPath).' directory must be present and writable.');
}
$this->files->put($this->manifestPath, '<?php return '.var_export($manifest, true).';', true);
}
public function getClassNames()
{
$files = [];
foreach($this->paths as $path)
{
if (is_dir($path)) {
foreach($this->files->allFiles($path) as $file) {
$files[] = $file;
}
}
}
return collect($files)
->map(function (SplFileInfo $file) {
if (preg_match('/app/', $file->getPath())) {
return app()->getNamespace() . str($file->getPathname())
->after(app_path().'/')
->replace(['/', '.php'], ['\\', ''])
->__toString();
}
$filename = str_replace('.php', '', $file->getFilename());
return str_replace(' ', '', config('app.name')) . '\\' . $filename . str($file->getPathname())
->replace([
config('livewire-extra.vendor_dir') . strtolower($filename) . '/src'
,'/',
'.php'
], ['', '\\', ''])
->__toString();
})->filter(function (string $class) {
return is_subclass_of($class, Component::class) &&
! (new ReflectionClass($class))->isAbstract();
});
}
}
<?php
namespace MarketDragon\LivewireExtra;
use Illuminate\Support\ServiceProvider;
use Livewire\Commands\ComponentParser;
use Illuminate\Filesystem\Filesystem;
use MarketDragon\LivewireExtra\Commands\DiscoverLivewire;
class LivewireExtraServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
if ($this->app->runningInConsole()) {
$this->commands([
DiscoverLivewire::class
]);
}
$this->mergeConfigFrom(
__DIR__ . '/../config/livewire-extra.php', 'livewire-extra'
);
$this->registerComponentAutoDiscovery();
}
protected function registerComponentAutoDiscovery()
{
// Rather than forcing users to register each individual component,
// we will auto-detect the component's class based on its kebab-cased
// alias. For instance: 'examples.foo' => App\Http\Livewire\Examples\Foo
// We will generate a manifest file so we don't have to do the lookup every time.
$defaultManifestPath = $this->app['livewire']->isRunningServerless()
? '/tmp/storage/bootstrap/cache/livewire-components.php'
: app()->bootstrapPath('cache/livewire-components.php');
$this->app->singleton(LivewireComponentsFinder::class, function () use ($defaultManifestPath) {
$namespaces = config('md-admin.namespaces');
$packages = (new Filesystem)
->directories(config('livewire-extra.vendor_dir'));
$livewireDefault = ComponentParser::generatePathFromNameSpace(config('livewire.class_namespace'));
$livewirePackages = array_map(function($package) {
return $package . '/src/' . 'Http/Livewire/';
}, $packages);
$components = array_merge([$livewireDefault], $livewirePackages);
return new LivewireComponentsFinder(
new Filesystem,
config('livewire.manifest_path') ?: $defaultManifestPath,
$components
);
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment