8000 Allow model and resource name to be overridden · sablesoft/laravel-json-api@2d250a8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2d250a8

Browse files
committed
Allow model and resource name to be overridden
1 parent aff3e3e commit 2d250a8

File tree

12 files changed

+224
-35
lines changed

12 files changed

+224
-35
lines changed

src/Api/Api.php

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@ class Api
8282
private $url;
8383

8484
/**
85-
* @var string|null
85+
* @var Jobs
8686
*/
87-
private $jobFqn;
87+
private $jobs;
8888

8989
/**
9090
* @var string|null
@@ -120,7 +120,7 @@ class Api
120120
* @param $apiName
121121
* @param array $codecs
122122
* @param Url $url
123-
* @param string|null $jobFqn
123+
* @param Jobs $jobs
124124
* @param bool $useEloquent
125125
* @param string|null $supportedExt
126126
* @param array $errors
@@ -131,7 +131,7 @@ public function __construct(
131131
$apiName,
132132
array $codecs,
133133
Url $url,
134-
$jobFqn = null,
134+
Jobs $jobs,
135135
$useEloquent = true,
136136
$supportedExt = null,
137137
array $errors = []
@@ -141,7 +141,7 @@ public function __construct(
141141
$this->name = $apiName;
142142
$this->codecs = $codecs;
143143
$this->url = $url;
144-
$this->jobFqn = $jobFqn;
144+
$this->jobs = $jobs;
145145
$this->useEloquent = $useEloquent;
146146
$this->supportedExt = $supportedExt;
147147
$this->errors = $errors;
@@ -213,13 +213,11 @@ public function getUrl()
213213
}
214214

215215
/**
216-
* Get the fully qualified name of the class to use for storing client jobs.
217-
*
218-
* @return string
216+
* @return Jobs
219217
*/
220-
public function getJobFqn()
218+
public function getJobs()
221219
{
222-
return $this->jobFqn ?: ClientJob::class;
220+
return $this->jobs;
223221
}
224222

225223
/**

src/Api/Jobs.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
namespace CloudCreativity\LaravelJsonApi\Api;
4+
5+
use CloudCreativity\LaravelJsonApi\Queue\ClientJob;
6+
use CloudCreativity\LaravelJsonApi\Routing\ResourceRegistrar;
7+
8+
class Jobs
9+
{
10+
11+
/**
12+
* @var string
13+
*/
14+
private $resource;
15+
16+
/**
17+
* @var string
18+
*/
19+
private $model;
20+
21+
/**
22+
* @param array $input
23+
* @return Jobs
24+
*/
25+
public static function fromArray(array $input): self
26+
{
27+
return new self(
28+
$input['resource'] ?? ResourceRegistrar::KEYWORD_PROCESSES,
29+
$input['model'] ?? ClientJob::class
30+
);
31+
}
32+
33+
/**
34+
* Jobs constructor.
35+
*
36+
* @param string $resource
37+
* @param string $model
38+
*/
39+
public function __construct(string $resource, string $model)
40+
{
41+
if (!class_exists($model)) {
42+
throw new \InvalidArgumentException("Expecting {$model} to be a valid class name.");
43+
}
44+
45+
$this->resource = $resource;
46+
$this->model = $model;
47+
}
48+
49+
/**
50+
* @return string
51+
*/
52+
public function getResource(): string
53+
{
54+
return $this->resource;
55+
}
56+
57+
/**
58+
* @return string
59+
*/
60+
public function getModel(): string
61+
{
62+
return $this->model;
63+
}
64+
65+
}

