Completed
Push — master ( 7f011d...511c4e )
by recca
04:58
created

Generator::setFullRepositoryInterface()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1.125

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 3
cts 6
cp 0.5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 6
nc 1
nop 1
crap 1.125
1
<?php
2
3
namespace Recca0120\Generator;
4
5
use Illuminate\Support\Arr;
6
use Illuminate\Support\Str;
7
use Illuminate\Filesystem\Filesystem;
8
use Recca0120\Generator\Fixers\UseSortFixer;
9
10
class Generator
11
{
12
    /**
13
     * $filesystem.
14
     *
15
     * @var \Illuminate\Filesystem\Filesystem
16
     */
17
    protected $filesystem;
18
19
    /**
20
     * $useSortFixer.
21
     *
22
     * @var \Recca0120\Generator\Fixers\UseSortFixer
23
     */
24
    protected $useSortFixer;
25
26
    /**
27
     * $attributes.
28
     *
29
     * @var array
30
     */
31
    protected $attributes = [];
32
33
    /**
34
     * __construct.
35
     *
36
     * @param \Illuminate\Filesystem\Filesystem $filesystem   [description]
37
     * @param \Recca0120\Generator\Fixers\UseSortFixers $useSortFixer [description]
38
     */
39 9
    public function __construct(Filesystem $filesystem = null, UseSortFixer $useSortFixer = null)
40
    {
41 9
        $this->filesystem = $filesystem ?: new Filesystem();
42 9
        $this->useSortFixer = $useSortFixer ?: new UseSortFixer();
43 9
        $this->useSortFixer->setSortType(UseSortFixer::SORT_TYPE_LENGTH);
44 9
    }
45
46
    /**
47
     * parseAttribute.
48
     *
49
     * @param string $value
50
     * @return array
51
     */
52 9
    protected function parseAttribute($value)
53
    {
54 9
        $alias = array_map('trim', explode(' as ', $value));
55 9
        $className = $alias[0];
56
57 9
        $dummyClass = class_basename(isset($alias[1]) === true ? $alias[1] : $className);
58 9
        $dummyNamespace = $this->getNamespace($className);
59
60
        $dummyModelVariable = Str::camel(Str::singular(
61
            preg_replace('/(Controller|Repository)$/', '', $dummyClass)
62
        ));
63
64
        $dummyCollectionVariable = Str::plural($dummyModelVariable);
65
        $dummyCollectionVariable = $dummyCollectionVariable === $dummyModelVariable ?
66
            $dummyModelVariable.'Collection' : $dummyCollectionVariable;
67
68
        $dummyRepositoryVariable = $dummyCollectionVariable;
69
70
        $dummyView = Str::snake(Str::plural($dummyModelVariable));
71
        $dummyRoute = Str::snake(Str::plural($dummyModelVariable));
72
73
        return compact(
74
            'dummyNamespace',
75
            'dummyClass',
76
            'dummyRepositoryVariable',
77
            'dummyCollectionVariable',
78
            'dummyModelVariable',
79
            'dummyView',
80
            'dummyRoute'
81
        );
82
    }
83
84
    /**
85
     * setFullBaseClass.
86
     *
87
     * @param string $value
88
     * @return static
89
     */
90
    public function setFullBaseClass($value)
91
    {
92
        $this->set('DummyFullBaseClass', $value);
93
94
        extract($this->parseAttribute($value));
0 ignored issues
show
Bug introduced by
$this->parseAttribute($value) cannot be passed to extract() as the parameter $var_array expects a reference.
Loading history...
95
96
        $this->set('DummyBaseClass', $dummyClass);
97
        if ($this->get('DummyNamespace') === $this->getNamespace($value)) {
98
            $this->remove('DummyFullBaseClass');
99
        }
100
101
        return $this;
102
    }
103
104
    /**
105
     * setFullRepositoryInterface.
106
     *
107
     * @param string $value
108
     * @return static
109
     */
110 1
    public function setFullRepositoryInterface($value)
111
    {
112 1
        $this->set('DummyFullRepositoryInterface', $value);
113
114 1
        extract($this->parseAttribute($value));
0 ignored issues
show
Bug introduced by
$this->parseAttribute($value) cannot be passed to extract() as the parameter $var_array expects a reference.
Loading history...
115
116
        return $this->setDefault('DummyNamespace', $dummyNamespace)
117
            ->setDefault('DummyClass', $dummyClass)
118
            ->setDefault('DummyRepositoryInterface', $dummyClass);
119
    }
120
121
    /**
122
     * setFullRepositoryClass.
123
     *
124
     * @param string $value
125
     * @return static
126
     */
127 3
    public function setFullRepositoryClass($value)
128
    {
129 3
        $this->set('DummyFullRepositoryClass', $value);
130
131 3
        extract($this->parseAttribute($value));
0 ignored issues
show
Bug introduced by
$this->parseAttribute($value) cannot be passed to extract() as the parameter $var_array expects a reference.
Loading history...
132
133
        return $this->setDefault('DummyNamespace', $dummyNamespace)
134
            ->setDefault('DummyClass', $dummyClass)
135
            ->setDefault('DummyFullRepositoryInterface', $dummyNamespace.'\Contracts\\'.$dummyClass)
136
            ->set('DummyRepositoryClass', $dummyClass);
137
    }
138
139
    /**
140
     * setFullModelClass.
141
     *
142
     * @param string $value
143
     * @return static
144
     */
145 1
    public function setFullModelClass($value)
146
    {
147 1
        $this->set('DummyFullModelClass', $value);
148
149 1
        extract($this->parseAttribute($value));
0 ignored issues
show
Bug introduced by
$this->parseAttribute($value) cannot be passed to extract() as the parameter $var_array expects a reference.
Loading history...
150
151
        return $this->setDefault('DummyNamespace', $dummyNamespace)
152
            ->setDefault('DummyClass', $dummyClass)
153
            ->setDefault('DummyModelVariable', $dummyModelVariable)
154
            ->setDefault('DummyFullPresenterClass', $dummyNamespace.'\Presenters\\'.$dummyClass.'Presenter')
155
            ->setDefault('DummyPresenterClass', $dummyClass.'Presenter')
156
            ->set('DummyModelClass', $dummyClass);
157
    }
158
159
    /**
160
     * setFullPresenterClass.
161
     *
162
     * @param string $value
163
     * @return static
164
     */
165 1
    public function setFullPresenterClass($value)
166
    {
167 1
        $this->set('DummyFullPresenterClass', $value);
168
169 1
        extract($this->parseAttribute($value));
0 ignored issues
show
Bug introduced by
$this->parseAttribute($value) cannot be passed to extract() as the parameter $var_array expects a reference.
Loading history...
170
171
        return $this->setDefault('DummyNamespace', $dummyNamespace)
172
            ->setDefault('DummyClass', $dummyClass)
173
            ->set('DummyPresenterClass', $dummyClass);
174
    }
175
176
    /**
177
     * setFullRequestClass.
178
     *
179
     * @param string $value
180
     * @return static
181
     */
182 1
    public function setFullRequestClass($value)
183
    {
184 1
        $this->set('DummyFullRequestClass', $value);
185
186 1
        extract($this->parseAttribute($value));
0 ignored issues
show
Bug introduced by
$this->parseAttribute($value) cannot be passed to extract() as the parameter $var_array expects a reference.
Loading history...
187
188
        return $this->setDefault('DummyNamespace', $dummyNamespace)
189
            ->setDefault('DummyClass', $dummyClass)
190
            ->set('DummyRequestClass', $dummyClass);
191
    }
192
193
    /**
194
     * setFullControllerClass.
195
     *
196
     * @param string $value
197
     * @return static
198
     */
199 2
    public function setFullControllerClass($value)
200
    {
201 2
        $this->set('DummyFullControllerClass', $value);
202
203 2
        extract($this->parseAttribute($value));
0 ignored issues
show
Bug introduced by
$this->parseAttribute($value) cannot be passed to extract() as the parameter $var_array expects a reference.
Loading history...
204
205
        return $this->setDefault('DummyNamespace', $dummyNamespace)
206
            ->setDefault('DummyClass', $dummyClass)
207
            ->setDefault('DummyRepositoryVariable', $dummyRepositoryVariable)
208
            ->setDefault('DummyCollectionVariable', $dummyCollectionVariable)
209
            ->setDefault('DummyModelVariable', $dummyModelVariable)
210
            ->setDefault('DummyView', $dummyView)
211
            ->setDefault('DummyRoute', $dummyRoute)
212
            ->set('DummyControllerClass', $dummyClass);
213
    }
214
215
    /**
216
     * set.
217
     *
218
     * @param string $value
219
     * @return static
220
     */
221 9
    public function set($key, $value)
222
    {
223 9
        $this->attributes[$key] = $value;
224
225 9
        return $this;
226
    }
227
228
    /**
229
     * setDefault.
230
     *
231
     * @param string $value
232
     * @return static
233
     */
234
    protected function setDefault($key, $value)
235
    {
236
        if (isset($this->attributes[$key]) === false) {
237
            $this->attributes[$key] = $value;
238
        }
239
240
        return $this;
241
    }
242
243
    /**
244
     * get.
245
     *
246
     * @param string $value
0 ignored issues
show
Bug introduced by
There is no parameter named $value. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
247
     * @return string
248
     */
249
    public function get($key)
250
    {
251
        return Arr::get($this->attributes, $key);
252
    }
253
254
    /**
255
     * remove.
256
     *
257
     * @param string $key
258
     * @return bool
259
     */
260
    public function remove($key)
261
    {
262
        return Arr::forget($this->attributes, $key);
263
    }
264
265
    /**
266
     * render.
267
     *
268
     * @param string $stub
269
     * @param bool $orderedUses
270
     * @return string
271
     */
272
    public function render($stub, $orderedUses = true)
273
    {
274
        $content = strtr(strtr(strtr($this->filesystem->get($stub), $this->attributes), ["\r\n" => "\n"]), [
275
            ' extends DummyBaseClass' => '',
276
            'use DummyFullBaseClass;' => '',
277
        ]);
278
279
        return $orderedUses === true ? $this->orderedUses($content) : $content;
280
    }
281
282
    /**
283
     * renderServiceProvider.
284
     *
285
     * @param string $content
286
     * @return string
287
     */
288
    public function renderServiceProvider($content)
289
    {
290
        if (strpos($content, '$this->registerRepositories') === false) {
291
            $content = preg_replace_callback('/public function register\(.+\n\s+{/', function ($m) {
292
                return $m[0]."\n".
293
                    str_repeat(' ', 8).
294
                    '$this->registerRepositories();';
295
            }, $content);
296
        }
297
298
        if (strpos($content, 'protected function registerRepositories()') === false) {
299
            $content = substr($content, 0, strrpos($content, '}')).
300
                "\n".str_repeat(' ', 4).
301
                'protected function registerRepositories()'.
302
                "\n".str_repeat(' ', 4).'{'.
303
                "\n".str_repeat(' ', 4).'}'.
304
                "\n}\n";
305
        }
306
307 View Code Duplication
        if (strpos($content, sprintf('use %s;', $this->get('DummyFullRepositoryClass'))) === false) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
308
            $content = preg_replace_callback(
309
                '/namespace.+/',
310
                [$this, 'replaceServieProviderCallback'],
311
                $content
312
            );
313
        }
314
315 View Code Duplication
        if (strpos($content, sprintf('$this->app->singleton(%sContract::class, %s::class);', $this->get('DummyClass'), $this->get('DummyClass'))) === false) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
316
            $content = preg_replace_callback(
317
                '/protected function registerRepositories.+\n\s+{/',
318
                [$this, 'replaceServieProviderCallback'],
319
                $content
320
            );
321
        }
