Skip to content
This repository was archived by the owner on Aug 27, 2024. It is now read-only.

Commit c1ab1d5

Browse files
committed
Move classes to packages
1 parent 6fad6e3 commit c1ab1d5

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed

src/Api/ApiResourceRegistrar.php

+136
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<?php
2+
3+
namespace Saritasa\Laravel\Controllers\Api;
4+
5+
use Saritasa\Exceptions\ConfigurationException;
6+
use Dingo\Api\Routing\Router;
7+
8+
/**
9+
* Wrapper for Dingo router, adds concise methods for API URLs registration.
10+
* @method void get(string $resource, string $controller, string $action = null, string $route = null) Add POST route
11+
* @method void post(string $resource, string $controller, string $action = null, string $route = null) Add POST route
12+
* @method void patch(string $resource, string $controller, string $action = null, string $route = null) Add POST route
13+
* @method void put(string $resource, string $controller, string $action = null, string $route = null) Add POST route
14+
* @method void delete(string $resource, string $controller, string $action = null, string $route = null) Add POST route
15+
*/
16+
class ApiResourceRegistrar
17+
{
18+
/**
19+
* @var Router
20+
*/
21+
private $api;
22+
23+
private $default = [
24+
'index' => ['verb' => 'get', 'route' => ''],
25+
'create' => ['verb' => 'post', 'route' => ''],
26+
'show' => ['verb' => 'get', 'route' => '/{id}'],
27+
'update' => ['verb' => 'put', 'route' => '/{id}'],
28+
'destroy' => ['verb' => 'delete', 'route' => '/{id}']
29+
];
30+
31+
const VERBS = ['get', 'post', 'put', 'patch', 'delete'];
32+
33+
public function __construct(Router $api)
34+
{
35+
$this->api = $api;
36+
}
37+
38+
/**
39+
* Registers controller methods
40+
*
41+
* index - as GET /resourceName
42+
* create - as POST /resourceName
43+
* show - as GET /resourceName/{id}
44+
* update - as PUT /resourceName/{id}
45+
* destroy - as DELETE /resourceName/{id}
46+
*
47+
* @param string $resourceName
48+
* @param string $controller
49+
* @param array $options
50+
*/
51+
public function resource(string $resourceName, string $controller, array $options = [])
52+
{
53+
$routes = [];
54+
if (!$options || !count($options)) {
55+
$routes = $this->default;
56+
} else if (isset($options['only'])) {
57+
$routes = array_intersect_key($this->default, $this->asArray($options['only']));
58+
} else if (isset($options['except'])) {
59+
$routes = array_diff_key($this->default, $this->asArray($options['except']));
60+
}
61+
62+
foreach (static::VERBS as $verb) {
63+
if (isset($options[$verb])) {
64+
$actions = $this->asArray($options[$verb]);
65+
if (!is_array($actions)) {
66+
$t = gettype($actions);
67+
throw new \InvalidArgumentException("\$options['$verb'] must contain string or array. $t was given");
68+
}
69+
70+
foreach ($actions as $action => $i) {
71+
$routes[$action] = ['verb' => $verb, 'route' => '/'.$action];
72+
}
73+
}
74+
}
75+
76+
foreach ($routes as $action => $opt) {
77+
$verb = $opt['verb'];
78+
$this->api->$verb($resourceName.$opt['route'], [
79+
'as' => $resourceName.'.'.$action,
80+
'uses' => $controller.'@'.$action
81+
]);
82+
}
83+
}
84+
85+
public function __call($name, $arguments)
86+
{
87+
if (in_array($name, static::VERBS)) {
88+
array_splice($arguments, 0, 0, [$name]);
89+
return call_user_func_array([$this, 'action'], $arguments);
90+
}
91+
throw new ConfigurationException("Unknown HTTP verb $name used for route $arguments[0]");
92+
}
93+
94+
/**
95+
* @param string $verb - one of GET / POST / PUT / DELETE
96+
* @param string $path - URL path
97+
* @param string $controller Class, containing action method
98+
* @param string|null $action method, which will be executed on route hit
99+
* @param string|null $route - route name
100+
* @return mixed
101+
*/
102+
private function action(string $verb, string $path, string $controller, string $action = null, string $route = null)
103+
{
104+
$pos = strrpos($path, '/', -1);
105+
$pathLastSegment = $pos ? substr($path, $pos+1) : $path;
106+
107+
if (!$action) {
108+
$action = $pathLastSegment;
109+
}
110+
if (!$route) {
111+
$route = strtolower(str_replace('/', '.', $path));
112+
// Small piece of magic: make auto-named routes look nicer
113+
if ($pathLastSegment != $action) {
114+
if (strrpos($route, '.'.$pathLastSegment, -1) === false) {
115+
$route = "$route.$action";
116+
} else {
117+
$route = str_replace('.' . $pathLastSegment, '.' . $action, $route);
118+
}
119+
}
120+
$route = strtolower($route);
121+
}
122+
return $this->api->$verb($path ?: $action, ['uses' => $controller.'@'.$action, 'as' => $route]);
123+
}
124+
125+
private function asArray($value): array
126+
{
127+
if (is_array($value)) {
128+
return $value;
129+
}
130+
if (is_string($value)) {
131+
$keys = explode(',', $value);
132+
return array_flip($keys);
133+
}
134+
return null;
135+
}
136+
}

0 commit comments

Comments
 (0)