Completed
Pull Request — master (#1150)
by
unknown
01:41
created

LivewireCommand   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 223
Duplicated Lines 18.39 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
dl 41
loc 223
rs 10
c 0
b 0
f 0
wmc 28
lcom 1
cbo 7

12 Methods

Rating   Name   Duplication   Size   Complexity  
B handle() 0 34 8
A getArguments() 0 7 1
A getOptions() 8 8 1
A getComponent() 0 17 1
A getClassInfo() 0 26 2
A getViewInfo() 0 22 2
A createClass() 16 16 3
A classContents() 0 11 2
A createView() 17 17 4
A viewContents() 0 4 1
A ensureDirectoryExists() 0 6 2
A isReservedClassName() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace Nwidart\Modules\Commands;
4
5
use Illuminate\Support\Str;
6
use Illuminate\Console\Command;
7
use Illuminate\Support\Facades\File;
8
use Nwidart\Modules\Support\Stub;
9
use Nwidart\Modules\Traits\ModuleCommandTrait;
10
use Nwidart\Modules\Support\Config\GenerateConfigReader;
11
use Symfony\Component\Console\Input\InputOption;
12
use Symfony\Component\Console\Input\InputArgument;
13
14
class LivewireCommand extends Command
15
{
16
    use ModuleCommandTrait;
17
18
    public $component;
19
20
    public $module;
21
22
    public $directories;
23
24
    /**
25
     * The console command name.
26
     *
27
     * @var string
28
     */
29
    protected $name = 'module:make-livewire';
30
31
    /**
32
     * The console command description.
33
     *
34
     * @var string
35
     */
36
    protected $description = 'Generate Livewire Component.';
37
38
    /**
39
     * Execute the console command.
40
     *
41
     * @return int
42
     */
43
    public function handle()
44
    {
45
        if (! class_exists('Livewire')) {
46
            $this->line("\n<options=bold,reverse;fg=red> WHOOPS! </> 😳 \n");
47
            $this->line("<fg=red;options=bold>Livewire not found!</> \n");
48
            $this->line("<fg=green;options=bold>Install The Livewire Package - composer require livewire/livewire</> \n");
49
            return 0;
50
        }
51
52
        $this->component = $this->getComponent();
53
54
        if ($this->isReservedClassName($name = $this->component->class->name)) {
55
            $this->line("\n<options=bold,reverse;fg=red> WHOOPS! </> 😳 \n");
56
            $this->line("<fg=red;options=bold>Class is reserved:</> {$name} \n");
57
            return 0;
58
        }
59
60
        $force = $this->option('force');
61
        $inline = $this->option('inline');
62
63
        $class = $this->createClass($force, $inline);
64
        $view = $this->createView($force, $inline);
65
66
        if ($class || $view) {
67
            $this->line("\n <options=bold,reverse;fg=green> COMPONENT CREATED </> 🤙\n");
68
            $class && $this->line("<options=bold;fg=green>CLASS:</> {$this->component->class->path}");
69
70
            if (! $inline) {
71
                $view && $this->line("<options=bold;fg=green>VIEW:</>  {$this->component->view->path}");
72
            }
73
        }
74
75
        return 0;
76
    }
77
78
    /**
79
     * Get the console command arguments.
80
     *
81
     * @return array
82
     */
83
    protected function getArguments()
84
    {
85
        return [
86
            ['module', InputArgument::REQUIRED, 'The name of module will be used.'],
87
            ['name', InputArgument::REQUIRED, 'The name of the component.'],
88
        ];
89
    }
90
91
    /**
92
     * Get the console command options.
93
     *
94
     * @return array
95
     */
96 View Code Duplication
    protected function getOptions()
97
    {
98
        return [
99
            ['view', null, InputOption::VALUE_OPTIONAL, 'Set custom view path for Component.'],
100
            ['force', false, InputOption::VALUE_NONE, 'Force create component if the class already exists.'],
101
            ['inline', false, InputOption::VALUE_NONE, 'Create inline component.'],
102
        ];
103
    }
104
105
    protected function getComponent()
106
    {
107
        $module = $this->laravel['modules']->findOrFail($this->getModuleName());
108
        
109
        $this->module = $module;
110
        
111
        $this->directories = preg_split('/[.\/(\\\\)]+/', $this->argument('name'));
112
        
113
        $classInfo = $this->getClassInfo();
114
        
115
        $viewInfo = $this->getViewInfo();
116
117
        return (object) [
118
            'class' => $classInfo,
119
            'view' => $viewInfo
120
        ];
121
    }
122
123
    public function getClassInfo()
124
    {
125
        $modulePath = $this->module->getPath().'/';
126
127
        $defaultNamespace = GenerateConfigReader::read('livewire-namespace')->getPath();
128
129
        $classDir = $modulePath . strtr($defaultNamespace, ['\\' => '/']);
130
131
        $path = collect($this->directories)
132
            ->map([\Str::class, 'studly'])
133
            ->implode('/');
134
135
        $beforeLast = (\Str::contains($path, '/')) ? '/' . \Str::beforeLast($path, '/') : '';
136
137
        $namespace = config('modules.namespace') . '\\' . $this->module->getName() . '\\' . $defaultNamespace . strtr($beforeLast, ['/' => '\\']);
138
139
        $name = \Str::studly( \Arr::last($this->directories) );
140
141
        return (object) [
142
            'dir' => $classDir,
143
            'path' => $path,
144
            'file' => $classDir . '/' . $path . '.php',
145
            'namespace' => $namespace,
146
            'name' => $name,
147
        ];
148
    }
149
150
    public function getViewInfo()
151
    {
152
        $modulePath = $this->module->getPath().'/';
153
154
        $viewDir = $modulePath . GenerateConfigReader::read('livewire-view')->getPath();
155
156
        $path = collect($this->directories)
157
            ->map([\Str::class, 'kebab'])
158
            ->implode('/');
159
160
        if ($this->option('view')) $path = strtr($this->option('view'), ['.' => '/']);
161
        
162
        $name = strtr($path, ['/' => '.']);
163
164
        return (object) [
165
            'dir' => $viewDir,
166
            'path' => $path,
167
            'folder' => \Str::after($viewDir, 'views/'),
168
            'file' => $viewDir . '/' . $path . '.blade.php',
169
            'name' => $name,
170
        ];
171
    }
172
173 View Code Duplication
    protected function createClass($force = false, $inline = false)
174
    {
175
        $classPath = $this->component->class->file;
176
177
        if (File::exists($classPath) && ! $force) {
178
            $this->line("<options=bold,reverse;fg=red> WHOOPS </> 😳 \n");
179
            $this->line("<fg=red;options=bold>Class already exists:</> {$this->component->class->path}");
180
            return false;
181
        }
182
183
        $this->ensureDirectoryExists($classPath);
184
185
        File::put($classPath, $this->classContents($inline));
186
187
        return $classPath;
188
    }
189
190
    public function classContents($inline = false)
191
    {
192
        $stubName = $inline ? '/livewire/livewire.inline.stub' : '/livewire/livewire.stub';
193
194
        return (new Stub($stubName, [
195
            'NAMESPACE'  => $this->component->class->namespace,
196
            'CLASS'      => $this->component->class->name,
197
            'LOWER_NAME' => $this->module->getLowerName(),
198
            'VIEW_NAME'  => $this->component->view->folder . '.' . $this->component->view->name,
199
        ]))->render();
200
    }
201
202 View Code Duplication
    protected function createView($force = false, $inline = false)
203
    {
204
        if ($inline) return false;
205
206
        $viewPath = $this->component->view->file;
207
208
        if (File::exists($viewPath) && ! $force) {
209
            $this->line("<fg=red;options=bold>View already exists:</> {$this->component->view->path}");
210
            return false;
211
        }
212
213
        $this->ensureDirectoryExists($viewPath);
214
215
        File::put($viewPath, $this->viewContents());
216
217
        return $viewPath;
218
    }
219
220
    public function viewContents($inline = false)
0 ignored issues
show
Unused Code introduced by
The parameter $inline is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
221
    {
222
        return (new Stub('/livewire/livewire.view.stub'))->render();
223
    }
224
225
    protected function ensureDirectoryExists($path)
226
    {
227
        if (! File::isDirectory(dirname($path))) {
228
            File::makeDirectory(dirname($path), 0777, $recursive = true, $force = true);
229
        }
230
    }
231
232
    public function isReservedClassName($name)
233
    {
234
        return array_search($name, ['Parent', 'Component', 'Interface']) !== false;
235
    }
236
}
237