Skip to content

Commit c2c84f5

Browse files
committed
Refactor to resolver strategies
1 parent 222366a commit c2c84f5

6 files changed

Lines changed: 185 additions & 53 deletions

File tree

src/APIResourceManager.php

Lines changed: 12 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
use Exception;
66
use Illuminate\Http\Resources\Json\JsonResource;
7-
use Illuminate\Session\Store;
87
use Illuminate\Support\Facades\Storage;
98
use Illuminate\Support\Str;
109
use Juampi92\APIResources\Exceptions\ResourceNotFoundException;
1110
use Juampi92\APIResources\Exceptions\WrongConfigurationException;
11+
use Juampi92\APIResources\Resolvers\ResolverFactory;
1212

1313
class APIResourceManager
1414
{
@@ -170,40 +170,9 @@ public function getBasePath(): string
170170
return $this->path;
171171
}
172172

173-
/**
174-
* Returns the classname of the versioned resource,
175-
* or it's latest version if it doesn't exist.
176-
*
177-
* Throws an exception if it cannot find it.
178-
*
179-
* @param string $classname
180-
*
181-
* @return string
182-
* @throws ResourceNotFoundException
183-
*/
184-
public function resolveClassname(string $classname)
173+
public function getResourcesPath(): string
185174
{
186-
$path = $this->parseClassname($classname);
187-
188-
// Check if the resource was found
189-
if (class_exists($path)) {
190-
return $path;
191-
}
192-
193-
// If we are on the latest version, stop searching
194-
if ($this->isLatest()) {
195-
throw new Exceptions\ResourceNotFoundException($classname, $path);
196-
}
197-
198-
// Search on the latest version
199-
$path = $this->parseClassname($classname, true);
200-
201-
// If still does not exists, fail
202-
if (! class_exists($path)) {
203-
throw new Exceptions\ResourceNotFoundException($classname, $path);
204-
}
205-
206-
return $path;
175+
return $this->resources;
207176
}
208177

