Skip to content

Commit

Permalink
Merge pull request #233 from c-harris/hookupClassFinder
Browse files Browse the repository at this point in the history
Hookup class finder
  • Loading branch information
CyberiaResurrection committed Mar 5, 2020
2 parents 59d7253 + 937e627 commit 9f24e3d
Show file tree
Hide file tree
Showing 9 changed files with 34 additions and 125 deletions.
11 changes: 6 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,20 @@
"sort-packages": true
},
"require": {
"php": "^7.1",
"algo-web/podata": "0.3.*|dev-master",
"cruxinator/class-finder": "1.0.0-RC2|dev-master",
"doctrine/dbal": "^2.5",
"php": "^7.1",
"laravel/framework": "^5.5|^6.0",
"illuminate/http": "^5.5|^6.0",
"voku/anti-xss": "2.1.*",
"symfony/yaml": "^2.7|^3.0|^4.0",
"symfony/http-foundation": "^2.7|^3.0|^4.0"
"laravel/framework": "^5.5|^6.0",
"symfony/http-foundation": "^2.7|^3.0|^4.0",
"symfony/yaml": "^2.7|^3.0|^4.0"
},
"require-dev": {
"mockery/mockery": "dev-master",
"php-coveralls/php-coveralls": ">=v2.1",
"phpunit/phpunit": "^6.0|^7.0|^8.0",
"ocramius/package-versions": "1.3.*|1.4.*|1.5.*",
"orchestra/database": "3.5.*|3.6.*|3.7.*|3.8.*|^4.0",
"orchestra/testbench": "3.5.*|3.6.*|3.7.*|3.8.*|^4.0",
"infection/infection": "^0.13|dev-master"
Expand Down
31 changes: 0 additions & 31 deletions src/Providers/MetadataBaseProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,37 +42,6 @@ protected function handlePostBoot(bool $isCaching, $hasCache, string $key, $meta
}
}

/**
* @return array
*/
protected function getClassMap()
{
$classes = get_declared_classes();
$autoClass = null;
foreach ($classes as $class) {
if (\Illuminate\Support\Str::startsWith($class, 'Composer\\Autoload\\ComposerStaticInit')) {
$autoClass = $class;
}
}

$classes = $autoClass::$classMap;
$this->checkClassMap($classes);
return array_keys($classes);
}

/**
* @param $classMap
* @throws \Exception
*/
protected function checkClassMap($classMap)
{
$class = __CLASS__;
if (!isset($classMap[$class])) {
throw new \Exception(sprintf('%s was not found in autoload class map, this usually indicates you '.
'need to dump an optimised autoloader (`composer dump-autoload -o`)', $class));
}
}

protected function getAppNamespace()
{
try {
Expand Down
51 changes: 14 additions & 37 deletions src/Providers/MetadataControllerProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use AlgoWeb\PODataLaravel\Controllers\MetadataControllerContainer;
use AlgoWeb\PODataLaravel\Controllers\MetadataControllerTrait;
use Cruxinator\ClassFinder\ClassFinder;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Cache;
Expand Down Expand Up @@ -42,9 +43,7 @@ public function boot()
/** @var MetadataControllerContainer $meta */
$meta = App::make('metadataControllers');

$classes = $this->getClassMap();
$ends = $this->getCandidateControllers($classes);

$ends = $this->getCandidateControllers();
// now process each class that uses the metadata controller trait and stick results in $metamix
$metamix = [];
foreach ($ends as $end) {
Expand Down Expand Up @@ -96,43 +95,21 @@ function () {
}

/**
* @param array $classes
* @return mixed
* @throws \Exception
* @return array
*/
protected function getCandidateControllers(array $classes)
protected function getCandidateControllers()
{
$ends = [];
$startName = $this->getAppNamespace();
$rawClasses = [];
foreach ($classes as $name) {
// not in app namespace, keep moving
if (!\Illuminate\Support\Str::startsWith($name, $startName)) {
continue;
}
// if class doesn't exist (for whatever reason), skip it now rather than muck about later
if (!class_exists($name)) {
continue;
}
$rawClasses[] = $name;
}

foreach ($rawClasses as $name) {
try {
if (in_array(MetadataControllerTrait::class, class_uses($name, false))) {
$result = $this->app->make($name);
if (!$result instanceof Controller) {
throw new InvalidOperationException('Resolved result not a controller');
}
$ends[] = $result;
}
} catch (\Exception $e) {
if (!$this->app->runningInConsole()) {
throw $e;
}
// Squash exceptions thrown here when running from CLI so app can continue booting
}
}
$classes = ClassFinder::getClasses(
$this->getAppNamespace(),
function ($className) {
return in_array(MetadataControllerTrait::class, class_uses($className)) &&
($this->app->make($className) instanceof Controller);
}, true);
$ends = array_reduce($classes, function ($carry, $item) {
$carry[] = $this->app->make($item);
return $carry;
}, []);
return $ends;
}
}
19 changes: 6 additions & 13 deletions src/Providers/MetadataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use AlgoWeb\PODataLaravel\Models\ObjectMap\Entities\EntityFieldType;
use AlgoWeb\PODataLaravel\Models\ObjectMap\Entities\EntityGubbins;
use AlgoWeb\PODataLaravel\Models\ObjectMap\Map;
use Cruxinator\ClassFinder\ClassFinder;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\App;
Expand Down Expand Up @@ -317,19 +318,11 @@ public function register()
*/
protected function getCandidateModels()
{
$classes = $this->getClassMap();
$ends = [];
$startName = $this->getAppNamespace();
foreach ($classes as $name) {
if (Str::startsWith($name, $startName)) {
if (in_array('AlgoWeb\\PODataLaravel\\Models\\MetadataTrait', class_uses($name))) {
if (is_subclass_of($name, '\\Illuminate\\Database\\Eloquent\\Model')) {
$ends[] = $name;
}
}
}
}
return $ends;
return ClassFinder::getClasses($this->getAppNamespace(),
function ($className) {
return in_array(\AlgoWeb\PODataLaravel\Models\MetadataTrait::class, class_uses($className)) &&
is_subclass_of($className, \Illuminate\Database\Eloquent\Model::class);
}, true);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,6 @@ public function testBootNonExistentControllers()
Cache::shouldReceive('forget')->with('metadataControllers')->once();

$foo = m::mock(MetadataControllerProvider::class)->makePartial()->shouldAllowMockingProtectedMethods();
$foo->shouldReceive('getClassMap')->andReturn(['abc', 'def'])->once();
$foo->shouldReceive('getIsCaching')->andReturn(false)->once();

$foo->boot();
Expand Down
5 changes: 0 additions & 5 deletions tests/Orchestra/Providers/DummyMetadataBaseProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,4 @@ public function handlePostBoot(bool $isCaching, $hasCache, string $key, $meta)
{
return parent::handlePostBoot($isCaching, $hasCache, $key, $meta);
}

public function checkClassMap($classMap)
{
parent::checkClassMap($classMap);
}
}
4 changes: 2 additions & 2 deletions tests/Orchestra/Providers/DummyMetadataControllerProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ class DummyMetadataControllerProvider extends MetadataControllerProvider
* @throws \Exception
* @return array
*/
public function getCandidateControllers(array $classes)
public function getCandidateControllers()
{
return parent::getCandidateControllers($classes);
return parent::getCandidateControllers();
}
}
12 changes: 0 additions & 12 deletions tests/Orchestra/Unit/Providers/MetadataBaseProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,4 @@ public function testExplicitZeroCacheDurationMeansOne()

$foo->handlePostBoot(true, null, 'key', null);
}

