GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Generator::run()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 3
Ratio 25 %

Importance

Changes 0
Metric Value
cc 4
eloc 7
nc 3
nop 0
dl 3
loc 12
rs 9.2
c 0
b 0
f 0
1
<?php
2
3
namespace Milkmeowo\Framework\Repository\Generators;
4
5
use Illuminate\Support\Str;
6
use Illuminate\Filesystem\Filesystem;
7
use Milkmeowo\Framework\Repository\Generators\Exceptions\FileAlreadyExistsException;
8
9
abstract class Generator
10
{
11
    /**
12
     * The filesystem instance.
13
     *
14
     * @var \Illuminate\Filesystem\Filesystem
15
     */
16
    protected $filesystem;
17
18
    /**
19
     * The array of options.
20
     *
21
     * @var array
22
     */
23
    protected $options;
24
25
    /**
26
     * The shortname of stub.
27
     *
28
     * @var string
29
     */
30
    protected $stub;
31
32
    /**
33
     * Create new instance of this class.
34
     *
35
     * @param array $options
36
     */
37
    public function __construct(array $options = [])
38
    {
39
        $this->filesystem = new Filesystem;
40
        $this->options = $options;
41
    }
42
43
    /**
44
     * Get the filesystem instance.
45
     *
46
     * @return \Illuminate\Filesystem\Filesystem
47
     */
48
    public function getFilesystem()
49
    {
50
        return $this->filesystem;
51
    }
52
53
    /**
54
     * Set the filesystem instance.
55
     *
56
     * @param \Illuminate\Filesystem\Filesystem $filesystem
57
     *
58
     * @return $this
59
     */
60
    public function setFilesystem(Filesystem $filesystem)
61
    {
62
        $this->filesystem = $filesystem;
63
64
        return $this;
65
    }
66
67
    /**
68
     * Get stub template for generated file.
69
     *
70
     * @return string
71
     */
72
    public function getStub()
73
    {
74
        $path = config('repository.generator.stubsOverridePath', __DIR__);
75
76
        if (! file_exists($path.'/Stubs/'.$this->stub.'.stub')) {
77
            $path = __DIR__;
78
        }
79
80
        return (new Stub($path.'/Stubs/'.$this->stub.'.stub', $this->getReplacements()))->render();
81
    }
82
83
    /**
84
     * Get template replacements.
85
     *
86
     * @return array
87
     */
88
    public function getReplacements()
89
    {
90
        return [
91
            'class'          => $this->getClass(),
92
            'namespace'      => $this->getNamespace(),
93
            'root_namespace' => $this->getRootNamespace(),
94
        ];
95
    }
96
97
    /**
98
     * Get base path of destination file.
99
     *
100
     * @return string
101
     */
102
    public function getBasePath()
103
    {
104
        return base_path();
105
    }
106
107
    /**
108
     * Get destination path for generated file.
109
     *
110
     * @return string
111
     */
112
    public function getPath()
113
    {
114
        return $this->getBasePath().'/'.$this->getName().'.php';
115
    }
116
117
    /**
118
     * Get name input.
119
     *
120
     * @return string
121
     */
122
    public function getName()
123
    {
124
        $name = $this->name;
0 ignored issues
show
Bug introduced by
The property name does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
125
        if (str_contains($this->name, '\\')) {
126
            $name = str_replace('\\', '/', $this->name);
127
        }
128
        if (str_contains($this->name, '/')) {
129
            $name = str_replace('/', '/', $this->name);
130
        }
131
132
        return Str::studly(str_replace(' ', '/', ucwords(str_replace('/', ' ', $name))));
133
    }
134
135
    /**
136
     * Get application namespace.
137
     *
138
     * @return string
139
     */
140
    public function getAppNamespace()
141
    {
142
        return \Illuminate\Container\Container::getInstance()->getNamespace();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Illuminate\Container\Container as the method getNamespace() does only exist in the following sub-classes of Illuminate\Container\Container: Illuminate\Foundation\Application, Laravel\Lumen\Application. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
143
    }
144
145
    /**
146
     * Get class name.
147
     *
148
     * @return string
149
     */
150
    public function getClass()
151
    {
152
        return Str::studly(class_basename($this->getName()));
153
    }
154
155
    /**
156
     * Get paths of namespace.
157
     *
158
     * @return array
159
     */
160
    public function getSegments()
161
    {
162
        return explode('/', $this->getName());
163
    }
164
165
    /**
166
     * Get root namespace.
167
     *
168
     * @return string
169
     */
170
    public function getRootNamespace()
171
    {
172
        return config('repository.generator.rootNamespace', $this->getAppNamespace());
173
    }
174
175
    /**
176
     * Get class-specific output paths.
177
     *
178
     * @param string $class
179
     *
180
     * @return string
181
     */
182
    public function getConfigGeneratorClassPath($class, $directoryPath = false)
183
    {
184
        switch ($class) {
185
            case 'models' === $class:
186
                $path = config('repository.generator.paths.models', 'Entities');
187
                break;
188
            case 'repositories' === $class:
189
                $path = config('repository.generator.paths.repositories', 'Repositories');
190
                break;
191
            case 'interfaces' === $class:
192
                $path = config('repository.generator.paths.interfaces', 'Repositories');
193
                break;
194
            case 'presenters' === $class:
195
                $path = config('repository.generator.paths.presenters', 'Presenters');
196
                break;
197
            case 'transformers' === $class:
198
                $path = config('repository.generator.paths.transformers', 'Transformers');
199
                break;
200
            case 'validators' === $class:
201
                $path = config('repository.generator.paths.validators', 'Validators');
202
                break;
203
            case 'controllers' === $class:
204
                $path = config('repository.generator.paths.controllers', 'Http\Controllers');
205
                break;
206
            case 'provider' === $class:
207
                $path = config('repository.generator.paths.provider', 'RepositoryServiceProvider');
208
                break;
209
            case 'routes.web' === $class:
210
                $path = config('repository.generator.paths.routes.web', 'web');
211
                break;
212
            case 'routes.api' === $class:
213
                $path = config('repository.generator.paths.routes.api', 'api');
214
                break;
215
            case 'criteria' === $class:
216
                $path = config('repository.generator.paths.criteria', 'Criteria');
217
                break;
218
            default:
219
                $path = '';
220
        }
221
222
        if ($directoryPath) {
223
            $path = str_replace('\\', '/', $path);
224
        } else {
225
            $path = str_replace('/', '\\', $path);
226
        }
227
228
        return $path;
229
    }
230
231
    abstract public function getPathConfigNode();
232
233
    /**
234
     * Get class namespace.
235
     *
236
     * @return string
237
     */
238
    public function getNamespace()
239
    {
240
        $segments = $this->getSegments();
241
        array_pop($segments);
242
        $rootNamespace = $this->getRootNamespace();
243
        if ($rootNamespace == false) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $rootNamespace of type string to the boolean false. If you are specifically checking for an empty string, consider using the more explicit === '' instead.
Loading history...
244
            return;
245
        }
246
247
        return 'namespace '.rtrim($rootNamespace.'\\'.implode($segments, '\\'), '\\').';';
248
    }
