Skip to content

Commit a98ead2

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

6 files changed

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

src/Resolvers/PathResolver.php

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

src/Resolvers/Resolver.php

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

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)