AbstractCreatorTask::shouldBeSkippedIfFileExists()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
1
<?php
2
3
namespace Cerbero\ConsoleTasker\Tasks;
4
5
use Cerbero\ConsoleTasker\ManipulatedFile;
6
use Illuminate\Container\Container;
7
use RuntimeException;
8
9
/**
10
 * The abstract creator task.
11
 *
12
 */
13
abstract class AbstractCreatorTask extends AbstractFilesManipulatorTask
14
{
15
    /**
16
     * The file to create.
17
     *
18
     * @var ManipulatedFile
19
     */
20
    protected $file;
21
22
    /**
23
     * Whether this task should be skipped if the file to create already exists.
24
     *
25
     * @var bool
26
     */
27
    protected $shouldBeSkippedIfFileExists = true;
28
29
    /**
30
     * Retrieve the path of the stub
31
     *
32
     * @return string
33
     */
34
    abstract protected function getStubPath(): string;
35
36
    /**
37
     * Run the task
38
     *
39
     * @return mixed
40
     */
41
    public function run()
42
    {
43
        $this->file = $this->file($this->getPath());
44
45
        if ($reason = $this->needsManualUpdateTo()) {
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $reason is correct as $this->needsManualUpdateTo() targeting Cerbero\ConsoleTasker\Ta...::needsManualUpdateTo() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
46
            $this->file->needsManualUpdateTo($reason);
0 ignored issues
show
Bug introduced by
$reason of type void is incompatible with the type string expected by parameter $reason of Cerbero\ConsoleTasker\Ma...::needsManualUpdateTo(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

46
            $this->file->needsManualUpdateTo(/** @scrutinizer ignore-type */ $reason);
Loading history...
47
        }
48
49
        if ($this->canCreateFile()) {
50
            return $this->createFile();
51
        }
52
53
        if (!$this->shouldBeSkippedIfFileExists()) {
54
            $this->setError($this->getCreationError());
55
            return false;
56
        }
57
    }
58
59
    /**
60
     * Retrieve the path of the file to create
61
     *
62
     * @return string
63
     */
64
    protected function getPath(): string
65
    {
66
        if (is_null($name = $this->getFullyQualifiedName())) {
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $name is correct as $this->getFullyQualifiedName() targeting Cerbero\ConsoleTasker\Ta...getFullyQualifiedName() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
introduced by
The condition is_null($name = $this->getFullyQualifiedName()) is always true.
Loading history...
67
            throw new RuntimeException('Please provide a path or a fully qualified name for the file to create');
68
        }
69
70
        if (strpos($name, $namespace = Container::getInstance()->make('app')->getNamespace()) === 0) {
71
            $name = substr_replace($name, 'app/', 0, strlen($namespace));
72
        }
73
74
        return Container::getInstance()->make('app')->basePath(str_replace('\\', '/', $name)) . '.php';
75
    }
76
77
    /**
78
     * Retrieve the fully qualified name of the file to create
79
     *
80
     * @return string|null
81
     */
82
    protected function getFullyQualifiedName(): ?string
83
    {
84
        return null;
85
    }
86
87
    /**
88
     * Retrieve the reason why the file needs to be updated manually
89
     *
90
     * @return string|null
91
     */
92
    public function needsManualUpdateTo(): ?string
93
    {
94
        return null;
95
    }
96
97
    /**
98
     * Determine whether the file can be created
99
     *
100
     * @return bool
101
     */
102
    protected function canCreateFile(): bool
103
    {
104
        if ($this->hasOption('force') && $this->option('force')) {
105
            return true;
106
        }
107
108
        return !file_exists($this->getPath());
109
    }
110
111
    /**
112
     * Retrieve the reason why the file could not be created
113
     *
114
     * @return string
115
     */
116
    protected function getCreationError(): string
117
    {
118
        return 'the file ' . basename($this->getPath()) . ' already exists';
119
    }
120
121
    /**
122
     * Create the file
123
     *
124
     * @return bool
125
     */
126
    protected function createFile(): bool
127
    {
128
        $path = $this->getPath();
129
130
        if (!is_dir(dirname($path))) {
131
            @mkdir(dirname($path), 0777, true);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for mkdir(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

131
            /** @scrutinizer ignore-unhandled */ @mkdir(dirname($path), 0777, true);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
132
        }
133
134
        $replacements = array_merge($this->getDefaultReplacements(), $this->getReplacements());
135
        $stubContent = file_get_contents($this->getStubPath());
136
        $content = str_replace(array_keys($replacements), array_values($replacements), $stubContent);
137
138
        return file_put_contents($path, $content) !== false;
139
    }
140
141
    /**
142
     * Retrieve the default replacements to apply on the stub
143
     *
144
     * @return array
145
     */
146
    protected function getDefaultReplacements(): array
147
    {
148
        $qualified = $this->getFullyQualifiedName();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $qualified is correct as $this->getFullyQualifiedName() targeting Cerbero\ConsoleTasker\Ta...getFullyQualifiedName() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
149
        $class = class_basename($qualified);
150
        $namespace = substr($qualified, 0, strrpos($qualified, $class) - 1);
0 ignored issues
show
Bug introduced by
$qualified of type null is incompatible with the type string expected by parameter $haystack of strrpos(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

150
        $namespace = substr($qualified, 0, strrpos(/** @scrutinizer ignore-type */ $qualified, $class) - 1);
Loading history...
Bug introduced by
$qualified of type null is incompatible with the type string expected by parameter $string of substr(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

150
        $namespace = substr(/** @scrutinizer ignore-type */ $qualified, 0, strrpos($qualified, $class) - 1);
Loading history...
151
152
        return [
153
            'DummyClass' => $class,
154
            '{{ class }}' => $class,
155
            'DummyNamespace' => $namespace,
156
            '{{ namespace }}' => $namespace,
157
        ];
158
    }
159
160
    /**
161
     * Retrieve the replacements to apply on the stub
162
     *
163
     * @return array
164
     */
165
    protected function getReplacements(): array
166
    {
167
        return [];
168
    }
169
170
    /**
171
     * Determine whether this task should run
172
     *
173
     * @return bool
174
     */
175
    public function shouldRun(): bool
176
    {
177
        return !file_exists($this->getPath()) || !$this->shouldBeSkippedIfFileExists();
178
    }
179
180
    /**
181
     * Determine whether this task should be skipped if the file to create already exists
182
     *
183
     * @return bool
184
     */
185
    protected function shouldBeSkippedIfFileExists(): bool
186
    {
187
        return $this->shouldBeSkippedIfFileExists;
188
    }
189
190
    /**
191
     * Retrieve the reason why this task should not run
192
     *
193
     * @return string|null
194
     */
195
    public function getSkippingReason(): ?string
196
    {
197
        return $this->getCreationError();
198
    }
199
}
200