Completed
Push — master ( 5017d8...561e2a )
by Christian
07:36 queued 03:33
created

ClearCommand::emptyDirectory()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 12
rs 8.8571
cc 5
eloc 6
nc 4
nop 1
1
<?php
2
3
namespace N98\Magento\Command\Developer\Asset;
4
5
use Magento\Framework\App\Filesystem\DirectoryList;
6
use Magento\Framework\Filesystem;
7
use Magento\Framework\Filesystem\Directory\Read;
8
use Magento\Framework\Filesystem\Directory\WriteInterface;
9
use N98\Magento\Command\AbstractMagentoCommand;
10
use Symfony\Component\Console\Input\InputInterface;
11
use Symfony\Component\Console\Input\InputOption;
12
use Symfony\Component\Console\Output\OutputInterface;
13
14
class ClearCommand extends AbstractMagentoCommand
15
{
16
    /**
17
     * @var Filesystem
18
     */
19
    private $filesystem;
20
21
    /**
22
     * @var OutputInterface
23
     */
24
    private $output;
25
26
    /**
27
     * @var string[]
28
     */
29
    private $messages = [];
30
31
    /**
32
     * @param Filesystem $filesystem
33
     * @return void
34
     */
35
    public function inject(
36
        Filesystem $filesystem
37
    ) {
38
        $this->filesystem = $filesystem;
39
    }
40
41
    /**
42
     * @return void
43
     */
44
    protected function configure()
45
    {
46
        $help = <<<EOT
47
Clears static view files.
48
49
To clear assets for all themes:
50
51
   $ n98-magerun2.phar dev:asset:clear
52
53
To clear assets for specific theme(s) only:
54
55
   $ n98-magerun2.phar dev:asset:clear --theme=Magento/luma
56
57
EOT;
58
59
        $this
60
            ->setName('dev:asset:clear')
61
            ->addOption(
62
                'theme',
63
                't',
64
                InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
65
                'Clear assets for specific theme(s) only'
66
            )
67
            ->setDescription('Clear static assets')
68
            ->setHelp($help);
69
    }
70
71
    /**
72
     * @param string $code
73
     * @return WriteInterface|null
74
     */
75
    private function getDirectoryWrite($code)
76
    {
77
        /** @var WriteInterface $dir */
78
        $dir = $this->filesystem->getDirectoryWrite($code);
79
        $dirPath = $dir->getAbsolutePath();
80
        if (!$dir->isExist()) {
81
            $this->messages[] = '<warning>Directory "' . $dirPath . '" does not exist - skipped</warning>';
82
83
            return null;
84
        }
85
86
        return $dir;
87
    }
88
89
    /**
90
     * @param string $theme
91
     * @param string $code
92
     * @return string[]
93
     */
94
    private function findThemePaths($theme, $code)
95
    {
96
        $theme = '/' . trim($theme, '/');
97
        $themeLength = strlen($theme);
98
99
        /** @var Read $dir */
100
        $dir = $this->filesystem->getDirectoryRead($code);
101
        $entries = $dir->readRecursively('');
102
        $paths = [];
103
        foreach ($entries as $entry) {
104
            if (substr($entry, -$themeLength) === $theme &&
105
                $dir->isDirectory($entry)) {
106
                $paths[] = $entry;
107
            }
108
        }
109
110
        return $paths;
111
    }
112
113
    /**
114
     * @param WriteInterface $dir
115
     * @param string $path
116
     * @return void
117
     */
118
    private function deleteDirectory($dir, $path)
119
    {
120
        try {
121
            $dir->delete($path);
122
            $this->messages[] = '<info><comment>' . $dir->getAbsolutePath() . $path . '</comment> deleted</info>';
123
        } catch (\Exception $e) {
124
            $this->messages[] = '<error>' . $e->getMessage() . '</error>';
125
            if ($this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
126
                $this->messages[] = '<debug>' . $e->getTraceAsString() . '</debug>';
127
            }
128
        }
129
    }
130
131
    /**
132
     * @param string $code
133
     * @return void
134
     */
135
    private function emptyDirectory($code)
136
    {
137
        /** @var WriteInterface $dir */
138
        $dir = $this->getDirectoryWrite($code);
139
        if ($dir) {
140
            foreach ($dir->search('*') as $path) {
141
                if ($path !== '.' && $path !== '..') {
142
                    $this->deleteDirectory($dir, $path);
143
                }
144
            }
145
        }
146
    }
147
148
    /**
149
     * @param string $theme
150
     * @param string $code
151
     * @return void
152
     */
153
    private function deleteThemeDirectories($theme, $code)
154
    {
155
        /** @var WriteInterface $dir */
156
        $dir = $this->getDirectoryWrite($code);
157
        if ($dir) {
158
            $paths = $this->findThemePaths($theme, $code);
159
            foreach ($paths as $path) {
160
                $this->deleteDirectory($dir, $path);
161
            }
162
        }
163
    }
164
165
    /**
166
     * @param array $themes
167
     * @return void
168
     */
169
    private function clearThemes($themes)
170
    {
171
        foreach ($themes as $theme) {
172
            $this->deleteThemeDirectories($theme, DirectoryList::STATIC_VIEW);
173
            $this->deleteThemeDirectories($theme, DirectoryList::TMP_MATERIALIZATION_DIR);
174
        }
175
    }
176
177
    /**
178
     * @return void
179
     */
180
    private function clearAllThemes()
181
    {
182
        $this->emptyDirectory(DirectoryList::STATIC_VIEW);
183
        $this->emptyDirectory(DirectoryList::TMP_MATERIALIZATION_DIR);
184
    }
185
186
    /**
187
     * @param InputInterface $input
188
     * @param OutputInterface $output
189
     * @return void
190
     */
191
    protected function execute(InputInterface $input, OutputInterface $output)
192
    {
193
        $this->detectMagento($output, true);
194
        if (!$this->initMagento()) {
195
            return;
196
        }
197
198
        if ($this->runsInProductionMode($input, $output)) {
199
            $output->writeln('This command is not available in production mode');
200
            return;
201
        }
202
203
        $this->output = $output;
204
        $themes = $input->getOption('theme');
205
        if ($themes) {
206
            $this->clearThemes($themes);
207
        } else {
208
            $this->clearAllThemes();
209
        }
210
211
        $output->writeln($this->messages);
212
    }
213
}
214