Skip to content

Commit be16a21

Browse files
authored
feat: add support to replace model in resource stub (#272)
1 parent 567263e commit be16a21

File tree

5 files changed

+119
-23
lines changed

5 files changed

+119
-23
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
/*
3+
* Copyright 2024 Cloud Creativity Limited
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
declare(strict_types=1);
19+
20+
namespace LaravelJsonApi\Laravel\Console\Concerns;
21+
22+
use Illuminate\Support\Str;
23+
use function array_keys;
24+
use function array_values;
25+
use function str_replace;
26+
27+
trait ReplacesModel
28+
{
29+
30+
/**
31+
* @param string $stub
32+
* @param string $model
33+
* @return string
34+
*/
35+
protected function replaceModel(string $stub, string $model): string
36+
{
37+
$model = str_replace('/', '\\', $model);
38+
39+
if (Str::startsWith($model, '\\')) {
40+
$namespacedModel = trim($model, '\\');
41+
} else {
42+
$namespacedModel = $this->qualifyModel($model);
43+
}
44+
45+
$model = class_basename($model);
46+
47+
$replace = [
48+
'{{ namespacedModel }}' => $namespacedModel,
49+
'{{namespacedModel}}' => $namespacedModel,
50+
'{{ model }}' => $model,
51+
'{{model}}' => $model,
52+
];
53+
54+
return str_replace(
55+
array_keys($replace), array_values($replace), $stub
56+
);
57+
}
58+
}

src/Console/MakeResource.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919

2020
namespace LaravelJsonApi\Laravel\Console;
2121

22+
use LaravelJsonApi\Laravel\Console\Concerns\ReplacesModel;
2223
use Symfony\Component\Console\Input\InputOption;
2324

2425
class MakeResource extends GeneratorCommand
2526
{
27+
use ReplacesModel;
2628

2729
/**
2830
* @var string
@@ -52,15 +54,27 @@ protected function getStub()
5254
return $this->resolveStubPath('resource.stub');
5355
}
5456

57+
/**
58+
* @inheritDoc
59+
*/
60+
protected function buildClass($name)
61+
{
62+
$stub = parent::buildClass($name);
63+
64+
$model = $this->option('model') ?: $this->guessModel();
65+
66+
return $this->replaceModel($stub, $model);
67+
}
68+
5569
/**
5670
* @inheritDoc
5771
*/
5872
protected function getOptions()
5973
{
6074
return [
6175
['force', null, InputOption::VALUE_NONE, 'Create the class even if the resource already exists'],
76+
['model', 'm', InputOption::VALUE_REQUIRED, 'The model that the resource applies to.'],
6277
['server', 's', InputOption::VALUE_REQUIRED, 'The JSON:API server the resource exists in.'],
6378
];
6479
}
65-
6680
}

src/Console/MakeSchema.php

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@
1919

2020
namespace LaravelJsonApi\Laravel\Console;
2121

22-
use Illuminate\Support\Str;
22+
use LaravelJsonApi\Laravel\Console\Concerns\ReplacesModel;
2323
use Symfony\Component\Console\Input\InputOption;
2424
use function array_keys;
2525
use function array_values;
2626
use function str_replace;
2727

