Passed
Push — master ( 73b7c1...6422a4 )
by Richard
126:50 queued 119:58
created

RoutesGenerator::buildClasses()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
c 0
b 0
f 0
dl 0
loc 16
rs 10
cc 2
nc 2
nop 0
1
<?php
2
3
namespace PWWEB\Artomator\Generators\Scaffold;
4
5
use Illuminate\Support\Str;
6
use PWWEB\Artomator\Common\CommandData;
7
8
class RoutesGenerator
9
{
10
    /**
11
     * Command data instance.
12
     *
13
     * @var CommandData
14
     */
15
    private $commandData;
16
17
    /**
18
     * Path variable.
19
     *
20
     * @var string
21
     */
22
    private $path;
23
24
    /**
25
     * Route Contents.
26
     *
27
     * @var string
28
     */
29
    private $routeContents;
30
31
    /**
32
     * Route template.
33
     *
34
     * @var string
35
     */
36
    private $routesTemplate;
37
38
    /**
39
     * Routes array.
40
     *
41
     * @var string
42
     */
43
    private $routes;
44
45
    /**
46
     * Clasess array.
47
     *
48
     * @var string
49
     */
50
    private $classes;
51
52
    /**
53
     * Classes array.
54
     *
55
     * @var string[]
56
     */
57
    private $classNames;
58
59
    /**
60
     * Constructor.
61
     *
62
     * @param CommandData $commandData Command data passed in from above.
63
     */
64
    public function __construct(CommandData $commandData)
65
    {
66
        $this->commandData = $commandData;
67
        $this->path = $commandData->config->pathRoutes;
68
    }
69
70
    /**
71
     * Prepare the routes array.
72
     *
73
     * @return void
74
     */
75
    public function prepareRoutes()
76
    {
77
        $fileName = $this->path.'.json';
78
79
        if (true === file_exists($fileName)) {
80
            // Routes json exists:
81
            $fileRoutes = file_get_contents($fileName);
82
            $fileRoutes = json_decode($fileRoutes, true);
83
        } else {
84
            $fileRoutes = [];
85
        }
86
87
        if (true === empty($this->commandData->config->prefixes['route'])) {
88
            $new = [
89
                'resources' => [$this->commandData->modelName => $this->commandData->modelName],
90
                'name'      => strtolower($this->commandData->modelName),
91
            ];
92
            $routes = [ucfirst($this->commandData->modelName) => $new];
93
        } else {
94
            $prefixes = explode('.', $this->commandData->config->prefixes['route']);
95
            $routes = [];
96
            foreach (array_reverse($prefixes) as $key => $prefix) {
97
                $new = [
98
                    'prefix' => $prefix,
99
                    'name'   => strtolower($prefix),
100
                ];
101
                if (0 === $key) {
102
                    $new['resources'] = [$this->commandData->modelName => $this->commandData->modelName];
103
                } else {
104
                    $new['group'] = $routes;
105
                }
106
                $routes = [ucfirst($prefix) => $new];
107
            }
108
        }
109
        $fileRoutes = array_replace_recursive($fileRoutes, $routes);
110
        file_put_contents($fileName, json_encode($fileRoutes, JSON_PRETTY_PRINT));
111
        $this->commandData->commandComment("\nRoute JSON File saved: ");
112
        $this->commandData->commandInfo($fileName);
113
        $this->routes = $this->buildText($fileRoutes);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $this->routes is correct as $this->buildText($fileRoutes) targeting PWWEB\Artomator\Generato...sGenerator::buildText() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Documentation Bug introduced by
It seems like $this->buildText($fileRoutes) of type void is incompatible with the declared type string of property $routes.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
114
        $this->classes = $this->buildClasses();
115
    }
116
117
    /**
118
     * Generator function.
119
     *
120
     * @return void
121
     */
122
    public function generate()
123
    {
124
        $this->prepareRoutes();
125
        $this->routeContents = file_get_contents($this->path);
126
        if (1 !== preg_match('/\/\/ Artomator Routes Start(.*)\/\/ Artomator Routes Stop/sU', $this->routeContents)) {
127
            $this->routeContents .= "\n\n// Artomator Routes Start\n// Artomator Routes Stop";
128
        }
129
130
        $this->routeContents = preg_replace(
131
            '/(\/\/ Artomator Routes Start)(.*)(\/\/ Artomator Routes Stop)/sU',
132
            "$1\n".$this->routes.'$3',
0 ignored issues
show
Bug introduced by
Are you sure $this->routes of type void can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

132
            "$1\n"./** @scrutinizer ignore-type */ $this->routes.'$3',
Loading history...
133
            $this->routeContents
134
        );
135
136
        if (1 !== preg_match(
137
            '/\/\/ Artomator Class References Start(.*)\/\/ Artomator Class References Stop/sU',
138
            $this->routeContents
139
        )) {
140
            $this->routeContents = preg_replace(
141
                '/(<\?php)/sU',
142
                "<?php\n\n// Artomator Routes Start\n// Artomator Routes Stop",
143
                $this->routeContents
144
            );
145
        }
146
147
        $this->routeContents = preg_replace(
148
            '/(\/\/ Artomator Class References Start)(.*)(\/\/ Artomator Class References Stop)/sU',
149
            "$1\n".$this->classes.'$3',
150
            $this->routeContents
151
        );
152
153
        file_put_contents($this->path, $this->routeContents);
154
        $this->commandData->commandComment("\n".$this->commandData->config->mCamelPlural.' routes added.');
155
    }
156
157
    /**
158
     * Re-generator the routes function.
159
     *
160
     * @return void
161
     */
162
    public function regenerate()
163
    {
164
        $fileName = $this->path.'.json';
165
166
        if (true === file_exists($fileName)) {
167
            // Routes json exists:
168
            $fileRoutes = file_get_contents($fileName);
169
            $fileRoutes = json_decode($fileRoutes, true);
170
        } else {
171
            $fileRoutes = [];
172
        }
173
        $this->routes = $this->buildText($fileRoutes);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->buildText($fileRoutes) of type void is incompatible with the declared type string of property $routes.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
Bug introduced by
Are you sure the assignment to $this->routes is correct as $this->buildText($fileRoutes) targeting PWWEB\Artomator\Generato...sGenerator::buildText() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
174
        $this->routeContents = file_get_contents($this->path);
175
        if (1 !== preg_match('/\/\/ Artomator Routes Start(.*)\/\/ Artomator Routes Stop/sU', $this->routeContents)) {
176
            $this->routeContents .= "\n\n// Artomator Routes Start\n// Artomator Routes Stop";
177
        }
178
179
        $this->routeContents = preg_replace(
180
            '/(\/\/ Artomator Routes Start)(.*)(\/\/ Artomator Routes Stop)/sU',
181
            "$1\n".$this->routes.'$3',
0 ignored issues
show
Bug introduced by
Are you sure $this->routes of type void can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

181
            "$1\n"./** @scrutinizer ignore-type */ $this->routes.'$3',
Loading history...
182
            $this->routeContents
183
        );
184
185
        if (1 !== preg_match(
186
            '/\/\/ Artomator Class References Start(.*)\/\/ Artomator Class References Stop/sU',
187
            $this->routeContents
188
        )) {
189
            $this->routeContents = preg_replace(
190
                '/(<\?php)/sU',
191
                "<?php\n\n// Artomator Routes Start\n// Artomator Routes Stop",
192
                $this->routeContents
193
            );
194
        }
195
196
        $this->routeContents = preg_replace(
197
            '/(\/\/ Artomator Class References Start)(.*)(\/\/ Artomator Class References Stop)/sU',
198
            "$1\n".$this->classes.'$3',
199
            $this->routeContents
200
        );
201
202
        file_put_contents($this->path, $this->routeContents);
203
        $this->commandData->commandComment("\nRoutes regenerated.");
204
    }
205
206
    /**
207
     * Rollback function.
208
     *
209
     * @return void
210
     */
211
    public function rollback()
212
    {
213
        if (true === Str::contains($this->routeContents, $this->routesTemplate)) {
214
            $this->routeContents = str_replace($this->routesTemplate, '', $this->routeContents);
215
            file_put_contents($this->path, $this->routeContents);
216
            $this->commandData->commandComment('scaffold routes deleted');
217
        }
218
    }
219
220
    /**
221
     * Template text builder function.
222
     *
223
     * @param array  $routes Routes array to process
224
     * @param int    $indent Indent counter
225
     * @param string $parent Parent prefix for fallback route
226
     *
227
     * @return void
228
     */
229
    private function buildText(array $routes, int $indent = 0, string $parent = '')
230
    {
231
        $templateContent = '';
232
        $fallback = '';
233
        foreach ($routes as $route_key => $route) {
234
            $templateString = '';
235
            $tabs = (true === isset($route['prefix'])) ? (($indent * 3) + 3) : 0;
236
            if (true === isset($route['custom'])) {
237
                foreach ($route['custom'] as $custom_key => $custom) {
238
                    if (true === isset($custom['function']) && '' !== $custom['function']) {
239
                        $custom['function'] = '@'.$custom['function'];
240
                    }
241
                    $vars = [
242
                        '$ITERATION_CUSTOM_METHOD$' => $custom['method'],
243
                        '$ITERATION_CUSTOM_ENDPOINT$' => $custom['endpoint'],
244
                        '$ITERATION_CUSTOM_CONTROLLER$' => $custom['controller'],
245
                        '$ITERATION_CUSTOM_FUNCTION$' => $custom['function'],
246
                        '$ITERATION_CUSTOM_NAME$' => $custom['name'],
247
                        '$INDENT$' => infy_tabs($tabs),
248
                    ];
249
                    $templateString .= get_artomator_template('scaffold.routes.prefixed.custom');
250
                    $templateString = fill_template($vars, $templateString);
251
                }
252
            }
253
            if (isset($route['resources'])) {
254
                $tabs = (isset($route['prefix'])) ? (($indent * 3) + 3) : 0;
255
                foreach ($route['resources'] as $resource_key => $only) {
256
                    if (null === $fallback) {
257
                        $fallback = $parent.'.'.$resource_key.'.index';
258
                    }
259
260
                    if (true === is_array($only)) {
261
                        $only = '->only([\''.implode('\', \'', $only).'\'])';
262
                    } else {
263
                        $only = '';
264
                    }
265
266
                    $className = $parent.'.'.$resource_key;
267
                    $className = explode('.', $className);
268
                    foreach ($className as &$path) {
269
                        $path = ucfirst($path);
270
                    }
271
                    $className = implode('/', $className);
272
273
                    $this->classNames[] = $className;
274
275
                    $vars = [
276
                        '$ITERATION_MODEL_NAME_PLURAL_CAMEL$' => Str::camel(Str::plural($resource_key)),
277
                        '$ITERATION_MODEL_NAME$'              => $resource_key,
278
                        '$ITERATION_ONLY$'                    => $only,
279
                        '$INDENT$'                            => infy_tabs($tabs),
280
                    ];
281
                    $templateString .= get_artomator_template('scaffold.routes.prefixed.route');
282
                    $templateString = fill_template($vars, $templateString);
283
                }
284
            }
285
            if (true === (isset($route['group']))) {
286
                if ('' !== $parent) {
287
                    $parent .= '.';
288
                }
289
                $parent .= (true === isset($route['prefix'])) ? $route['prefix'] : '';
290
                $templateString .= $this->buildText($route['group'], ($indent + 1), $parent);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->buildText($route[..., $indent + 1, $parent) targeting PWWEB\Artomator\Generato...sGenerator::buildText() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
291
            }
292
            if (true === (isset($route['prefix']))) {
293
                $vars = [
294
                    '$ITERATION_NAMESPACE_CAMEL$' => ucfirst($route_key),
295
                    '$ITERATION_NAMESPACE_LOWER$' => strtolower($route_key),
296
                    '$FALLBACK_ROUTE$'            => $fallback,
297
                    '$INDENT$'                    => infy_tabs($indent * 3),
298
                ];
299
                $templateString = get_artomator_template('scaffold.routes.prefixed.namespace')
300
                    .$templateString
301
                    .get_artomator_template('scaffold.routes.prefixed.fallback')
302
                    .get_artomator_template('scaffold.routes.prefixed.closure');
303
304
                $templateString = fill_template($vars, $templateString);
305
            }
306
            $templateContent .= $templateString;
307
        }
308
309
        return $templateContent;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $templateContent returns the type string which is incompatible with the documented return type void.
Loading history...
310
    }
311
312
    /**
313
     * Build the class names to be used in the refences.
314
     *
315
     * @return string The string of classnames in the form.
316
     */
317
    private function buildClasses()
318
    {
319
        $this->classNames = Arr::sort($this->classNames);
0 ignored issues
show
Bug introduced by
The type PWWEB\Artomator\Generators\Scaffold\Arr was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
320
321
        $classContent = '';
322
        foreach ($this->classNames as $key => $value) {
323
            $var = [
324
                '$ITERATION_NAMESPACE_CONTROLLER_NAME$' => $value,
325
            ];
326
327
            $classContent .= get_artomator_template('scaffold.routes.prefixed.reference');
328
329
            $classContent = fill_template($var, $classContent);
330
        }
331
332
        return $classContent;
333
    }
334
}
335