Skip to content

Commit fc1c417

Browse files
committed
[Feature] Add sort-field generator command
1 parent 9b06977 commit fc1c417

File tree

6 files changed

+241
-2
lines changed

6 files changed

+241
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. This projec
1111
schemas. Previously only sortable attributes were supported. These new classes are added to schemas in the
1212
`sortables()` method.
1313
- Eloquent schemas now support a default sort order via the `$defaultSort` property.
14+
- New generator command `jsonapi:sort-field` to create a custom sort field class.
1415
- [#74](https://github.com/laravel-json-api/laravel/issues/74) Developers can now add default include paths to the query
1516
request classes (e.g. `PostQuery` and `PostCollectionQuery`) via the `$defaultIncludePaths` property. These include
1617
paths are used if the client does not provide any include paths.

src/Console/MakeSortField.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
/*
3+
* Copyright 2021 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;
21+
22+
use Illuminate\Console\GeneratorCommand as BaseGeneratorCommand;
23+
use Symfony\Component\Console\Input\InputOption;
24+
25+
class MakeSortField extends BaseGeneratorCommand
26+
{
27+
28+
use Concerns\ResolvesStub;
29+
30+
/**
31+
* @var string
32+
*/
33+
protected $name = 'jsonapi:sort-field';
34+
35+
/**
36+
* @var string
37+
*/
38+
protected $description = 'Create a new JSON:API sort field.';
39+
40+
/**
41+
* @var string
42+
*/
43+
protected $type = 'JSON:API sort field';
44+
45+
/**
46+
* @inheritDoc
47+
*/
48+
protected function getStub()
49+
{
50+
return $this->resolveStubPath('sort-field.stub');
51+
}
52+
53+
/**
54+
* @inheritDoc
55+
*/
56+
protected function getDefaultNamespace($rootNamespace)
57+
{
58+
$jsonApi = trim(config('jsonapi.namespace') ?: 'JsonApi', '\\');
59+
60+
return $rootNamespace . '\\' . $jsonApi . '\\' . 'Sorting';
61+
}
62+
63+
/**
64+
* Get the console command options.
65+
*
66+
* @return array
67+
*/
68+
protected function getOptions()
69+
{
70+
return [
71+
['force', null, InputOption::VALUE_NONE, 'Create the class even if the sort field already exists'],
72+
];
73+
}
74+
75+
}

src/ServiceProvider.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public function boot(Router $router): void
5555
Console\MakeResource::class,
5656
Console\MakeSchema::class,
5757
Console\MakeServer::class,
58+
Console\MakeSortField::class,
5859
Console\StubPublish::class,
5960
]);
6061
}

stubs/sort-field.stub

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
namespace {{ namespace }};
4+
5+
use LaravelJsonApi\Eloquent\Contracts\SortField;
6+
7+
class {{ class }} implements SortField
8+
{
9+
10+
/**
11+
* @var string
12+
*/
13+
private string $name;
14+
15+
/**
16+
* Create a new sort field.
17+
*
18+
* @param string $name
19+
* @param string|null $column
20+
* @return {{ class }}
21+
*/
22+
public static function make(string $name): self
23+
{
24+
return new static($name);
25+
}
26+
27+
/**
28+
* {{ class }} constructor.
29+
*
30+
* @param string $name
31+
*/
32+
public function __construct(string $name)
33+
{
34+
$this->name = $name;
35+
}
36+
37+
/**
38+
* Get the name of the sort field.
39+
*
40+
* @return string
41+
*/
42+
public function sortField(): string
43+
{
44+
return $this->name;
45+
}
46+
47+
/**
48+
* Apply the sort order to the query.
49+
*
50+
* @param \Illuminate\Database\Eloquent\Builder $query
51+
* @param string $direction
52+
* @return \Illuminate\Database\Eloquent\Builder
53+
*/
54+
public function sort($query, string $direction = 'asc')
55+
{
56+
// @TODO
57+
}
58+
59+
}

tests/lib/Integration/Console/MakeFilterTest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,10 @@ private function assertFilterCreated(string $namespace): void
8888

8989
$tests = [
9090
"namespace App\\{$namespace}\\Filters;",
91+
'use LaravelJsonApi\Eloquent\Contracts\Filter;',
9192
'class CustomFilter implements Filter',
92-
"* @return CustomFilter",
93-
"* CustomFilter constructor.",
93+
'* @return CustomFilter',
94+
'* CustomFilter constructor.',
9495
];
9596

9697
foreach ($tests as $expected) {
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<?php
2+
/*
3+
* Copyright 2021 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\Tests\Integration\Console;
21+
22+
use Illuminate\Filesystem\Filesystem;
23+
use LaravelJsonApi\Laravel\Tests\Integration\TestCase;
24+
25+
class MakeSortFieldTest extends TestCase
26+
{
27+
28+
/**
29+
* @return void
30+
*/
31+
protected function setUp(): void
32+
{
33+
parent::setUp();
34+
$this->withoutMockingConsoleOutput();
35+
36+
$files = new Filesystem();
37+
$files->deleteDirectory(app_path('JsonApi'));
38+
$files->deleteDirectory(app_path('Foo'));
39+
}
40+
41+
/**
42+
* @return void
43+
*/
44+
protected function tearDown(): void
45+
{
46+
parent::tearDown();
47+
$files = new Filesystem();
48+
$files->deleteDirectory(app_path('JsonApi'));
49+
$files->deleteDirectory(app_path('Foo'));
50+
}
51+
52+
public function test(): void
53+
{
54+
config()->set('jsonapi', [
55+
'namespace' => 'JsonApi',
56+
]);
57+
58+
$result = $this->artisan('jsonapi:sort-field CustomSort');
59+
60+
$this->assertSame(0, $result);
61+
$this->assertSortFieldCreated('JsonApi');
62+
}
63+
64+
public function testCustomNamespace(): void
65+
{
66+
config()->set('jsonapi', [
67+
'namespace' => 'Foo\Bar',
68+
]);
69+
70+
$result = $this->artisan('jsonapi:sort-field', [
71+
'name' => 'CustomSort'
72+
]);
73+
74+
$this->assertSame(0, $result);
75+
$this->assertSortFieldCreated('Foo\Bar');
76+
}
77+
78+
/**
79+
* @param string $namespace
80+
* @return void
81+
*/
82+
private function assertSortFieldCreated(string $namespace): void
83+
{
84+
$path = str_replace('\\', '/', $namespace);
85+
86+
$this->assertFileExists($path = app_path("{$path}/Sorting/CustomSort.php"));
87+
$content = file_get_contents($path);
88+
89+
$tests = [
90+
"namespace App\\{$namespace}\\Sorting;",
91+
'use LaravelJsonApi\Eloquent\Contracts\SortField;',
92+
'class CustomSort implements SortField',
93+
'* @return CustomSort',
94+
'* CustomSort constructor.',
95+
];
96+
97+
foreach ($tests as $expected) {
98+
$this->assertStringContainsString($expected, $content);
99+
}
100+
}
101+
102+
}

0 commit comments

Comments
 (0)