Skip to content

Commit

Permalink
refactor: model class to support directories outside app
Browse files Browse the repository at this point in the history
  • Loading branch information
bensherred committed Nov 27, 2023
1 parent f29a31d commit 261aeb6
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 5 deletions.
40 changes: 35 additions & 5 deletions src/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use Illuminate\Database\Eloquent\Model as EloquentModel;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Foundation\Application;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
Expand Down Expand Up @@ -46,7 +48,7 @@ public static function findOrFail(string $sqid): EloquentModel
}

/** @phpstan-ignore-next-line */
return $model::query()->findOrFailBySqid(sqid: $sqid);
return $model::query()->findBySqidOrFail(sqid: $sqid);
}

/**
Expand Down Expand Up @@ -81,15 +83,29 @@ protected static function models(): array
return $models;
}

protected static function namespaces(): array
{
$composer = File::json(path: base_path(path: 'composer.json'));

/** @var array $namespaces */
$namespaces = Arr::get(array: $composer, key: 'autoload.psr-4', default: []);

return array_flip($namespaces);
}

protected static function fullQualifiedClassNameFromFile(SplFileInfo $file): string
{
/** @var Application $application */
$application = app();

return Str::of($file->getRealPath())
->replaceFirst(search: base_path(), replace: '')
return Str::of(string: $file->getRealPath())
->replaceFirst(search: static::basePath(), replace: '')
->replaceLast(search: '.php', replace: '')
->trim(characters: DIRECTORY_SEPARATOR)
->replace(
search: array_keys(static::namespaces()),
replace: array_values(static::namespaces())
)
->ucfirst()
->replace(
search: [DIRECTORY_SEPARATOR, 'App\\'],
Expand All @@ -106,12 +122,12 @@ protected static function getFilesRecursively(): array
$files = [];

$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(
directory: app_path(),
directory: static::basePath(),
));

/** @var SplFileInfo $file */
foreach ($iterator as $file) {
if ($file->isDir()) {
if ($file->isDir() || str_contains(haystack: $file->getRealPath(), needle: 'vendor')) {
continue;
}

Expand All @@ -120,4 +136,18 @@ protected static function getFilesRecursively(): array

return $files;
}

protected static function basePath(): string
{
/** @var Application $application */
$application = app();

if ($application->runningUnitTests()) {
$basePath = new SplFileInfo(base_path(path: '../../../../'));

return $basePath->getRealPath();
}

return base_path();
}
}
41 changes: 41 additions & 0 deletions tests/ModelTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

use Illuminate\Database\Eloquent\ModelNotFoundException;
use RedExplosion\Sqids\Model;
use Workbench\App\Models\Charge;
use Workbench\App\Models\Customer;
use Workbench\Database\Factories\ChargeFactory;
use Workbench\Database\Factories\CustomerFactory;

it('can find a model from the sqid', function (): void {
$john = CustomerFactory::new()->create(['name' => 'John']);
$jane = CustomerFactory::new()->create(['name' => 'Jane']);

$charge = ChargeFactory::new()->create(['amount' => 2000]);

expect(Model::find(sqid: 'invalid-sqid'))
->toBeNull()
->and(Model::find(sqid: $jane->sqid))
->toBeInstanceOf(Customer::class)
->name->toBe('Jane')
->and(Model::find(sqid: $charge->sqid))
->toBeInstanceOf(Charge::class)
->amount->toBe(2000)
->and(Model::find(sqid: $john->sqid))
->toBeInstanceOf(Customer::class)
->name->toBe('John');
});

it('can find a model from the sqid or throw an exception', function (): void {
$customer = CustomerFactory::new()->create();

expect(Model::findOrFail(sqid: $customer->sqid))
->toBeInstanceOf(Customer::class)
->name->toBe($customer->name);

$this->expectException(ModelNotFoundException::class);

Model::findOrFail(sqid: 'invalid-sqid');
});

0 comments on commit 261aeb6

Please sign in to comment.