-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f67e5f0
commit 59265c7
Showing
8 changed files
with
252 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Salehhashemi\Repository\Commands; | ||
|
||
use Illuminate\Console\Command; | ||
use Illuminate\Filesystem\Filesystem; | ||
use Illuminate\Support\Str; | ||
use RuntimeException; | ||
|
||
class MakeRepository extends Command | ||
{ | ||
protected $signature = 'make:repository {name : The name of the model}'; | ||
|
||
protected $description = 'Creates a new repository, interface, and filter for the specified model'; | ||
|
||
public function handle(Filesystem $filesystem): void | ||
{ | ||
$name = Str::studly($this->argument('name')); | ||
$modelName = class_basename($name); | ||
$modelNamespace = 'App\\Models'; // Assuming models are under the 'App\Models' namespace | ||
|
||
// Derive paths and namespaces from configuration | ||
$repositoryPath = config('repository.path', app_path('Repositories')); | ||
$repositoryNamespace = $this->pathToNamespace($repositoryPath); | ||
|
||
// Check and create the necessary directories | ||
$this->ensureDirectoryExists($repositoryPath, $filesystem); | ||
|
||
// Paths for generated files | ||
$repositoryFilePath = "{$repositoryPath}/{$modelName}Repository.php"; | ||
$interfaceFilePath = "{$repositoryPath}/Contracts/{$modelName}RepositoryInterface.php"; | ||
$filterFilePath = "{$repositoryPath}/Filters/{$modelName}Filter.php"; | ||
|
||
// Generate repository, interface, and filter | ||
$this->createFileFromStub('repository.stub', $repositoryFilePath, [ | ||
'{{namespace}}' => $repositoryNamespace, | ||
'{{modelName}}' => $modelName, | ||
'{{modelNamespace}}' => $modelNamespace, | ||
'{{name}}' => "{$modelName}", | ||
], $filesystem); | ||
|
||
$this->createFileFromStub('repository-interface.stub', $interfaceFilePath, [ | ||
'{{namespace}}' => "{$repositoryNamespace}\\Contracts", | ||
'{{modelName}}' => $modelName, | ||
'{{modelNamespace}}' => $modelNamespace, | ||
'{{name}}' => "{$modelName}", | ||
], $filesystem); | ||
|
||
$this->createFileFromStub('filter.stub', $filterFilePath, [ | ||
'{{namespace}}' => "{$repositoryNamespace}\\Filters", | ||
'{{modelName}}' => $modelName, | ||
'{{modelNamespace}}' => $modelNamespace, | ||
'{{name}}' => "{$modelName}", | ||
], $filesystem); | ||
|
||
$this->info("Repository, interface, and filter for {$modelName} created successfully."); | ||
} | ||
|
||
protected function createFileFromStub( | ||
string $stubName, | ||
string $filePath, | ||
array $replacements, | ||
Filesystem $filesystem | ||
): void { | ||
$stubPath = __DIR__."/stubs/{$stubName}"; | ||
$content = $filesystem->get($stubPath); | ||
$content = str_replace(array_keys($replacements), array_values($replacements), $content); | ||
|
||
if (! $filesystem->put($filePath, $content)) { | ||
throw new RuntimeException("Failed to create file at {$filePath}"); | ||
} | ||
|
||
$this->info("Created: {$filePath}"); | ||
} | ||
|
||
protected function ensureDirectoryExists(string $path, Filesystem $filesystem): void | ||
{ | ||
if (! $filesystem->isDirectory($path)) { | ||
$filesystem->makeDirectory($path, 0755, true); | ||
} | ||
} | ||
|
||
protected function pathToNamespace(string $path): string | ||
{ | ||
// Convert file path to namespace | ||
$namespace = str_replace([app_path(), '/', '\\'], ['', '\\', '\\'], $path); | ||
|
||
return 'App'.($namespace ? "\\{$namespace}" : ''); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace {{namespace}}\Filters; | ||
|
||
use Salehhashemi\Repository\BaseFilter; | ||
use Illuminate\Database\Eloquent\Builder; | ||
use {{modelNamespace}}\{{modelName}}; | ||
|
||
class {{name}}Filter extends BaseFilter | ||
{ | ||
/** | ||
* Apply filters to the query builder based on a set of parameters. | ||
*/ | ||
public function applyFilters(array $filters): Builder | ||
{ | ||
$this | ||
->whereLike('title', $queryParams['title'] ?? '', self::WILD_BOTH) | ||
->whereValue('status', $queryParams['status'] ?? '') | ||
->compare('created_at', '>=', $queryParams['created_from'] ?? '') | ||
->compare('created_at', '<=', $queryParams['created_to'] ?? ''); | ||
|
||
if (! empty($queryParams['category_id'])) { | ||
$this->getQuery()->whereHas('categories', function ($query) use ($queryParams) { | ||
$query->where('categories.id', $queryParams['category_id']); | ||
}); | ||
} | ||
|
||
return $this->getQuery(); | ||
} | ||
|
||
/** | ||
* The Eloquent model class that this filter applies to. | ||
*/ | ||
protected function getModelClass(): string | ||
{ | ||
return {{modelName}}::class; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace {{namespace}}\Contracts; | ||
|
||
use Illuminate\Contracts\Pagination\Paginator; | ||
use Illuminate\Database\Eloquent\Collection as EloquentCollection; | ||
use Salehhashemi\Repository\Contracts\RepositoryInterface; | ||
use Salehhashemi\Repository\Contracts\SearchableRepositoryInterface; | ||
|
||
/** | ||
* @method \{{modelNamespace}}\{{modelName}}|null findOne(int|string $primaryKey = null) | ||
* @method \{{modelNamespace}}\{{modelName}} findOneOrFail(int|string $primaryKey = null) | ||
*/ | ||
interface {{name}}RepositoryInterface extends RepositoryInterface, SearchableRepositoryInterface | ||
{ | ||
// ... | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace {{namespace}}; | ||
|
||
use {{namespace}}\Contracts\{{name}}RepositoryInterface; | ||
use Salehhashemi\Repository\Eloquent\BaseRepository; | ||
use {{modelNamespace}}\{{modelName}}; | ||
use {{namespace}}\Filters\{{name}}Filter; | ||
use Illuminate\Database\Eloquent\Builder; | ||
|
||
class {{name}}Repository extends BaseRepository implements {{name}}RepositoryInterface | ||
{ | ||
/** | ||
* Get the filter manager for this repository. | ||
*/ | ||
protected function getFilterManager(): {{name}}Filter | ||
{ | ||
$filterManager = new {{name}}Filter(); | ||
$filterManager->setQuery($this->getQuery()); | ||
|
||
return $filterManager; | ||
} | ||
|
||
/** | ||
* Specify Model class name | ||
*/ | ||
public function model(): string | ||
{ | ||
return {{modelName}}::class; | ||
} | ||
|
||
// Add other method implementations as needed | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<?php | ||
|
||
namespace Salehhashemi\Repository\Tests; | ||
|
||
use Illuminate\Support\Facades\File; | ||
|
||
class MakeRepositoryCommandTest extends BaseTest | ||
{ | ||
protected string $model = 'TestModel'; | ||
|
||
protected string $basePath; | ||
|
||
protected function setUp(): void | ||
{ | ||
parent::setUp(); | ||
|
||
$this->basePath = config('repository.path', app_path('Repositories')); | ||
|
||
// Ensure the target directory exists | ||
if (! File::isDirectory($this->basePath)) { | ||
File::makeDirectory($this->basePath, 0755, true); | ||
} | ||
} | ||
|
||
protected function tearDown(): void | ||
{ | ||
// Cleanup: Remove the directories and files created during the test | ||
File::deleteDirectory($this->basePath); | ||
|
||
parent::tearDown(); | ||
} | ||
|
||
public function testRepositoryStubGeneration(): void | ||
{ | ||
$this->artisan('make:repository', ['name' => $this->model]); | ||
|
||
$expectedFiles = [ | ||
"{$this->basePath}/{$this->model}Repository.php", | ||
"{$this->basePath}/Contracts/{$this->model}RepositoryInterface.php", | ||
"{$this->basePath}/Filters/{$this->model}Filter.php", | ||
]; | ||
|
||
foreach ($expectedFiles as $file) { | ||
$this->assertTrue(File::exists($file), "$file does not exist."); | ||
} | ||
} | ||
} |