Completed
Push — master ( 880a30...6b3c1e )
by Fumio
02:31
created

AddonNameCommand::setClassNamespace()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 24
ccs 16
cts 16
cp 1
rs 8.9714
cc 3
eloc 13
nc 4
nop 0
crap 3
1
<?php
2
3
namespace Jumilla\Addomnipot\Laravel\Console;
4
5
use Illuminate\Console\Command;
6
use Illuminate\Filesystem\Filesystem;
7
use Symfony\Component\Finder\Finder;
8
use Jumilla\Addomnipot\Laravel\Environment as AddonEnvironment;
9
use Jumilla\Addomnipot\Laravel\Addon;
10
use UnexpectedValueException;
11
12
class AddonNameCommand extends Command
13
{
14
    /**
15
     * The console command signature.
16
     *
17
     * @var string
18
     */
19
    protected $signature = 'addon:name
20
        {addon : The desired namespace.}
21
        {namespace : The desired namespace.}
22
    ';
23
24
    /**
25
     * The console command description.
26
     *
27
     * @var string
28
     */
29
    protected $description = 'Set the addon PHP namespace';
30
31
    /**
32
     * @var \Illuminate\Filesystem\Filesystem
33
     */
34
    protected $filesystem;
35
36
    /**
37
     * @var \Jumilla\Addomnipot\Laravel\Addons\Addon
38
     */
39
    protected $addon;
40
41
    /**
42
     * @var string
43
     */
44
    protected $currentNamespace;
45
46
    /**
47
     * @var string
48
     */
49
    protected $newNamespace;
50
51
    /**
52
     * Execute the console command.
53
     *
54
     * @return mixed
55
     */
56 2
    public function handle(Filesystem $filesystem, AddonEnvironment $env)
57
    {
58 2
        $this->filesystem = $filesystem;
59
60 2
        $addonName = $this->argument('addon');
61
62 2
        if (!$env->exists($addonName)) {
0 ignored issues
show
Bug introduced by
It seems like $addonName defined by $this->argument('addon') on line 60 can also be of type array; however, Jumilla\Addomnipot\Laravel\Environment::exists() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
63 1
            throw new UnexpectedValueException("Addon '$addonName' is not found.");
64
        }
65
66 1
        $this->addon = Addon::create($env->path($addonName));
0 ignored issues
show
Bug introduced by
It seems like $addonName defined by $this->argument('addon') on line 60 can also be of type array; however, Jumilla\Addomnipot\Laravel\Environment::path() does only seem to accept string|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Documentation Bug introduced by
It seems like \Jumilla\Addomnipot\Lara...$env->path($addonName)) of type object<Jumilla\Addomnipot\Laravel\Addon> is incompatible with the declared type object<Jumilla\Addomnipot\Laravel\Addons\Addon> of property $addon.

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...
67
68 1
        $this->currentNamespace = trim($this->addon->phpNamespace(), '\\');
69
70 1
        $this->newNamespace = str_replace('/', '\\', $this->argument('namespace'));
71
72 1
        $this->setAddonNamespaces();
73
74 1
        $this->setComposerNamespace();
75
76 1
        $this->setClassNamespace();
77
78 1
        $this->setConfigNamespaces();
79
80 1
        $this->info('Addon namespace set!');
81 1
    }
82
83
    /**
84
     * Set the namespace in addon.php, adon.json file.
85
     */
86 1
    protected function setAddonNamespaces()
87
    {
88 1
        $this->setAddonConfigNamespaces();
89 1
        $this->setAddonJsonNamespaces();
90 1
    }
91
92
    /**
93
     * Set the namespace in addon.php file.
94
     */
95 1
    protected function setAddonConfigNamespaces()
96
    {
97 1
        if (file_exists($this->addon->path('addon.php'))) {
98
            $search = [
99 1
                "'namespace' => '{$this->currentNamespace}'",
100 1
                "'{$this->currentNamespace}\\",
101 1
                "\"{$this->currentNamespace}\\",
102 1
                "\\{$this->currentNamespace}\\",
103 1
            ];
104
105
            $replace = [
106 1
                "'namespace' => '{$this->newNamespace}'",
107 1
                "'{$this->newNamespace}\\",
108 1
                "\"{$this->newNamespace}\\",
109 1
                "\\{$this->newNamespace}\\",
110 1
            ];
111
112 1
            $this->replaceIn($this->addon->path('addon.php'), $search, $replace);
113 1
        }
114 1
    }
115
116
    /**
117
     * Set the namespace in addon.json file.
118
     */
119 1
    protected function setAddonJsonNamespaces()
120
    {
121 1
        if (file_exists($this->addon->path('addon.json'))) {
122
            $currentNamespace = str_replace('\\', '\\\\', $this->currentNamespace);
123
            $newNamespace = str_replace('\\', '\\\\', $this->newNamespace);
124
125
            $search = [
126
                "\"namespace\": \"{$currentNamespace}\"",
127
                "\"{$currentNamespace}\\\\",
128
                "\\\\{$currentNamespace}\\\\",
129
            ];
130
131
            $replace = [
132
                "\"namespace\": \"{$newNamespace}\"",
133
                "\"{$newNamespace}\\\\",
134
                "\\\\{$newNamespace}\\\\",
135
            ];
136
137
            $this->replaceIn($this->addon->path('addon.json'), $search, $replace);
138
        }
139 1
    }
140
141
    /**
142
     * Set the PSR-4 namespace in the Composer file.
143
     */
144 1
    protected function setComposerNamespace()
145
    {
146 1
        if (file_exists($this->addon->path('composer.json'))) {
147
            $this->replaceIn(
148
                $this->addon->path('composer.json'), $this->currentNamespace.'\\\\', str_replace('\\', '\\\\', $this->newNamespace).'\\\\'
149
            );
150
        }
151 1
    }
152
153
    /**
154
     * Set the namespace on the files in the class directory.
155
     */
156 1
    protected function setClassNamespace()
157
    {
158 1
        $files = Finder::create();
159
160 1
        foreach ($this->addon->config('addon.directories') as $path) {
161 1
            $files->in($this->addon->path($path));
162 1
        }
163
164 1
        $files->name('*.php');
165
166
        $search = [
167 1
            'namespace '.$this->currentNamespace.';',
168 1
            $this->currentNamespace.'\\',
169 1
        ];
170
171
        $replace = [
172 1
            'namespace '.$this->newNamespace.';',
173 1
            $this->newNamespace.'\\',
174 1
        ];
175
176 1
        foreach ($files as $file) {
177 1
            $this->replaceIn($file, $search, $replace);
178 1
        }
179 1
    }
180
181
    /**
182
     * Set the namespace in the appropriate configuration files.
183
     */
184 1
    protected function setConfigNamespaces()
185
    {
186 1
        $configPath = $this->addon->path($this->addon->config('paths.config', 'config'));
187
188 1
        if ($this->filesystem->isDirectory($configPath)) {
189 1
            $files = Finder::create()
190 1
                ->in($configPath)
191 1
                ->name('*.php');
192
193 1
            foreach ($files as $file) {
194
                $this->replaceConfigNamespaces($file->getRealPath());
195 1
            }
196 1
        }
197 1
    }
198
199
    /**
200
     * Replace the namespace in PHP configuration file.
201
     *
202
     * @param string $path
203
     */
204
    protected function replaceConfigNamespaces($path)
205
    {
206
        $search = [
207
            "'{$this->currentNamespace}\\",
208
            "\"{$this->currentNamespace}\\",
209
            "\\{$this->currentNamespace}\\",
210
        ];
211
212
        $replace = [
213
            "'{$this->newNamespace}\\",
214
            "\"{$this->newNamespace}\\",
215
            "\\{$this->newNamespace}\\",
216
        ];
217
218
        $this->replaceIn($path, $search, $replace);
219
    }
220
221
    /**
222
     * Replace the given string in the given file.
223
     *
224
     * @param string $path
225
     * @param string | array $search
226
     * @param string | array $replace
227
     */
228 1
    protected function replaceIn($path, $search, $replace)
229
    {
230 1
        if ($this->output->isVerbose()) {
231
            $this->line("{$path} ...");
232
        }
233
234 1
        $this->filesystem->put($path, str_replace($search, $replace, $this->filesystem->get($path)));
235 1
    }
236
}
237