209178
/**
@@ -212,6 +181,7 @@ public function resolveClassname(string $classname)
212181
* @param bool $forceLatest Set to true if last version is required
213182
*
214183
* @return class-string<JsonResource>
184+
* @deprecated
215185
*/
216186
protected function parseClassname(string $classname, bool $forceLatest = false): string
217187
{
@@ -255,26 +225,15 @@ protected function resolveClassnameFromFilesystem(string $classname, string $ver
255225
*/
256226
public function resolve(string $classname): APIResource
257227
{
258-
$path = $this->resolveClassname($classname);
259-
260-
// Check if the resource was found
261-
if (! class_exists($path)) {
262-
263-
// If we are on the latest version, stop searching
264-
if ($this->isLatest()) {
265-
throw new Exceptions\ResourceNotFoundException($classname, $path);
266-
}
267-
268-
// Search on the latest version
269-
$path = $this->resolveClassname($classname, true);
270-
271-
// If still does not exists, fail
272-
if (! class_exists($path)) {
273-
throw new Exceptions\ResourceNotFoundException($classname, $path);
274-
}
275-
}
228+
return ResolverFactory::make($classname)->run();
229+
}
276230

277-
return new APIResource($path);
231+
/**
232+
* @throws ResourceNotFoundException
233+
*/
234+
public function resolveClassname(string $classname): string
235+
{
236+
return ResolverFactory::make($classname)->dryRun();
278237
}
279238

280239
/**

src/Facades/APIResource.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@
77
/**
88
* @method static \Juampi92\APIResources\APIResourceManager setVersion(string $version, string $apiName = null)
99
* @method static string getVersion()
10+
* @method static string getLatestVersion()
1011
* @method static bool isLatest(string $c = null)
1112
* @method static string resolveClassname(string $classname, bool $forceLatest = null) Returns formatted classname using current version
1213
* @method static \Juampi92\APIResources\APIResource resolve(string $classname)
1314
* @method static \Illuminate\Http\Resources\Json\Resource make(string $classname, ...$args) Resolves the classname and instantiates the resource
1415
* @method static \Illuminate\Http\Resources\Json\Resource collection(string $classname, ...$args) Resolves the classname and instantiates the resource as a collection
1516
* @method static string getRoute(string $name, array $parameters, bool $absolute)
1617
* @method static string getRouteName(string $name)
18+
* @method static string getBasePath()
19+
* @method static string getResourcesPath()
1720
*
1821
* @see \Juampi92\APIResources\APIResourceManager
1922
*/

src/Resolvers/CacheResolver.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Juampi92\APIResources\Resolvers;
4+
5+
use Illuminate\Http\Resources\Json\JsonResource;
6+
use Illuminate\Http\Resources\Json\ResourceCollection;
7+
use Illuminate\Support\Facades\Storage;
8+
9+
class CacheResolver extends Resolver
10+
{
11+
protected function resolve(): ?string
12+
{
13+
$routingManifest = json_decode(Storage::get(config('api.routing_manifest_path')), true);
14+
15+
if (! $routingManifest) {
16+
return null;
17+
}
18+
19+
/** @var ?class-string<JsonResource|ResourceCollection> $classPath */
20+
$classPath = $routingManifest[$this->classname][$this->version] ?? null;
21+
22+
if ($classPath && ! class_exists($classPath)) {
23+
return null;
24+
}
25+
26+
return $classPath;
27+
}
28+
}

src/Resolvers/PathResolver.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace Juampi92\APIResources\Resolvers;
4+
5+
use Illuminate\Http\Resources\Json\JsonResource;
6+
use Illuminate\Http\Resources\Json\ResourceCollection;
7+
use Illuminate\Support\Str;
8+
use Juampi92\APIResources\Facades\APIResource;
9+
10+
class PathResolver extends Resolver
11+
{
12+
protected function resolve(): ?string
13+
{
14+
$basePath = APIResource::getBasePath();
15+
16+
$resourcePath = $this->guessResourcePath();
17+
18+
/** @var class-string<JsonResource|ResourceCollection> $fullPath */
19+
$fullPath = "\\{$basePath}\\{$resourcePath}";
20+
21+
if (! class_exists($fullPath)) {
22+
return null;
23+
}
24+
25+
return $fullPath;
26+
}
27+
28+
private function guessResourcePath(): string
29+
{
30+
$resourcesPath = APIResource::getResourcesPath();
31+
32+
if (empty($resourcesPath)) {
33+
return "{$this->version}\\{$this->classname}";
34+
}
35+
36+
return sprintf(
37+
"%s\\%s\\%s",
38+
$resourcesPath,
39+
$this->version,
40+
Str::after($this->classname, $resourcesPath . "\\")
41+
);
42+
}
43+
}

src/Resolvers/Resolver.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
namespace Juampi92\APIResources\Resolvers;
4+
5+
use Illuminate\Http\Resources\Json\JsonResource;
6+
use Illuminate\Http\Resources\Json\ResourceCollection;
7+
use Juampi92\APIResources\APIResource;
8+
use Juampi92\APIResources\Exceptions\ResourceNotFoundException;
9+
10+
abstract class Resolver
11+
{
12+
protected string $classname;
13+
14+
protected string $version;
15+
16+
protected ?Resolver $fallback = null;
17+
18+
public function __construct(string $classname, string $version)
19+
{
20+
$this->version = $version;
21+
$this->classname = $classname;
22+
}
23+
24+
public function setFallback(Resolver $resolveStrategy): Resolver
25+
{
26+
$this->fallback = $resolveStrategy;
27+
28+
return $resolveStrategy;
29+
}
30+
31+
/**
32+
* @throws ResourceNotFoundException
33+
*/
34+
public function run(): APIResource
35+
{
36+
if ($path = $this->resolve()) {
37+
return new APIResource($path);
38+
}
39+
40+
if ($this->fallback) {
41+
return $this->fallback->run();
42+
}
43+
44+
throw new ResourceNotFoundException($this->classname, $path ?? '--unresolved--');
45+
}
46+
47+
/**
48+
* @throws ResourceNotFoundException
49+
*/
50+
public function dryRun(): string
51+
{
52+
if ($path = $this->resolve()) {
53+
return $path;
54+
}
55+
56+
if ($this->fallback) {
57+
return $this->fallback->dryRun();
58+
}
59+
60+
throw new ResourceNotFoundException($this->classname, $path ?? '--unresolved--');
61+
}
62+
63+
/**
64+
* @return class-string<JsonResource|ResourceCollection>
65+
*/
66+
abstract protected function resolve(): ?string;
67+
}

src/Resolvers/ResolverFactory.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace Juampi92\APIResources\Resolvers;
4+
5+
use Illuminate\Support\Str;
6+
use Juampi92\APIResources\Facades\APIResource;
7+
8+
class ResolverFactory
9+
{
10+
public static function make(string $classname): Resolver
11+
{
12+
$version = Str::start(APIResource::getVersion(), 'v');
13+
14+
$cacheResolver = new CacheResolver($classname, $version);
15+
16+
$pathResolver = new PathResolver($classname, $version);
17+
18+
if (! APIResource::isLatest()) {
19+
$latestVersion = Str::start(APIResource::getLatestVersion(), 'v');
20+
21+
$pathResolver->setFallback(
22+
new PathResolver($classname, $latestVersion)
23+
);
24+
}
25+
26+
$cacheResolver->setFallback(
27+
$pathResolver,
28+
);
29+
30+
return $cacheResolver;
31+
}
32+
}

0 commit comments

Comments
 (0)