public function testNotExistInClassMap()
{
$app = m::mock(Application::class);

$foo = new DummyMetadataBaseProvider($app);

$this->expectException(\Exception::class);
$this->expectExceptionMessage('AlgoWeb\PODataLaravel\Providers\MetadataBaseProvider was not found in autoload class map, this usually indicates you need to dump an optimised autoloader (`composer dump-autoload -o`)');

$foo->checkClassMap([]);
}
}
25 changes: 6 additions & 19 deletions tests/Orchestra/Unit/Providers/MetadataControllerProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,14 @@ public function testDontFilterActiveControllers()
public function testFilterControllerWithoutTrait()
{
$names = [OrchestraNonTraitController::class, OrchestraTestController::class];
$expected = [new OrchestraTestController()];
$expected = [new OrchestraBallastController(), new OrchestraTestController()];

$app = m::mock(Application::class);
$app->shouldReceive('runningInConsole')->andReturn(true);
$app->shouldReceive('make')->withArgs([OrchestraTestController::class])
->andReturn(new OrchestraTestController());
$app->shouldReceive('make')->withArgs([OrchestraBallastController::class])
->andReturn(new OrchestraBallastController());
$foo = new DummyMetadataControllerProvider($app);

$actual = $foo->getCandidateControllers($names);
Expand All @@ -60,33 +62,18 @@ public function testFilterControllerWithoutTrait()
public function testFilterFromOutsideNamespace()
{
$names = [Role::class, OrchestraTestController::class];
$expected = [new OrchestraTestController()];
$expected = [new OrchestraBallastController(), new OrchestraTestController()];

$app = m::mock(Application::class);
$app->shouldReceive('runningInConsole')->andReturn(true);
$app->shouldReceive('make')->withArgs([OrchestraTestController::class])
->andReturn(new OrchestraTestController());
$app->shouldReceive('make')->withArgs([OrchestraBallastController::class])
->andReturn(new OrchestraBallastController());

$foo = new DummyMetadataControllerProvider($app);

$actual = $foo->getCandidateControllers($names);
$this->assertEquals($expected, $actual);
}

public function testKaboomOnSwitcheroo()
{
$names = [OrchestraTestController::class];

$app = m::mock(\Illuminate\Foundation\Application::class)->makePartial();
$app->shouldReceive('make')->withArgs([OrchestraTestController::class])
->andReturn(new OrchestraTestModel());
$app->shouldReceive('runningInConsole')->andReturn(false)->once();
$foo = new DummyMetadataControllerProvider($app);

$this->expectException(InvalidOperationException::class);
$this->expectExceptionMessage('Resolved result not a controller');

App::instance('app', $app);
$foo->getCandidateControllers($names);
}
}

0 comments on commit 9f24e3d

Please sign in to comment.