Skip to content

Instantly share code, notes, and snippets.

@jszobody
Last active July 14, 2017 16:50
Show Gist options
  • Save jszobody/b4eebc582b1840021e20794b672144b9 to your computer and use it in GitHub Desktop.
Save jszobody/b4eebc582b1840021e20794b672144b9 to your computer and use it in GitHub Desktop.
Short class names with preferred namespaces
<?php
namespace App\Console;
use Illuminate\Support\Collection;
/**
* Taken from https://github.com/spatie/laravel-tinker-tools. Made to work with PHP 5.6, and have preferred namespaces.
*/
class ShortClassNames
{
/** @var \Illuminate\Support\Collection */
public $classes;
/** @var \Illuminate\Support\Collection */
public $preferredNamespaces;
/**
* @param null $classMapPath
*
* @return mixed
*/
public static function register($classMapPath = null)
{
$classMapPath = $classMapPath ? $classMapPath : base_path('vendor/composer/autoload_classmap.php');
return (new static($classMapPath))->registerAutoloader();
}
/**
* ShortClassNames constructor.
*
* @param $classMapPath
*/
public function __construct($classMapPath)
{
$classFiles = include $classMapPath;
$this->preferredNamespaces = collect();
$this->classes = collect($classFiles)
->map(function ($path, $fqcn) {
$name = last(explode('\\', $fqcn));
return compact('fqcn', 'name');
})
->filter()
->values();
Collection::macro('preferredNamespaces', function($namespaces) {
return $this
->filter(function ($match) use($namespaces) {
return $namespaces->contains(function($namespace) use ($match) {
return starts_with($match['fqcn'], $namespace);
});
})
->sortBy(function($match) use($namespaces) {
return $namespaces->filter(function($namespace) use ($match) {
return starts_with($match['fqcn'], $namespace);
})->keys()->first();
});
});
}
/**
* @return $this
*/
public function registerAutoloader()
{
spl_autoload_register([$this, 'aliasClass']);
return $this;
}
/**
* @param array $namespaces
*
* @return $this
*/
public function preferNamespaces($namespaces = [])
{
$this->preferredNamespaces = collect($namespaces);
return $this;
}
/**
* @param $findClass
*/
public function aliasClass($findClass)
{
if($class = $this->findClass($findClass)) {
class_alias($class['fqcn'], $class['name']);
}
}
/**
* @param $findClass
*
* @return mixed
*/
public function findClass($findClass)
{
return $this->classes
->whereStrict('name', $findClass)
->pipe(function($matches) {
if($matches->count() > 1 && $matches->preferredNamespaces($this->preferredNamespaces)->count()) {
$matches = $matches->preferredNamespaces($this->preferredNamespaces);
}
return $matches;
})
->first();
}
}
@jszobody
Copy link
Author

jszobody commented Jul 14, 2017

Then in my .psysh.php file I have:

App\Console\ShortClassNames::register()->preferNamespaces([
    'App', 'Illuminate\\Support', 'Illuminate'
]);

That will ensure my own App is preferred first. I then prioritize Illuminate\Support to ensure I get Illuminate\Support\Collection instead of Illuminate\Database\Eloquent\Collection, and a few other cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment