1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Bluz composer plugin |
4
|
|
|
* |
5
|
|
|
* @copyright Bluz PHP Team |
6
|
|
|
* @link https://github.com/bluzphp/composer-plugin |
7
|
|
|
*/ |
8
|
|
|
|
9
|
|
|
/** |
10
|
|
|
* @namespace |
11
|
|
|
*/ |
12
|
|
|
namespace Bluz\Composer\Installers; |
13
|
|
|
|
14
|
|
|
use Composer\Composer; |
15
|
|
|
use Composer\EventDispatcher\EventSubscriberInterface; |
16
|
|
|
use Composer\Installer\PackageEvent; |
17
|
|
|
use Composer\IO\IOInterface; |
18
|
|
|
use Composer\Plugin\PluginInterface; |
19
|
|
|
use Composer\Script\ScriptEvents; |
20
|
|
|
|
21
|
|
|
class Plugin implements PluginInterface, EventSubscriberInterface |
22
|
|
|
{ |
23
|
|
|
const PERMISSION_CODE = 0755; |
24
|
|
|
const REPEAT = 5; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* @var Installer |
28
|
|
|
*/ |
29
|
|
|
protected $installer; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* @var string |
33
|
|
|
*/ |
34
|
|
|
protected $environment; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* Create instance, define constants |
38
|
|
|
*/ |
39
|
|
|
public function __construct() |
40
|
|
|
{ |
41
|
|
|
defined('PATH_ROOT') ? : define('PATH_ROOT', realpath($_SERVER['DOCUMENT_ROOT'])); |
42
|
|
|
defined('DS') ? : define('DS', DIRECTORY_SEPARATOR); |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Called after the plugin is loaded |
47
|
|
|
* |
48
|
|
|
* It setup composer installer |
49
|
|
|
* |
50
|
|
|
* {@inheritDoc} |
51
|
|
|
*/ |
52
|
|
|
public function activate(Composer $composer, IOInterface $io) |
53
|
|
|
{ |
54
|
|
|
$this->installer = new Installer($io, $composer); |
55
|
|
|
$composer->getInstallationManager()->addInstaller($this->installer); |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* Registered events after the plugin is loaded |
60
|
|
|
* |
61
|
|
|
* {@inheritDoc} |
62
|
|
|
*/ |
63
|
|
|
public static function getSubscribedEvents(): array |
64
|
|
|
{ |
65
|
|
|
return [ |
66
|
|
|
// copy files to working directory |
67
|
|
|
ScriptEvents::POST_PACKAGE_INSTALL => 'onPostPackageInstall', |
|
|
|
|
68
|
|
|
// removed unchanged files |
69
|
|
|
ScriptEvents::PRE_PACKAGE_UPDATE => 'onPrePackageUpdate', |
|
|
|
|
70
|
|
|
// copy new files |
71
|
|
|
ScriptEvents::POST_PACKAGE_UPDATE => 'onPostPackageUpdate', |
|
|
|
|
72
|
|
|
// removed all files |
73
|
|
|
ScriptEvents::PRE_PACKAGE_UNINSTALL => 'onPrePackageRemove' |
|
|
|
|
74
|
|
|
]; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Hook which is called after install package |
79
|
|
|
* |
80
|
|
|
* It copies bluz module |
81
|
|
|
*/ |
82
|
|
View Code Duplication |
public function onPostPackageInstall(PackageEvent $event) |
|
|
|
|
83
|
|
|
{ |
84
|
|
|
$packageName = $event->getOperation() |
|
|
|
|
85
|
|
|
->getPackage() |
86
|
|
|
->getName(); |
87
|
|
|
|
88
|
|
|
$event->getIo()->write( |
89
|
|
|
" - Installing module `$packageName`:", |
90
|
|
|
true, |
91
|
|
|
IOInterface::VERBOSE |
92
|
|
|
); |
93
|
|
|
|
94
|
|
|
if (file_exists($this->installer->getOption('vendorPath'))) { |
95
|
|
|
$this->copy(); |
96
|
|
|
} |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* Hook which is called before update package |
101
|
|
|
* |
102
|
|
|
* It checks bluz module |
103
|
|
|
*/ |
104
|
|
|
public function onPrePackageUpdate(PackageEvent $event) |
|
|
|
|
105
|
|
|
{ |
106
|
|
|
if (file_exists($this->installer->getOption('vendorPath'))) { |
107
|
|
|
$this->remove(); |
108
|
|
|
} |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* Hook which is called after update package |
113
|
|
|
* |
114
|
|
|
* It copies bluz module |
115
|
|
|
*/ |
116
|
|
|
public function onPostPackageUpdate(PackageEvent $event) |
|
|
|
|
117
|
|
|
{ |
118
|
|
|
if (file_exists($this->installer->getOption('vendorPath'))) { |
119
|
|
|
$this->copy(); |
120
|
|
|
} |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* Hook which is called before remove package |
125
|
|
|
* |
126
|
|
|
* It removes bluz module |
127
|
|
|
*/ |
128
|
|
View Code Duplication |
public function onPrePackageRemove(PackageEvent $event) |
|
|
|
|
129
|
|
|
{ |
130
|
|
|
$packageName = $event->getOperation() |
|
|
|
|
131
|
|
|
->getPackage() |
132
|
|
|
->getName(); |
133
|
|
|
|
134
|
|
|
$event->getIo()->write( |
135
|
|
|
" - Removing module `$packageName`:", |
136
|
|
|
true, |
137
|
|
|
IOInterface::VERBOSE |
138
|
|
|
); |
139
|
|
|
|
140
|
|
|
if (file_exists($this->installer->getOption('vendorPath'))) { |
141
|
|
|
$this->remove(); |
142
|
|
|
} |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
/** |
146
|
|
|
* It recursively copies the files and directories |
147
|
|
|
* @return bool |
148
|
|
|
*/ |
149
|
|
|
protected function copy() |
150
|
|
|
{ |
151
|
|
|
$this->copyRecursive('application'); |
152
|
|
|
$this->copyRecursive('data'); |
153
|
|
|
$this->copyRecursive('public'); |
154
|
|
|
$this->copyRecursive('tests'); |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
/** |
158
|
|
|
* It recursively copies the files and directories |
159
|
|
|
* @param $directory |
160
|
|
|
* @return bool |
161
|
|
|
*/ |
162
|
|
|
protected function copyRecursive($directory) |
163
|
|
|
{ |
164
|
|
|
$sourcePath = $this->installer->getOption('vendorPath') . DS . $directory; |
165
|
|
|
|
166
|
|
|
if (!is_dir($sourcePath)) { |
167
|
|
|
return false; |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
foreach ($iterator = new \RecursiveIteratorIterator( |
171
|
|
|
new \RecursiveDirectoryIterator( |
172
|
|
|
$sourcePath, |
173
|
|
|
\RecursiveDirectoryIterator::SKIP_DOTS |
174
|
|
|
), |
175
|
|
|
\RecursiveIteratorIterator::SELF_FIRST |
176
|
|
|
) as $item) { |
177
|
|
|
$filePath = PATH_ROOT . DS . $directory . DS . $iterator->getSubPathName(); |
178
|
|
|
|
179
|
|
|
if ($item->isDir()) { |
180
|
|
|
if (is_dir($filePath)) { |
181
|
|
|
$this->installer->getIo()->write( |
182
|
|
|
" - <comment>Directory `{$iterator->getSubPathName()}` already exists</comment>", |
183
|
|
|
true, |
184
|
|
|
IOInterface::VERBOSE |
185
|
|
|
); |
186
|
|
|
} else { |
187
|
|
|
mkdir($filePath, self::PERMISSION_CODE); |
188
|
|
|
$this->installer->getIo()->write( |
189
|
|
|
" - Created directory `{$iterator->getSubPathName()}`", |
190
|
|
|
true, |
191
|
|
|
IOInterface::VERBOSE |
192
|
|
|
); |
193
|
|
|
} |
194
|
|
|
} else { |
195
|
|
|
if (file_exists($filePath)) { |
196
|
|
|
$this->installer->getIo()->write( |
197
|
|
|
" - <comment>File `{$iterator->getSubPathName()}` already exists</comment>", |
198
|
|
|
true, |
199
|
|
|
IOInterface::VERBOSE |
200
|
|
|
); |
201
|
|
|
} else { |
202
|
|
|
copy($item, $filePath); |
203
|
|
|
$this->installer->getIo()->write( |
204
|
|
|
" - Copied file `{$iterator->getSubPathName()}`", |
205
|
|
|
true, |
206
|
|
|
IOInterface::VERBOSE |
207
|
|
|
); |
208
|
|
|
} |
209
|
|
|
} |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
return true; |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
/** |
216
|
|
|
* It recursively removes the files and directories |
217
|
|
|
* @return bool |
218
|
|
|
*/ |
219
|
|
|
protected function remove() |
220
|
|
|
{ |
221
|
|
|
$this->removeRecursive('application'); |
222
|
|
|
$this->removeRecursive('data'); |
223
|
|
|
$this->removeRecursive('public'); |
224
|
|
|
$this->removeRecursive('tests'); |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
/** |
228
|
|
|
* It recursively removes the files and directories |
229
|
|
|
* @param $directory |
230
|
|
|
* @return bool |
231
|
|
|
*/ |
232
|
|
|
protected function removeRecursive($directory) |
233
|
|
|
{ |
234
|
|
|
$sourcePath = $this->installer->getOption('vendorPath') . DS . $directory; |
235
|
|
|
|
236
|
|
|
if (!is_dir($sourcePath)) { |
237
|
|
|
return false; |
238
|
|
|
} |
239
|
|
|
foreach ($iterator = new \RecursiveIteratorIterator( |
240
|
|
|
new \RecursiveDirectoryIterator( |
241
|
|
|
$sourcePath, |
242
|
|
|
\RecursiveDirectoryIterator::SKIP_DOTS |
243
|
|
|
), |
244
|
|
|
\RecursiveIteratorIterator::CHILD_FIRST |
245
|
|
|
) as $item) { |
246
|
|
|
// path to copied file |
247
|
|
|
$current = PATH_ROOT . DS . $directory . DS . $iterator->getSubPathName(); |
248
|
|
|
|
249
|
|
|
// remove empty directories |
250
|
|
View Code Duplication |
if (is_dir($current)) { |
|
|
|
|
251
|
|
|
if (sizeof(scandir($current)) == 2) { |
252
|
|
|
rmdir($current); |
253
|
|
|
$this->installer->getIo()->write( |
254
|
|
|
" - Removed directory `{$iterator->getSubPathName()}`", |
255
|
|
|
true, |
256
|
|
|
IOInterface::VERBOSE |
257
|
|
|
); |
258
|
|
|
} else { |
259
|
|
|
$this->installer->getIo()->write( |
260
|
|
|
" - <comment>Skip directory `{$iterator->getSubPathName()}`</comment>", |
261
|
|
|
true, |
262
|
|
|
IOInterface::VERBOSE |
263
|
|
|
); |
264
|
|
|
} |
265
|
|
|
continue; |
266
|
|
|
} |
267
|
|
|
|
268
|
|
|
// skip already removed files |
269
|
|
|
if (!is_file($current)) { |
270
|
|
|
continue; |
271
|
|
|
} |
272
|
|
|
|
273
|
|
View Code Duplication |
if (md5_file($item) == md5_file($current)) { |
|
|
|
|
274
|
|
|
// remove file |
275
|
|
|
unlink($current); |
276
|
|
|
$this->installer->getIo()->write( |
277
|
|
|
" - Removed file `{$iterator->getSubPathName()}`", |
278
|
|
|
true, |
279
|
|
|
IOInterface::VERBOSE |
280
|
|
|
); |
281
|
|
|
} else { |
282
|
|
|
// or skip changed files |
283
|
|
|
$this->installer->getIo()->write( |
284
|
|
|
" - <comment>File `{$iterator->getSubPathName()}` has changed</comment>", |
285
|
|
|
true, |
286
|
|
|
IOInterface::VERBOSE |
287
|
|
|
); |
288
|
|
|
} |
289
|
|
|
} |
290
|
|
|
|
291
|
|
|
return false; |
292
|
|
|
} |
293
|
|
|
} |
294
|
|
|
|
This class constant has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.