Completed
Pull Request — master (#4)
by
unknown
02:16
created

ModuleCreator::createFile()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 25
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 25
rs 8.8571
cc 3
eloc 17
nc 4
nop 4
1
<?php
2
3
namespace Mnabialek\LaravelModular\Console\Traits;
4
5
use Mnabialek\LaravelModular\Models\Module;
6
use Mnabialek\LaravelModular\Traits\Normalizer;
7
use Exception;
8
9
trait ModuleCreator
10
{
11
    use Normalizer;
12
13
    /**
14
     * Verify stub group
15
     *
16
     * @param string $stubGroup
17
     *
18
     * @throws \Exception
19
     */
20
    protected function verifyStubGroup($stubGroup)
21
    {
22
        // first verify whether this group is in config file
23
24
        if (!collect($this->laravel['modular.config']->stubGroups())->contains($stubGroup)) {
0 ignored issues
show
Bug introduced by
The property laravel 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...
25
            throw new Exception("Stub group {$stubGroup} does not exist. You need to add it to stubs_groups");
26
        }
27
28
        // then verify whether this stub group directory exists
29
        $directory = $this->getStubGroupDirectory($stubGroup);
30
        if (!$this->exists($directory)) {
31
            throw new Exception("Stub group directory {$directory} does not exist");
32
        }
33
    }
34
35
    /**
36
     * Get directory for given stub group
37
     *
38
     * @param string $group
39
     *
40
     * @return string
41
     */
42
    protected function getStubGroupDirectory($group)
43
    {
44
        return $this->normalizePath($this->laravel['modular.config']->stubsPath() .
45
            DIRECTORY_SEPARATOR .
46
            $this->laravel['modular.config']->stubGroupDirectory($group));
47
    }
48
49
    /**
50
     * Verify whether module config was published
51
     *
52
     * @throws \Exception
53
     */
54
    protected function verifyConfigExistence()
55
    {
56
        if (!$this->exists($this->laravel['modular.config']->configPath())) {
57
            throw new Exception('Config file does not exists. Please run php artisan vendor:publish (see docs for details)');
58
        }
59
    }
60
61
    /**
62
     * Verify whether given file or directory exists
63
     *
64
     * @param string $path
65
     * @param Module $module
66
     *
67
     * @return bool
68
     */
69
    protected function exists($path, Module $module = null)
70
    {
71
        if ($module !== null) {
72
            $path = $module->directory() . DIRECTORY_SEPARATOR . $path;
73
        }
74
75
        return $this->laravel['files']->exists($path);
76
    }
77
78
    /**
79
     * Get stub group - either from input of default one
80
     *
81
     * @return mixed
82
     */
83
    protected function getStubGroup()
84
    {
85
        return $this->option('group') ?: $this->laravel['modular.config']->stubsDefaultGroup();
0 ignored issues
show
Bug introduced by
It seems like option() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
86
    }
87
88
    protected function getFilesStubGroup()
89
    {
90
        return $this->option('group') ?: $this->laravel['modular.config']->filesStubsDefaultGroup();
0 ignored issues
show
Bug introduced by
It seems like option() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
91
    }
92
93
    /**
94
     * Creates module directories
95
     *
96
     * @param Module $module
97
     * @param string $stubGroup
98
     */
99
    protected function createModuleDirectories(Module $module, $stubGroup)
100
    {
101
        $directories = collect($this->laravel['modular.config']
102
            ->stubGroupDirectories($stubGroup))->unique();
103
104
        if ($directories->isEmpty()) {
105
            $this->warn("[Module {$module->name()}] No explicit directories created");
0 ignored issues
show
Bug introduced by
It seems like warn() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
106
        } else {
107
            $directories->each(function ($directory) use ($module) {
108
                $this->createDirectory($module, $directory);
109
            });
110
        }
111
    }
112
113
    /**
114
     * Creates directory
115
     *
116
     * @param Module $module
117
     * @param string $directory
118
     *
119
     * @return bool
120
     * @throws Exception
121
     */
122
    protected function createDirectory(Module $module, $directory)
123
    {
124
        if( file_exists(base_path().DIRECTORY_SEPARATOR.$directory)){
125
            return true;
126
        }else{
127
            $result =
128
                $this->laravel['files']->makeDirectory($module->directory() .
129
                    DIRECTORY_SEPARATOR . $directory, 0755, true);
130
131
            if ($result) {
132
                $this->line("[Module {$module->name()}] Created directory {$directory}");
0 ignored issues
show
Bug introduced by
It seems like line() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
133
            } else {
134
                throw new Exception("[Module {$module->name()}] Cannot create directory {$directory}");
135
            }
136
137
            return true;
138
        }
139
        return false;
0 ignored issues
show
Unused Code introduced by
return false; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
140
    }
141
142
    /**
143
     * Create files inside given module
144
     *
145
     * @param Module $module
146
     * @param string $stubGroup
147
     * @param string $subModule
148
     *
149
     * @return bool
150
     */
151
    protected function createModuleFiles(
152
        Module $module,
153
        $stubGroup,
154
        $subModule = null
155
    ) {
156
        $files = collect($this->laravel['modular.config']
157
            ->stubGroupFiles($stubGroup));
158
159
        if ($files->isEmpty()) {
160
            $this->warn("[Module {$module->name()}] No files created");
0 ignored issues
show
Bug introduced by
It seems like warn() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
161
162
            return false;
163
        }
164
165
        $replacements = $subModule ? ['class' => $subModule] : [];
166
167
        $files->each(function ($stubFile, $moduleFile) use ($module, $stubGroup, $replacements) {
168
            $this->copyStubFileIntoModule($module, $stubFile, $stubGroup,
169
                $moduleFile, $replacements);
170
        });
171
172
        return true;
173
    }
174
175
    /**
176
     * Copy single stub file into module
177
     *
178
     * @param Module $module
179
     * @param $stubFile
180
     * @param $stubGroup
181
     * @param $moduleFile
182
     * @param array $replacements
183
     *
184
     * @throws Exception
185
     */
186
    protected function copyStubFileIntoModule(
187
        Module $module,
188
        $stubFile,
189
        $stubGroup,
190
        $moduleFile,
191
        array $replacements = []
192
    ) {
193
        $stubPath = $this->getStubGroupDirectory($stubGroup) .
194
            DIRECTORY_SEPARATOR . $stubFile;
195
196
        if (!$this->exists($stubPath)) {
197
            throw new Exception("Stub file {$stubPath} does NOT exist");
198
        }
199
        $moduleFile = $this->replace($moduleFile, $module, $replacements);
0 ignored issues
show
Bug introduced by
It seems like replace() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
200
201
        if ($this->exists($moduleFile, $module)) {
202
            throw new Exception("[Module {$module->name()}] File {$moduleFile} already exists");
203
        }
204
205
        $this->createMissingDirectory($module, $moduleFile);
206
        $this->createFile($module, $stubPath, $moduleFile, $replacements);
207
    }
208
209
    /**
210
     * Creates directory for given file (if it doesn't exist)
211
     *
212
     * @param Module $module
213
     * @param string $file
214
     */
215
    protected function createMissingDirectory(Module $module, $file)
216
    {
217
        if (!$this->exists(($dir = dirname($file)), $module)) {
218
            $this->createDirectory($module, $dir);
219
        }
220
    }
221
222
    /**
223
     * Creates single file
224
     *
225
     * @param Module $module
226
     * @param string $sourceFile
227
     * @param string $destinationFile
228
     * @param array $replacements
229
     *
230
     * @throws Exception
231
     */
232
    protected function createFile(
233
        Module $module,
234
        $sourceFile,
235
        $destinationFile,
236
        array $replacements = []
237
    ) {
238
        if(file_exists(base_path().DIRECTORY_SEPARATOR.dirname($destinationFile))){
239
            $result = $this->laravel['files']->put($destinationFile,
240
                $this->replace($this->laravel['files']->get($sourceFile), $module,
0 ignored issues
show
Bug introduced by
It seems like replace() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
241
                    $replacements)
242
            );
243
        }else{
244
            $result = $this->laravel['files']->put($module->directory() .
245
                DIRECTORY_SEPARATOR . $destinationFile,
246
                $this->replace($this->laravel['files']->get($sourceFile), $module,
0 ignored issues
show
Bug introduced by
It seems like replace() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
247
                    $replacements)
248
            );
249
        }
250
251
        if ($result === false) {
252
            throw new Exception("[Module {$module->name()}] Cannot create file {$destinationFile}");
253
        }
254
255
        $this->line("[Module {$module->name()}] Created file {$destinationFile}");
0 ignored issues
show
Bug introduced by
It seems like line() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
256
    }
257
}
258