rawilk /
laravel-modules
| 1 | <?php |
||||||
| 2 | |||||||
| 3 | namespace Rawilk\LaravelModules\Generators; |
||||||
| 4 | |||||||
| 5 | use Illuminate\Console\Command as Console; |
||||||
| 6 | use Illuminate\Contracts\Config\Repository as Config; |
||||||
| 7 | use Illuminate\Filesystem\Filesystem; |
||||||
| 8 | use Illuminate\Support\Str; |
||||||
| 9 | use Rawilk\LaravelModules\Contracts\Activator; |
||||||
| 10 | use Rawilk\LaravelModules\FileRepository; |
||||||
| 11 | use Rawilk\LaravelModules\Support\Config\GenerateConfigReader; |
||||||
| 12 | use Rawilk\LaravelModules\Support\Stub; |
||||||
| 13 | |||||||
| 14 | class ModuleGenerator extends Generator |
||||||
| 15 | { |
||||||
| 16 | /** @var \Rawilk\LaravelModules\Contracts\Activator */ |
||||||
| 17 | protected $activator; |
||||||
| 18 | |||||||
| 19 | /** @var \Illuminate\Contracts\Config\Repository */ |
||||||
| 20 | protected $config; |
||||||
| 21 | |||||||
| 22 | /** @var \Illuminate\Console\Command */ |
||||||
| 23 | protected $console; |
||||||
| 24 | |||||||
| 25 | /** @var \Illuminate\Filesystem\Filesystem */ |
||||||
| 26 | protected $filesystem; |
||||||
| 27 | |||||||
| 28 | /** @var bool */ |
||||||
| 29 | protected $force = false; |
||||||
| 30 | |||||||
| 31 | /** @var bool */ |
||||||
| 32 | protected $isActive = false; |
||||||
| 33 | |||||||
| 34 | /** @var \Rawilk\LaravelModules\Module */ |
||||||
| 35 | protected $module; |
||||||
| 36 | |||||||
| 37 | /** @var string */ |
||||||
| 38 | protected $name; |
||||||
| 39 | |||||||
| 40 | /** @var bool */ |
||||||
| 41 | protected $plain = false; |
||||||
| 42 | |||||||
| 43 | /** |
||||||
| 44 | * @param string $name |
||||||
| 45 | * @param \Rawilk\LaravelModules\FileRepository|null $module |
||||||
| 46 | * @param \Illuminate\Contracts\Config\Repository|null $config |
||||||
| 47 | * @param \Illuminate\Filesystem\Filesystem|null $filesystem |
||||||
| 48 | * @param \Illuminate\Console\Command|null $console |
||||||
| 49 | * @param \Rawilk\LaravelModules\Contracts\Activator|null $activator |
||||||
| 50 | */ |
||||||
| 51 | public function __construct( |
||||||
| 52 | string $name, |
||||||
| 53 | FileRepository $module = null, |
||||||
| 54 | Config $config = null, |
||||||
| 55 | Filesystem $filesystem = null, |
||||||
| 56 | Console $console = null, |
||||||
| 57 | Activator $activator = null |
||||||
| 58 | ) |
||||||
| 59 | { |
||||||
| 60 | $this->name = $name; |
||||||
| 61 | $this->config = $config; |
||||||
| 62 | $this->filesystem = $filesystem; |
||||||
| 63 | $this->console = $console; |
||||||
| 64 | $this->module = $module; |
||||||
|
0 ignored issues
–
show
|
|||||||
| 65 | $this->activator = $activator; |
||||||
| 66 | } |
||||||
| 67 | |||||||
| 68 | public function generate(): void |
||||||
| 69 | { |
||||||
| 70 | $name = $this->getName(); |
||||||
| 71 | |||||||
| 72 | if ($this->module->has($name)) { |
||||||
|
0 ignored issues
–
show
The method
has() does not exist on Rawilk\LaravelModules\Module. Since you implemented __call, consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 73 | if ($this->force) { |
||||||
| 74 | $this->module->delete($name); |
||||||
|
0 ignored issues
–
show
The call to
Rawilk\LaravelModules\Module::delete() has too many arguments starting with $name.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above. Loading history...
|
|||||||
| 75 | } else { |
||||||
| 76 | $this->console->error("Module [{$name}] already exists!"); |
||||||
| 77 | |||||||
| 78 | return; |
||||||
| 79 | } |
||||||
| 80 | } |
||||||
| 81 | |||||||
| 82 | $this->generateFolders(); |
||||||
| 83 | |||||||
| 84 | $this->generateModuleJsonFile(); |
||||||
| 85 | |||||||
| 86 | if ($this->plain) { |
||||||
| 87 | $this->cleanModuleJsonFile(); |
||||||
| 88 | } else { |
||||||
| 89 | $this->generateFiles(); |
||||||
| 90 | $this->generateResources(); |
||||||
| 91 | } |
||||||
| 92 | |||||||
| 93 | $this->activator->setActiveByName($name, $this->isActive); |
||||||
| 94 | |||||||
| 95 | $this->console->info("Module [{$name}] was created successfully!"); |
||||||
| 96 | } |
||||||
| 97 | |||||||
| 98 | public function generateFiles(): void |
||||||
| 99 | { |
||||||
| 100 | foreach ($this->getFiles() as $stub => $file) { |
||||||
| 101 | $path = $this->module->getModulePath($this->getName()) . $file; |
||||||
|
0 ignored issues
–
show
The method
getModulePath() does not exist on Rawilk\LaravelModules\Module. Since you implemented __call, consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 102 | |||||||
| 103 | if (! $this->filesystem->isDirectory($dir = dirname($path))) { |
||||||
| 104 | $this->filesystem->makeDirectory($dir, 0775, true); |
||||||
| 105 | } |
||||||
| 106 | |||||||
| 107 | $this->filesystem->put($path, $this->getStubContents($stub)); |
||||||
| 108 | |||||||
| 109 | $this->console->info("Created: {$path}"); |
||||||
| 110 | } |
||||||
| 111 | } |
||||||
| 112 | |||||||
| 113 | public function generateFolders(): void |
||||||
| 114 | { |
||||||
| 115 | foreach ($this->getFolders() as $key => $folder) { |
||||||
| 116 | $folder = GenerateConfigReader::read($key); |
||||||
| 117 | |||||||
| 118 | if ($folder->generate() === false) { |
||||||
| 119 | continue; |
||||||
| 120 | } |
||||||
| 121 | |||||||
| 122 | $path = str_replace( |
||||||
| 123 | '//', |
||||||
| 124 | '/', |
||||||
| 125 | $this->module->getModulePath($this->getName()) . '/' . $folder->getPath() |
||||||
| 126 | ); |
||||||
| 127 | |||||||
| 128 | if (! $this->filesystem->isDirectory($path)) { |
||||||
| 129 | $this->filesystem->makeDirectory($path, 0755, true); |
||||||
| 130 | |||||||
| 131 | if (config('modules.stubs.gitkeep')) { |
||||||
| 132 | $this->generateGitKeep($path); |
||||||
| 133 | } |
||||||
| 134 | } |
||||||
| 135 | } |
||||||
| 136 | } |
||||||
| 137 | |||||||
| 138 | public function generateGitKeep(string $path): void |
||||||
| 139 | { |
||||||
| 140 | $this->filesystem->put("{$path}/.gitkeep", ''); |
||||||
| 141 | } |
||||||
| 142 | |||||||
| 143 | public function generateResources(): void |
||||||
| 144 | { |
||||||
| 145 | $this->console->call('module:make-seed', [ |
||||||
| 146 | 'name' => $this->getName(), |
||||||
| 147 | 'module' => $this->getName(), |
||||||
| 148 | '--master' => true |
||||||
| 149 | ]); |
||||||
| 150 | |||||||
| 151 | $this->console->call('module:make-provider', [ |
||||||
| 152 | 'name' => $this->getName() . 'ServiceProvider', |
||||||
| 153 | 'module' => $this->getName(), |
||||||
| 154 | '--master' => true |
||||||
| 155 | ]); |
||||||
| 156 | |||||||
| 157 | $this->console->call('module:route-provider', [ |
||||||
| 158 | 'module' => $this->getName() |
||||||
| 159 | ]); |
||||||
| 160 | } |
||||||
| 161 | |||||||
| 162 | public function getConfig(): Config |
||||||
| 163 | { |
||||||
| 164 | return $this->config; |
||||||
| 165 | } |
||||||
| 166 | |||||||
| 167 | public function getConsole(): Console |
||||||
| 168 | { |
||||||
| 169 | return $this->console; |
||||||
| 170 | } |
||||||
| 171 | |||||||
| 172 | public function getFiles(): array |
||||||
| 173 | { |
||||||
| 174 | return $this->module->config('stubs.files'); |
||||||
|
0 ignored issues
–
show
The method
config() does not exist on Rawilk\LaravelModules\Module. Since you implemented __call, consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 175 | } |
||||||
| 176 | |||||||
| 177 | public function getFilesystem(): Filesystem |
||||||
| 178 | { |
||||||
| 179 | return $this->filesystem; |
||||||
| 180 | } |
||||||
| 181 | |||||||
| 182 | public function getFolders(): array |
||||||
| 183 | { |
||||||
| 184 | return $this->module->config('paths.generator'); |
||||||
| 185 | } |
||||||
| 186 | |||||||
| 187 | public function getModule(): FileRepository |
||||||
| 188 | { |
||||||
| 189 | return $this->module; |
||||||
|
0 ignored issues
–
show
|
|||||||
| 190 | } |
||||||
| 191 | |||||||
| 192 | public function getName(): string |
||||||
| 193 | { |
||||||
| 194 | return Str::studly($this->name); |
||||||
| 195 | } |
||||||
| 196 | |||||||
| 197 | public function getReplacements(): array |
||||||
| 198 | { |
||||||
| 199 | return $this->module->config('stubs.replacements'); |
||||||
| 200 | } |
||||||
| 201 | |||||||
| 202 | public function setActivator(Activator $activator): self |
||||||
| 203 | { |
||||||
| 204 | $this->activator = $activator; |
||||||
| 205 | |||||||
| 206 | return $this; |
||||||
| 207 | } |
||||||
| 208 | |||||||
| 209 | public function setActive(bool $active): self |
||||||
| 210 | { |
||||||
| 211 | $this->isActive = $active; |
||||||
| 212 | |||||||
| 213 | return $this; |
||||||
| 214 | } |
||||||
| 215 | |||||||
| 216 | public function setConfig(Config $config): self |
||||||
| 217 | { |
||||||
| 218 | $this->config = $config; |
||||||
| 219 | |||||||
| 220 | return $this; |
||||||
| 221 | } |
||||||
| 222 | |||||||
| 223 | public function setConsole(Console $console): self |
||||||
| 224 | { |
||||||
| 225 | $this->console = $console; |
||||||
| 226 | |||||||
| 227 | return $this; |
||||||
| 228 | } |
||||||
| 229 | |||||||
| 230 | public function setForce(bool $force): self |
||||||
| 231 | { |
||||||
| 232 | $this->force = $force; |
||||||
| 233 | |||||||
| 234 | return $this; |
||||||
| 235 | } |
||||||
| 236 | |||||||
| 237 | public function setPlain(bool $plain): self |
||||||
| 238 | { |
||||||
| 239 | $this->plain = $plain; |
||||||
| 240 | |||||||
| 241 | return $this; |
||||||
| 242 | } |
||||||
| 243 | |||||||
| 244 | public function setFilesystem(Filesystem $filesystem): self |
||||||
| 245 | { |
||||||
| 246 | $this->filesystem = $filesystem; |
||||||
| 247 | |||||||
| 248 | return $this; |
||||||
| 249 | } |
||||||
| 250 | |||||||
| 251 | public function setModule(FileRepository $module): self |
||||||
| 252 | { |
||||||
| 253 | $this->module = $module; |
||||||
|
0 ignored issues
–
show
It seems like
$module of type Rawilk\LaravelModules\FileRepository is incompatible with the declared type Rawilk\LaravelModules\Module of property $module.
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...
|
|||||||
| 254 | |||||||
| 255 | return $this; |
||||||
| 256 | } |
||||||
| 257 | |||||||
| 258 | protected function getAuthorEmailReplacement(): string |
||||||
| 259 | { |
||||||
| 260 | return $this->module->config('composer.author.email'); |
||||||
| 261 | } |
||||||
| 262 | |||||||
| 263 | protected function getAuthorNameReplacement(): string |
||||||
| 264 | { |
||||||
| 265 | return $this->module->config('composer.author.name'); |
||||||
| 266 | } |
||||||
| 267 | |||||||
| 268 | protected function getLowerNameReplacement(): string |
||||||
| 269 | { |
||||||
| 270 | return strtolower($this->getName()); |
||||||
| 271 | } |
||||||
| 272 | |||||||
| 273 | protected function getModuleNamespaceReplacement(): string |
||||||
| 274 | { |
||||||
| 275 | return str_replace('\\', '\\\\', $this->module->config('namespace')); |
||||||
| 276 | } |
||||||
| 277 | |||||||
| 278 | protected function getReplacement(string $stub): array |
||||||
| 279 | { |
||||||
| 280 | $replacements = $this->getReplacements(); |
||||||
| 281 | |||||||
| 282 | if (! isset($replacements[$stub])) { |
||||||
| 283 | return []; |
||||||
| 284 | } |
||||||
| 285 | |||||||
| 286 | $keys = $replacements[$stub]; |
||||||
| 287 | |||||||
| 288 | $replaces = []; |
||||||
| 289 | |||||||
| 290 | foreach ($keys as $key) { |
||||||
| 291 | if (method_exists($this, $method = 'get' . ucfirst(Str::studly(strtolower($key))) . 'Replacement')) { |
||||||
| 292 | $replaces[$key] = $this->$method(); |
||||||
| 293 | } else { |
||||||
| 294 | $replaces[$key] = null; |
||||||
| 295 | } |
||||||
| 296 | } |
||||||
| 297 | |||||||
| 298 | return $replaces; |
||||||
| 299 | } |
||||||
| 300 | |||||||
| 301 | protected function getStubContents(string $stub): string |
||||||
| 302 | { |
||||||
| 303 | return (new Stub( |
||||||
| 304 | "/{$stub}.stub", |
||||||
| 305 | $this->getReplacement($stub) |
||||||
| 306 | ))->render(); |
||||||
| 307 | } |
||||||
| 308 | |||||||
| 309 | protected function getStudlyNameReplacement(): string |
||||||
| 310 | { |
||||||
| 311 | return $this->getName(); |
||||||
| 312 | } |
||||||
| 313 | |||||||
| 314 | protected function getVendorReplacement(): string |
||||||
| 315 | { |
||||||
| 316 | return $this->module->config('composer.vendor'); |
||||||
| 317 | } |
||||||
| 318 | |||||||
| 319 | /** |
||||||
| 320 | * Remove the default service provider that was added in the module.json file. |
||||||
| 321 | * This is needed when a --plain module is created. |
||||||
| 322 | */ |
||||||
| 323 | private function cleanModuleJsonFile(): void |
||||||
| 324 | { |
||||||
| 325 | $path = $this->module->getModulePath($this->getName()) . 'module.json'; |
||||||
| 326 | |||||||
| 327 | $content = $this->filesystem->get($path); |
||||||
| 328 | $namespace = $this->getModuleNamespaceReplacement(); |
||||||
| 329 | $studlyName = $this->getStudlyNameReplacement(); |
||||||
| 330 | |||||||
| 331 | $provider = '"' . $namespace . '\\\\' . $studlyName . '\\\\Providers\\\\' . $studlyName . 'ServiceProvider"'; |
||||||
| 332 | |||||||
| 333 | $content = str_replace($provider, '', $content); |
||||||
| 334 | |||||||
| 335 | $this->filesystem->put($path, $content); |
||||||
| 336 | } |
||||||
| 337 | |||||||
| 338 | private function generateModuleJsonFile(): void |
||||||
| 339 | { |
||||||
| 340 | $path = $this->module->getModulePath($this->getName()) . 'module.json'; |
||||||
| 341 | |||||||
| 342 | if (! $this->filesystem->isDirectory($dir = dirname($path))) { |
||||||
| 343 | $this->filesystem->makeDirectory($dir, 0775, true); |
||||||
| 344 | } |
||||||
| 345 | |||||||
| 346 | $this->filesystem->put($path, $this->getStubContents('json')); |
||||||
| 347 | |||||||
| 348 | $this->console->info("Created: {$path}"); |
||||||
| 349 | } |
||||||
| 350 | } |
||||||
| 351 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountIdthat can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theidproperty of an instance of theAccountclass. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.