src/Api/Repository.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public function createApi($apiName, $host = null)
7979
$apiName,
8080
$config['codecs'],
8181
Url::fromArray($config['url']),
82-
$config['jobs'],
82+
Jobs::fromArray($config['jobs'] ?: []),
8383
$config['use-eloquent'],
8484
$config['supported-ext'],
8585
$config['errors']
@@ -128,7 +128,7 @@ private function normalize(array $config, $host = null)
128128
$config = array_replace([
129129
'namespace' => null,
130130
'by-resource' => true,
131-
'resources' => null,
131+
'resources' => [],
132132
'use-eloquent' => true,
133133
'codecs' => null,
134134
'supported-ext' => null,
@@ -141,6 +141,7 @@ private function normalize(array $config, $host = null)
141141
$config['namespace'] = rtrim(app()->getNamespace(), '\\') . '\\JsonApi';
142142
}
143143

144+
$config['resources'] = $this->normalizeResources($config['resources'] ?? [], $config);
144145
$config['url'] = $this->normalizeUrl((array) $config['url'], $host);
145146
$config['errors'] = array_replace($this->defaultErrors(), (array) $config['errors']);
146147

@@ -188,4 +189,20 @@ private function normalizeUrl(array $url, $host = null)
188189
'name' => (string) array_get($url, 'name'),
189190
];
190191
}
192+
193+
/**
194+
* @param array $resources
195+
* @param array $config
196+
* @return array
197+
*/
198+
private function normalizeResources(array $resources, array $config)
199+
{
200+
$jobs = isset($config['jobs']) ? Jobs::fromArray($config['jobs']) : null;
201+
202+
if ($jobs && !isset($resources[$jobs->getResource()])) {
203+
$resources[$jobs->getResource()] = $jobs->getModel();
204+
}
205+
206+
return $resources;
207+
}
191208
}