249
250
    /**
251
     * Setup some hook.
252
     *
253
     * @return void
254
     */
255
    public function setUp()
256
    {
257
        //
258
    }
259
260
    /**
261
     * Run the generator.
262
     *
263
     * @return int
264
     * @throws FileAlreadyExistsException
265
     */
266
    public function run()
267
    {
268
        $this->setUp();
269
        if ($this->filesystem->exists($path = $this->getPath()) && ! $this->force) {
0 ignored issues
show
Documentation introduced by
The property force does not exist on object<Milkmeowo\Framewo...y\Generators\Generator>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
270
            throw new FileAlreadyExistsException($path);
271
        }
272 View Code Duplication
        if (! $this->filesystem->isDirectory($dir = dirname($path))) {
0 ignored issues
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...
273
            $this->filesystem->makeDirectory($dir, 0777, true, true);
274
        }
275
276
        return $this->filesystem->put($path, $this->getStub());
277
    }
278
279
    /**
280
     * Get options.
281
     *
282
     * @return string
283
     */
284
    public function getOptions()
285
    {
286
        return $this->options;
287
    }
288
289
    /**
290
     * Determinte whether the given key exist in options array.
291
     *
292
     * @param  string $key
293
     *
294
     * @return bool
295
     */
296
    public function hasOption($key)
297
    {
298
        return array_key_exists($key, $this->options);
299
    }
300
301
    /**
302
     * Get value from options by given key.
303
     *
304
     * @param  string      $key
305
     * @param  string|null $default
306
     *
307
     * @return string
308
     */
309
    public function getOption($key, $default = null)
310
    {
311
        if (! $this->hasOption($key)) {
312
            return $default;
313
        }
314
315
        return $this->options[$key] ?: $default;
316
    }
317
318
    /**
319
     * Helper method for "getOption".
320
     *
321
     * @param  string      $key
322
     * @param  string|null $default
323
     *
324
     * @return string
325
     */
326
    public function option($key, $default = null)
327
    {
328
        return $this->getOption($key, $default);
329
    }
330
331
    /**
332
     * Handle call to __get method.
333
     *
334
     * @param  string $key
335
     *
336
     * @return string|mixed
337
     */
338
    public function __get($key)
339
    {
340
        if (property_exists($this, $key)) {
341
            return $this->{$key};
342
        }
343
344
        return $this->option($key);
345
    }
346
}
347