322
323
        return $this->orderedUses($content);
324
    }
325
326
    /**
327
     * replaceServieProviderCallback.
328
     *
329
     * @param  array $match
330
     * @return string
331
     */
332
    protected function replaceServieProviderCallback($match)
333
    {
334
        $fullRepositoryClass = $this->get('DummyFullRepositoryClass');
335
        $fullRepositoryInterface = $this->get('DummyFullRepositoryInterface');
336
        $dummyClass = $this->get('DummyClass');
337
338
        if (Str::startsWith($match[0], 'namespace') === true) {
339
            return $match[0]."\n\n".
340
                sprintf("use %s as %sContract;\n", $fullRepositoryInterface, $dummyClass).
341
                sprintf("use %s;\n", $fullRepositoryClass);
342
        } else {
343
            return $match[0]."\n".
344
                str_repeat(' ', 8).
345
                sprintf('$this->app->singleton(%sContract::class, %s::class);', $dummyClass, $dummyClass);
346
        }
347
    }
348
349
    /**
350
     * getNamespace.
351
     *
352
     * @param string $name [description]
353
     * @return string
354
     */
355 9
    protected function getNamespace($name)
356
    {
357 9
        return rtrim(preg_replace('/'.$baseClass.'$/', '', class_basename($name)), '\\');
0 ignored issues
show
Bug introduced by
The variable $baseClass does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
358
    }
359
360
361
    /**
362
     * orderedUses.
363
     *
364
     * @param string $content
365
     * @return string
366
     */
367
    protected function orderedUses($content)
368
    {
369
        $fix = $this->useSortFixer->fix($content);
370
371
        return $fix === false ? $content : strtr($fix, ["\r\n" => "\n"]);
372
    }
373
}
374