src/Queue/ClientDispatch.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,9 @@ public function getMaxTries(): ?int
141141
*/
142142
public function dispatch(): AsynchronousProcess
143143
{
144-
$fqn = json_api($this->getApi())->getJobFqn();
144+
$fqn = json_api($this->getApi())
145+
->getJobs()
146+
->getModel();
145147

146148
$this->job->clientJob = new $fqn;
147149
$this->job->clientJob->dispatching($this);

src/Queue/ClientJobSchema.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,17 @@ abstract class ClientJobSchema extends SchemaProvider
2323
{
2424

2525
/**
26-
* @var string
26+
* @var string|null
2727
*/
28-
protected $resourceType = 'queue-jobs';
28+
protected $api;
29+
30+
/**
31+
* @return string
32+
*/
33+
public function getResourceType()
34+
{
35+
return json_api($this->api)->getJobs()->getResource();
36+
}
2937

3038
/**
3139
* @param ClientJob $resource

src/Routing/ApiGroup.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ protected function resourceDefaults()
9999
{
100100
return [
101101
'default-authorizer' => $this->options->get('authorizer'),
102+
'processes' => $this->api->getJobs()->getResource(),
102103
'prefix' => $this->api->getUrl()->getNamespace(),
103104
'id' => $this->options->get('id'),
104105
];

src/Routing/RegistersResources.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ protected function resourceUrl()
6565
*/
6666
protected function baseProcessUrl(): string
6767
{
68-
return '/' . ResourceRegistrar::KEYWORD_PROCESSES;
68+
return '/' . $this->processType();
6969
}
7070

7171
/**
@@ -78,11 +78,10 @@ protected function processUrl(): string
7878

7979
/**
8080
* @return string
81-
* @todo allow this to be customised.
8281
*/
8382
protected function processType(): string
8483
{
85-
return 'queue-jobs';
84+
return $this->options->get('processes') ?: ResourceRegistrar::KEYWORD_PROCESSES;
8685
}
8786

8887
/**

stubs/api.php

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,18 @@
9999
| Jobs
100100
|--------------------------------------------------------------------------
101101
|
102-
| Defines the class that is used to store client dispatched jobs. The
103-
| storing of these classes allows you to implement the JSON API
104-
| recommendation for asynchronous processing.
102+
| Defines settings for the asynchronous processing feature. We recommend
103+
| referring to the documentation on asynchronous processing if you are
104+
| using this feature.
105105
|
106-
| We recommend referring to the Laravel JSON API documentation on
107-
| asynchronous processing if you are using this feature. If you use a
108-
| different class here, it must implement the asynchronous process
109-
| interface.
106+
| Note that if you use a different model class, it must implement the
107+
| asynchronous process interface.
110108
|
111109
*/
112-
'jobs' => \CloudCreativity\LaravelJsonApi\Queue\ClientJob::class,
110+
'jobs' => [
111+
'resource' => 'queue-jobs',
112+
'model' => \CloudCreativity\LaravelJsonApi\Queue\ClientJob::class,
113+
],
113114

114115
/*
115116
|--------------------------------------------------------------------------

tests/dummy/config/json-api-v1.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@
5858
'downloads' => \DummyApp\Download::class,
5959
'phones' => \DummyApp\Phone::class,
6060
'posts' => \DummyApp\Post::class,
61-
'queue-jobs' => \CloudCreativity\LaravelJsonApi\Queue\ClientJob::class,
6261
'sites' => \DummyApp\Entities\Site::class,
6362
'tags' => \DummyApp\Tag::class,
6463
'users' => \DummyApp\User::class,
@@ -108,17 +107,18 @@
108107
| Jobs
109108
|--------------------------------------------------------------------------
110109
|
111-
| Defines the class that is used to store client dispatched jobs. The
112-
| storing of these classes allows you to implement the JSON API
113-
| recommendation for asynchronous processing.
110+
| Defines settings for the asynchronous processing feature. We recommend
111+
| referring to the documentation on asynchronous processing if you are
112+
| using this feature.
114113
|
115-
| We recommend referring to the Laravel JSON API documentation on
116-
| asynchronous processing if you are using this feature. If you use a
117-
| different class here, it must implement the asynchronous process
118-
| interface.
114+
| Note that if you use a different model class, it must implement the
115+
| asynchronous process interface.
119116
|
120117
*/
121-
'jobs' => \CloudCreativity\LaravelJsonApi\Queue\ClientJob::class,
118+
'jobs' => [
119+
'resource' => 'queue-jobs',
120+
'model' => \CloudCreativity\LaravelJsonApi\Queue\ClientJob::class,
121+
],
122122

123123
/*
124124
|--------------------------------------------------------------------------
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace CloudCreativity\LaravelJsonApi\Tests\Integration\Queue;
4+
5+
use CloudCreativity\LaravelJsonApi\Eloquent\AbstractAdapter;
6+
use Illuminate\Support\Collection;
7+
8+
class CustomAdapter extends AbstractAdapter
9+
{
10+
11+
/**
12+
* Adapter constructor.
13+
*/
14+
public function __construct()
15+
{
16+
parent::__construct(new CustomJob());
17+
}
18+
19+
/**
20+
* @inheritDoc
21+
*/
22+
protected function filter($query, Collection $filters)
23+
{
24+
// TODO: Implement filter() method.
25+
}
26+
27+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace CloudCreativity\LaravelJsonApi\Tests\Integration\Queue;
4+
5+
use CloudCreativity\LaravelJsonApi\Queue\ClientJob;
6+
7+
class CustomJob extends ClientJob
8+
{
9+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
namespace CloudCreativity\LaravelJsonApi\Tests\Integration\Queue;
4+
5+
use CloudCreativity\LaravelJsonApi\Queue\ClientJob;
6+
use DummyApp\Jobs\CreateDownload;
7+
use DummyApp\JsonApi\QueueJobs;
8+
use CloudCreativity\LaravelJsonApi\Tests\Integration\TestCase;
9+
10+
class CustomiseTest extends TestCase
11+
{
12+
13+
/**
14+
* Set to false as we need to override config before
15+
*
16+
* @var bool
17+
*/
18+
protected $appRoutes = false;
19+
20+
/**
21+
* @var string
22+
*/
23+
protected $resourceType = 'client-jobs';
24+
25+
/**
26+
* @return void
27+
*/
28+
protected function setUp()
29+
{
30+
parent::setUp();
31+
32+
config()->set('json-api-v1.jobs', [
33+
'resource' => $this->resourceType,
34+
'model' => CustomJob::class,
35+
]);
36+
37+
$this->app->bind('DummyApp\JsonApi\ClientJobs\Adapter', CustomAdapter::class);
38+
$this->app->bind('DummyApp\JsonApi\ClientJobs\Schema', QueueJobs\Schema::class);
39+
$this->app->bind('DummyApp\JsonApi\ClientJobs\Validators', QueueJobs\Validators::class);
40+
41+
$this->withAppRoutes();
42+
}
43+
44+
public function testListAll()
45+
{
46+
$jobs = factory(ClientJob::class, 2)->create();
47+
// this one should not appear in results as it is for a different resource type.
48+
factory(ClientJob::class)->create(['resource_type' => 'foo']);
49+
50+
$this->getJsonApi('/api/v1/downloads/client-jobs')
51+
->assertFetchedMany($jobs);
52+
}
53+
54+
public function testPendingDispatch()
55+
{
56+
$async = CreateDownload::client('test')
57+
->setResource('downloads')
58+
->dispatch();
59+
60+
$this->assertInstanceOf(CustomJob::class, $async);
61+
}
62+
}

0 commit comments

Comments
 (0)
0