Passed
Pull Request — master (#178)
by
unknown
04:06
created

ResourceCacheClearCommand::initModule()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 7
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 10
rs 10
1
<?php
2
3
/**
4
 * Quantum PHP Framework
5
 *
6
 * An open source software development framework for PHP
7
 *
8
 * @package Quantum
9
 * @author Arman Ag. <[email protected]>
10
 * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org)
11
 * @link http://quantum.softberg.org/
12
 * @since 2.8.0
13
 */
14
15
namespace Quantum\Console\Commands;
16
17
use Quantum\Libraries\Storage\FileSystem;
18
use Quantum\Exceptions\ConfigException;
19
use Quantum\Exceptions\DiException;
20
use Quantum\Console\QtCommand;
21
use Quantum\Loader\Setup;
22
use ReflectionException;
23
use Quantum\Di\Di;
24
use Exception;
25
26
/**
27
 * Class EnvCommand
28
 * @package Quantum\Console\Commands
29
 */
30
class ResourceCacheClearCommand extends QtCommand
31
{
32
33
	/**
34
	 * Command name
35
	 * @var string
36
	 */
37
	protected $name = 'cache:clear';
38
39
	/**
40
	 * Command description
41
	 * @var string
42
	 */
43
	protected $description = 'Clearing resource caches';
44
45
	/**
46
	 * Command help text
47
	 * @var string
48
	 */
49
	protected $help = 'The command will clear the resource caches.';
50
51
	/**
52
	 * Command options
53
	 * @var array
54
	 */
55
	protected $options = [
56
		['all', 'all', 'none', ''],
57
		['type', 't', 'required', ''],
58
		['module', 'm', 'required', '']
59
	];
60
61
	/**
62
	 * @var array
63
	 */
64
	protected $types = ['views', 'asserts'];
65
66
	/**
67
	 * @var array
68
	 */
69
	protected $modules;
70
71
	/**
72
	 * @var string|null
73
	 */
74
	protected $type = null;
75
76
	/**
77
	 * @var string|null
78
	 */
79
	protected $module = null;
80
81
	/**
82
	 * @var string
83
	 */
84
	protected $cacheDir;
85
86
	/**
87
	 * @var object
88
	 */
89
	protected $fs;
90
91
	/**
92
	 * @return void
93
	 * @throws DiException
94
	 * @throws ReflectionException
95
	 */
96
	public function exec()
97
	{
98
		try {
99
			$this->importConfig();
100
			$this->initModule($this->getOption('module'));
101
			$this->initType($this->getOption('type'));
102
		}catch (Exception $e){
103
			$this->error($e->getMessage());
104
			return;
105
		}
106
107
		$this->fs = Di::get(FileSystem::class);
108
109
		if (!$this->fs->isDirectory($this->cacheDir)) {
110
			$this->error('Cache directory does not exist or is not accessible.');
111
			return;
112
		}
113
114
		if ($this->module || $this->type) {
115
			$this->clearResourceModuleAndType($this->module, $this->type);
116
		} elseif (!empty($this->getOption('all'))) {
117
			$this->removeFilesFromDirectory($this->cacheDir);
118
		} else {
119
			$this->error('Please specify at least one of the following options: --all, --module=moduleName or --type=typeName!');
120
			return;
121
		}
122
123
		$this->info('Resource cache cleared successfully.');
124
	}
125
126
	/**
127
	 * @return void
128
	 */
129
	private function importModules()
130
	{
131
		try {
132
			if (!config()->has('modules')) {
133
				config()->import(new Setup('config', 'modules'));
134
			}
135
136
			if (config()->has('modules')){
137
				$this->modules = array_keys(array_change_key_case(config()->get('modules.modules')));
0 ignored issues
show
Bug introduced by
It seems like config()->get('modules.modules') can also be of type null; however, parameter $array of array_change_key_case() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

137
				$this->modules = array_keys(array_change_key_case(/** @scrutinizer ignore-type */ config()->get('modules.modules')));
Loading history...
138
			}
139
		} catch (ConfigException|DiException|ReflectionException $e) {
140
			$this->error($e->getMessage());
141
			return;
142
		}
143
	}
144
145
	/**
146
	 * @return void
147
	 * @throws ConfigException
148
	 * @throws DiException
149
	 * @throws ReflectionException
150
	 */
151
	private function importConfig(): void
152
	{
153
		if (!config()->has('view_cache')) {
154
			config()->import(new Setup('config', 'view_cache'));
155
		}
156
157
		$this->cacheDir = base_dir() . DS . config()->get('view_cache.cache_dir', 'cache');
158
	}
159
160
	/**
161
	 * @param string|null $moduleOption
162
	 * @return void
163
	 * @throws Exception
164
	 */
165
	private function initModule(?string $moduleOption): void
166
	{
167
		if (!empty($moduleOption)) {
168
			$this->importModules();
169
			$module = strtolower($moduleOption);
170
171
			if (in_array($module, $this->modules)) {
172
				$this->module = $module;
173
			} else {
174
				throw new Exception('Module {'. $module .'} does not exist.');
175
			}
176
		}
177
	}
178
179
	/**
180
	 * @param string|null $typeOption
181
	 * @return void
182
	 * @throws Exception
183
	 */
184
	private function initType(?string $typeOption): void
185
	{
186
		if (!empty($typeOption)) {
187
			$type = strtolower($typeOption);
188
189
			if (in_array($type, $this->types)) {
190
				$this->type = $type;
191
			} else {
192
				throw new Exception('Cache type {'. $type .'} is invalid.');
193
			}
194
		}
195
	}
196
197
	/**
198
	 * @param string|null $moduleName
199
	 * @param string|null $type
200
	 * @return void
201
	 */
202
	private function clearResourceModuleAndType(?string $moduleName = null, ?string $type = null): void
203
	{
204
		$dir = $this->cacheDir;
205
206
		if ($type) {
207
			$dir = $dir . DS . strtolower($type);
208
		}
209
210
		if ($moduleName) {
211
			if (!$type) {
212
				$dir = $dir . DS . '*';
213
			}
214
			$dir = $dir . DS . strtolower($moduleName);
215
		}
216
217
		$this->removeFilesFromDirectory($dir);
218
	}
219
220
	/**
221
	 * @param string $dir
222
	 * @return void
223
	 */
224
	private function removeFilesFromDirectory(string $dir): void
225
	{
226
		$entries = $this->fs->glob($dir . DIRECTORY_SEPARATOR . '*');
227
228
		foreach ($entries as $entry) {
229
			if ($this->fs->isDirectory($entry)) {
230
				$this->removeFilesFromDirectory($entry);
231
232
				if (basename($entry) !== config()->get('view_cache.cache_dir', 'cache') &&
233
					count($this->fs->glob($entry . DIRECTORY_SEPARATOR . '*')) === 0
234
				) {
235
					$this->fs->removeDirectory($entry);
236
				}
237
			} else {
238
				$this->fs->remove($entry);
239
			}
240
		}
241
	}
242
}
243