2828
class MakeSchema extends GeneratorCommand
2929
{
30+
use ReplacesModel;
3031

3132
/**
3233
* @var string
@@ -47,7 +48,7 @@ class MakeSchema extends GeneratorCommand
4748
* @var string
4849
*/
4950
protected $classType = 'Schema';
50-
51+
5152
/**
5253
* @inheritDoc
5354
*/
@@ -65,7 +66,7 @@ protected function getStub()
6566
*/
6667
protected function buildClass($name)
6768
{
68-
$stub = parent::buildClass($name);
69+
$stub = $this->replaceSchema(parent::buildClass($name));
6970

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

@@ -77,24 +78,11 @@ protected function buildClass($name)
7778
* @param string $model
7879
* @return string
7980
*/
80-
protected function replaceModel(string $stub, string $model): string
81+
protected function replaceSchema(string $stub): string
8182
{
82-
$model = str_replace('/', '\\', $model);
83-
84-
if (Str::startsWith($model, '\\')) {
85-
$namespacedModel = trim($model, '\\');
86-
} else {
87-
$namespacedModel = $this->qualifyModel($model);
88-
}
89-
90-
$model = class_basename($model);
9183
$schema = $this->option('proxy') ? 'ProxySchema' : 'Schema';
9284

9385
$replace = [
94-
'{{ namespacedModel }}' => $namespacedModel,
95-
'{{namespacedModel}}' => $namespacedModel,
96-
'{{ model }}' => $model,
97-
'{{model}}' => $model,
9886
'{{ schema }}' => $schema,
9987
'{{schema}}' => $schema,
10088
];
@@ -117,5 +105,4 @@ protected function getOptions()
117105
['server', 's', InputOption::VALUE_REQUIRED, 'The JSON:API server the schema exists in.'],
118106
];
119107
}
120-
121108
}

stubs/resource.stub

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22

33
namespace {{ namespace }};
44

5+
use {{ namespacedModel }};
56
use Illuminate\Http\Request;
67
use LaravelJsonApi\Core\Resources\JsonApiResource;
78

9+
/**
10+
* @property {{ model }} $resource
11+
*/
812
class {{ class }} extends JsonApiResource
913
{
1014

@@ -17,8 +21,8 @@ class {{ class }} extends JsonApiResource
1721
public function attributes($request): iterable
1822
{
1923
return [
20-
'createdAt' => $this->created_at,
21-
'updatedAt' => $this->updated_at,
24+
'createdAt' => $this->resource->created_at,
25+
'updatedAt' => $this->resource->updated_at,
2226
];
2327
}
2428

tests/lib/Integration/Console/MakeResourceTest.php

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
class MakeResourceTest extends TestCase
2727
{
28-
2928
/**
3029
* @return void
3130
*/
@@ -60,6 +59,33 @@ public function test(): void
6059
$this->assertResourceCreated();
6160
}
6261

62+
public function testModelWithoutNamespace(): void
63+
{
64+
config()->set('jsonapi.servers', [
65+
'v1' => Server::class,
66+
]);
67+
68+
$result = $this->artisan('jsonapi:resource posts --model BlogPost');
69+
70+
$this->assertSame(0, $result);
71+
$this->assertResourceCreated('App\Models\BlogPost', 'BlogPost');
72+
}
73+
74+
public function testModelWithNamespace(): void
75+
{
76+
config()->set('jsonapi.servers', [
77+
'v1' => Server::class,
78+
]);
79+
80+
$result = $this->artisan('jsonapi:resource', [
81+
'name' => 'posts',
82+
'--model' => '\App\Foo\Bar\BlogPost',
83+
]);
84+
85+
$this->assertSame(0, $result);
86+
$this->assertResourceCreated('App\Foo\Bar\BlogPost', 'BlogPost');
87+
}
88+
6389
public function testServer(): void
6490
{
6591
config()->set('jsonapi.servers', [
@@ -104,9 +130,14 @@ public function testInvalidServer(): void
104130
}
105131

106132
/**
133+
* @param string $namespacedModel
134+
* @param string $model
107135
* @return void
108136
*/
109-
private function assertResourceCreated(): void
137+
private function assertResourceCreated(
138+
string $namespacedModel = 'App\Models\Post',
139+
string $model = 'Post'
140+
): void
110141
{
111142
$this->assertFileExists($path = app_path('JsonApi/V1/Posts/PostResource.php'));
112143
$content = file_get_contents($path);
@@ -115,6 +146,8 @@ private function assertResourceCreated(): void
115146
'namespace App\JsonApi\V1\Posts;',
116147
'use LaravelJsonApi\Core\Resources\JsonApiResource;',
117148
'class PostResource extends JsonApiResource',
149+
"use {$namespacedModel};",
150+
"@property {$model} \$resource",
118151
];
119152

120153
foreach ($tests as $expected) {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy