AddonNameCommand::setAddonNamespaces()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Jumilla\Addomnipot\Laravel\Commands;
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
    use Functions;
15
16
    /**
17
     * The console command signature.
18
     *
19
     * @var string
20
     */
21
    protected $signature = 'addon:name
22
        {addon : The desired addon.}
23
        {namespace : The desired namespace.}
24
        {--force : Force remove.}
25
    ';
26
27
    /**
28
     * The console command description.
29
     *
30
     * @var string
31
     */
32
    protected $description = 'Set the addon PHP namespace';
33
34
    /**
35
     * @var \Illuminate\Filesystem\Filesystem
36
     */
37
    protected $filesystem;
38
39
    /**
40
     * @var \Jumilla\Addomnipot\Laravel\Addons\Addon
41
     */
42
    protected $addon;
43
44
    /**
45
     * @var string
46
     */
47
    protected $currentNamespace;
48
49
    /**
50
     * @var string
51
     */
52
    protected $newNamespace;
53
54
    /**
55
     * Execute the console command.
56
     *
57
     * @return mixed
58
     */
59 2
    public function handle(Filesystem $filesystem, AddonEnvironment $env)
60
    {
61 2
        $this->filesystem = $filesystem;
62
63 2
        $addon_name = $this->argument('addon');
64
65 2
        $this->addon = $env->addon($addon_name);
66
67
        // check addon
68 2
        if ($this->addon === null) {
69 1
            throw new UnexpectedValueException("Addon '$addon_name' is not found.");
70
        }
71
72 1
        $this->currentNamespace = trim($this->addon->phpNamespace(), '\\');
73
74 1
        $this->newNamespace = str_replace('/', '\\', $this->argument('namespace'));
75
76
        // check namespace
77 1
        if (! $this->validPhpNamespace($this->newNamespace)) {
78
            throw new UnexpectedValueException("PHP namespace '{$this->newNamespace}' is invalid.");
79
        }
80
81
        // confirm
82 1
        $this->line('Addon name: '.$addon_name);
83 1
        $this->line('Addon path: '.$this->addon->relativePath($this->laravel));
84 1
        $this->line('PHP namespace: '.$this->newNamespace);
85
86 1
        if (!$this->option('force')) {
87
            if (!$this->confirm('Are you sure? [y/N]', false)) {
88
                $this->comment('canceled');
89
90
                return;
91
            }
92
        }
93
94 1
        $this->setAddonNamespaces();
95
96 1
        $this->setComposerNamespace();
97
98 1
        $this->setClassNamespace();
99
100 1
        $this->setConfigNamespaces();
101
102 1
        $this->info('Addon namespace set!');
103 1
    }
104
105
    /**
106
     * Set the namespace in addon.php, adon.json file.
107
     */
108 1
    protected function setAddonNamespaces()
109
    {
110 1
        $this->setAddonConfigNamespaces();
111 1
        $this->setAddonJsonNamespaces();
112 1
    }
113
114
    /**
115
     * Set the namespace in addon.php file.
116
     */
117 1
    protected function setAddonConfigNamespaces()
118
    {
119 1
        if (file_exists($this->addon->path('addon.php'))) {
120
            $search = [
121 1
                "namespace {$this->currentNamespace}",
122 1
                "'namespace' => '{$this->currentNamespace}'",
123 1
                "'{$this->currentNamespace}\\",
124 1
                "\"{$this->currentNamespace}\\",
125 1
                "\\{$this->currentNamespace}\\",
126
            ];
127
128
            $replace = [
129 1
                "namespace {$this->newNamespace}",
130 1
                "'namespace' => '{$this->newNamespace}'",
131 1
                "'{$this->newNamespace}\\",
132 1
                "\"{$this->newNamespace}\\",
133 1
                "\\{$this->newNamespace}\\",
134
            ];
135
136 1
            $this->replaceIn($this->addon->path('addon.php'), $search, $replace);
137
        }
138 1
    }
139
140
    /**
141
     * Set the namespace in addon.json file.
142
     */
143 1
    protected function setAddonJsonNamespaces()
144
    {
145 1
        if (file_exists($this->addon->path('addon.json'))) {
146
            $currentNamespace = str_replace('\\', '\\\\', $this->currentNamespace);
147
            $newNamespace = str_replace('\\', '\\\\', $this->newNamespace);
148
149
            $search = [
150
                "\"namespace\": \"{$currentNamespace}\"",
151
                "\"{$currentNamespace}\\\\",
152
                "\\\\{$currentNamespace}\\\\",
153
            ];
154
155
            $replace = [
156
                "\"namespace\": \"{$newNamespace}\"",
157
                "\"{$newNamespace}\\\\",
158
                "\\\\{$newNamespace}\\\\",
159
            ];
160
161
            $this->replaceIn($this->addon->path('addon.json'), $search, $replace);
162
        }
163 1
    }
164
165
    /**
166
     * Set the PSR-4 namespace in the Composer file.
167
     */
168 1
    protected function setComposerNamespace()
169
    {
170 1
        if (file_exists($this->addon->path('composer.json'))) {
171
            $this->replaceIn(
172
                $this->addon->path('composer.json'), $this->currentNamespace.'\\\\', str_replace('\\', '\\\\', $this->newNamespace).'\\\\'
173
            );
174
        }
175 1
    }
176
177
    /**
178
     * Set the namespace on the files in the class directory.
179
     */
180 1
    protected function setClassNamespace()
181
    {
182 1
        $classDirectories = $this->addon->config('addon.directories', []);
183
184 1
        if (count($this->addon->config('addon.directories', [])) === 0) {
185
            return;
186
        }
187
188 1
        $files = Finder::create();
189
190 1
        foreach ($classDirectories as $path) {
191 1
            $files->in($this->addon->path($path));
192
        }
193
194 1
        $files->name('*.php');
195
196
        $search = [
197 1
            $this->currentNamespace.'\\',
198 1
            'namespace '.$this->currentNamespace.';',
199
        ];
200
201
        $replace = [
202 1
            $this->newNamespace.'\\',
203 1
            'namespace '.$this->newNamespace.';',
204
        ];
205
206 1
        foreach ($files as $file) {
207 1
            $this->replaceIn($file, $search, $replace);
208
        }
209 1
    }
210
211
    /**
212
     * Set the namespace in the appropriate configuration files.
213
     */
214 1
    protected function setConfigNamespaces()
215
    {
216 1
        $configPath = $this->addon->path($this->addon->config('paths.config', 'config'));
217
218 1
        if ($this->filesystem->isDirectory($configPath)) {
219 1
            $files = Finder::create()
220 1
                ->in($configPath)
221 1
                ->name('*.php');
222
223 1
            foreach ($files as $file) {
224
                $this->replaceConfigNamespaces($file->getRealPath());
225
            }
226
        }
227 1
    }
228
229
    /**
230
     * Replace the namespace in PHP configuration file.
231
     *
232
     * @param string $path
233
     */
234
    protected function replaceConfigNamespaces($path)
235
    {
236
        $search = [
237
            "'{$this->currentNamespace}\\",
238
            "\"{$this->currentNamespace}\\",
239
            "\\{$this->currentNamespace}\\",
240
        ];
241
242
        $replace = [
243
            "'{$this->newNamespace}\\",
244
            "\"{$this->newNamespace}\\",
245
            "\\{$this->newNamespace}\\",
246
        ];
247
248
        $this->replaceIn($path, $search, $replace);
249
    }
250
251
    /**
252
     * Replace the given string in the given file.
253
     *
254
     * @param string $path
255
     * @param string | array $search
256
     * @param string | array $replace
257
     */
258 1
    protected function replaceIn($path, $search, $replace)
259
    {
260 1
        if ($this->output->isVerbose()) {
261
            $this->line("{$path} ...");
262
        }
263
264 1
        $this->filesystem->put($path, str_replace($search, $replace, $this->filesystem->get($path)));
265 1
    }
266
}
267