Skip to content

Commit

Permalink
feat: add support to replace model in resource stub (#272)
Browse files Browse the repository at this point in the history
  • Loading branch information
RobChatloop authored Mar 3, 2024
1 parent 567263e commit be16a21
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 23 deletions.
58 changes: 58 additions & 0 deletions src/Console/Concerns/ReplacesModel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php
/*
* Copyright 2024 Cloud Creativity Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

declare(strict_types=1);

namespace LaravelJsonApi\Laravel\Console\Concerns;

use Illuminate\Support\Str;
use function array_keys;
use function array_values;
use function str_replace;

trait ReplacesModel
{

/**
* @param string $stub
* @param string $model
* @return string
*/
protected function replaceModel(string $stub, string $model): string
{
$model = str_replace('/', '\\', $model);

if (Str::startsWith($model, '\\')) {
$namespacedModel = trim($model, '\\');
} else {
$namespacedModel = $this->qualifyModel($model);
}

$model = class_basename($model);

$replace = [
'{{ namespacedModel }}' => $namespacedModel,
'{{namespacedModel}}' => $namespacedModel,
'{{ model }}' => $model,
'{{model}}' => $model,
];

return str_replace(
array_keys($replace), array_values($replace), $stub
);
}
}
16 changes: 15 additions & 1 deletion src/Console/MakeResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@

namespace LaravelJsonApi\Laravel\Console;

use LaravelJsonApi\Laravel\Console\Concerns\ReplacesModel;
use Symfony\Component\Console\Input\InputOption;

class MakeResource extends GeneratorCommand
{
use ReplacesModel;

/**
* @var string
Expand Down Expand Up @@ -52,15 +54,27 @@ protected function getStub()
return $this->resolveStubPath('resource.stub');
}

/**
* @inheritDoc
*/
protected function buildClass($name)
{
$stub = parent::buildClass($name);

$model = $this->option('model') ?: $this->guessModel();

return $this->replaceModel($stub, $model);
}

/**
* @inheritDoc
*/
protected function getOptions()
{
return [
['force', null, InputOption::VALUE_NONE, 'Create the class even if the resource already exists'],
['model', 'm', InputOption::VALUE_REQUIRED, 'The model that the resource applies to.'],
['server', 's', InputOption::VALUE_REQUIRED, 'The JSON:API server the resource exists in.'],
];
}

}
23 changes: 5 additions & 18 deletions src/Console/MakeSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@

namespace LaravelJsonApi\Laravel\Console;

use Illuminate\Support\Str;
use LaravelJsonApi\Laravel\Console\Concerns\ReplacesModel;
use Symfony\Component\Console\Input\InputOption;
use function array_keys;
use function array_values;
use function str_replace;

class MakeSchema extends GeneratorCommand
{
use ReplacesModel;

/**
* @var string
Expand All @@ -47,7 +48,7 @@ class MakeSchema extends GeneratorCommand
* @var string
*/
protected $classType = 'Schema';

/**
* @inheritDoc
*/
Expand All @@ -65,7 +66,7 @@ protected function getStub()
*/
protected function buildClass($name)
{
$stub = parent::buildClass($name);
$stub = $this->replaceSchema(parent::buildClass($name));

$model = $this->option('model') ?: $this->guessModel();

Expand All @@ -77,24 +78,11 @@ protected function buildClass($name)
* @param string $model
* @return string
*/
protected function replaceModel(string $stub, string $model): string
protected function replaceSchema(string $stub): string
{
$model = str_replace('/', '\\', $model);

if (Str::startsWith($model, '\\')) {
$namespacedModel = trim($model, '\\');
} else {
$namespacedModel = $this->qualifyModel($model);
}

$model = class_basename($model);
$schema = $this->option('proxy') ? 'ProxySchema' : 'Schema';

$replace = [
'{{ namespacedModel }}' => $namespacedModel,
'{{namespacedModel}}' => $namespacedModel,
'{{ model }}' => $model,
'{{model}}' => $model,
'{{ schema }}' => $schema,
'{{schema}}' => $schema,
];
Expand All @@ -117,5 +105,4 @@ protected function getOptions()
['server', 's', InputOption::VALUE_REQUIRED, 'The JSON:API server the schema exists in.'],
];
}

}
8 changes: 6 additions & 2 deletions stubs/resource.stub
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@

namespace {{ namespace }};

use {{ namespacedModel }};
use Illuminate\Http\Request;
use LaravelJsonApi\Core\Resources\JsonApiResource;

/**
* @property {{ model }} $resource
*/
class {{ class }} extends JsonApiResource
{

Expand All @@ -17,8 +21,8 @@ class {{ class }} extends JsonApiResource
public function attributes($request): iterable
{
return [
'createdAt' => $this->created_at,
'updatedAt' => $this->updated_at,
'createdAt' => $this->resource->created_at,
'updatedAt' => $this->resource->updated_at,
];
}

Expand Down
37 changes: 35 additions & 2 deletions tests/lib/Integration/Console/MakeResourceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@

class MakeResourceTest extends TestCase
{

/**
* @return void
*/
Expand Down Expand Up @@ -60,6 +59,33 @@ public function test(): void
$this->assertResourceCreated();
}

public function testModelWithoutNamespace(): void
{
config()->set('jsonapi.servers', [
'v1' => Server::class,
]);

$result = $this->artisan('jsonapi:resource posts --model BlogPost');

$this->assertSame(0, $result);
$this->assertResourceCreated('App\Models\BlogPost', 'BlogPost');
}

public function testModelWithNamespace(): void
{
config()->set('jsonapi.servers', [
'v1' => Server::class,
]);

$result = $this->artisan('jsonapi:resource', [
'name' => 'posts',
'--model' => '\App\Foo\Bar\BlogPost',
]);

$this->assertSame(0, $result);
$this->assertResourceCreated('App\Foo\Bar\BlogPost', 'BlogPost');
}

public function testServer(): void
{
config()->set('jsonapi.servers', [
Expand Down Expand Up @@ -104,9 +130,14 @@ public function testInvalidServer(): void
}

/**
* @param string $namespacedModel
* @param string $model
* @return void
*/
private function assertResourceCreated(): void
private function assertResourceCreated(
string $namespacedModel = 'App\Models\Post',
string $model = 'Post'
): void
{
$this->assertFileExists($path = app_path('JsonApi/V1/Posts/PostResource.php'));
$content = file_get_contents($path);
Expand All @@ -115,6 +146,8 @@ private function assertResourceCreated(): void
'namespace App\JsonApi\V1\Posts;',
'use LaravelJsonApi\Core\Resources\JsonApiResource;',
'class PostResource extends JsonApiResource',
"use {$namespacedModel};",
"@property {$model} \$resource",
];

foreach ($tests as $expected) {
Expand Down

0 comments on commit be16a21

Please sign in to comment.