Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Plugin.php
Go to the documentation of this file.
1 <?php
10 
11 use Composer\Autoload\AutoloadGenerator;
12 use Composer\Autoload\ClassMapGenerator;
13 use Composer\EventDispatcher\EventDispatcher;
14 use RecursiveDirectoryIterator;
15 use RecursiveIteratorIterator;
16 use Composer\Composer;
17 use Composer\IO\IOInterface;
18 use Composer\Package\PackageInterface;
19 use Composer\Plugin\PluginInterface;
20 use Composer\Plugin\PluginEvents;
21 use Composer\EventDispatcher\EventSubscriberInterface;
22 use Composer\Script\ScriptEvents;
23 use Composer\Installer\PackageEvents;
24 use Composer\Util\Filesystem;
25 use Symfony\Component\Process\Process;
26 
27 class Plugin implements PluginInterface, EventSubscriberInterface
28 {
29 
33  protected $io;
34 
35 
39  protected $config;
40 
41 
45  protected $deployManager;
46 
47 
51  protected $composer;
52 
56  private $installer;
57 
61  protected $filesystem;
62 
66  private $regenerate = '/.regenerate';
67 
71  private $varFolder = '/var';
72 
73  protected function initDeployManager(Composer $composer, IOInterface $io)
74  {
75  $this->deployManager = new DeployManager($io);
76 
77  $extra = $composer->getPackage()->getExtra();
78  $sortPriority = isset($extra['magento-deploy-sort-priority']) ? $extra['magento-deploy-sort-priority'] : array();
79  $this->deployManager->setSortPriority($sortPriority);
80 
81  }
82 
83 
84  public function activate(Composer $composer, IOInterface $io)
85  {
86  $this->io = $io;
87  $this->composer = $composer;
88  $this->filesystem = new Filesystem();
89  $this->config = new ProjectConfig($composer->getPackage()->getExtra());
90  $this->installer = new Installer($io, $composer);
91  $this->initDeployManager($composer, $io);
92  $this->installer->setDeployManager($this->deployManager);
93  $this->installer->setConfig($this->config);
94  if ($this->io->isDebug()) {
95  $this->io->write('activate magento plugin');
96  }
97  $composer->getInstallationManager()->addInstaller($this->installer);
98  }
99 
100  public static function getSubscribedEvents()
101  {
102  return array(
103  PluginEvents::COMMAND => array(
104  array('onCommandEvent', 0),
105  ),
106  ScriptEvents::POST_INSTALL_CMD => array(
107  array('onNewCodeEvent', 0),
108  ),
109  ScriptEvents::POST_UPDATE_CMD => array(
110  array('onNewCodeEvent', 0),
111  ),
112  PackageEvents::POST_PACKAGE_UNINSTALL => array(
113  array('onPackageUnistall', 0),
114  )
115  );
116  }
117 
118  public function onPackageUnistall(\Composer\Installer\PackageEvent $event)
119  {
120  $ds = DIRECTORY_SEPARATOR;
121  $package = $event->getOperation()->getPackage();
122  list($vendor, $packageName) = explode('/', $package->getPrettyName());
123  $packageName = trim(str_replace('module-', '', $packageName));
124  $packageInstallationPath = $packageInstallationPath = $this->installer->getTargetDir();
125  $packagePath = ucfirst($vendor) . $ds . str_replace(' ', '', ucwords(str_replace('-', ' ', $packageName)));
126  $this->io->write("Removing $packagePath");
127  $libPath = 'lib' . $ds . 'internal' . $ds . $packagePath;
128  $magentoPackagePath = 'app' . $ds . 'code' . $ds . $packagePath;
129  $deployStrategy = $this->installer->getDeployStrategy($package);
130  $deployStrategy->rmdirRecursive($packageInstallationPath . $ds . $libPath);
131  $deployStrategy->rmdirRecursive($packageInstallationPath . $ds . $magentoPackagePath);
132  $this->requestRegeneration();
133  }
134 
140  public function onCommandEvent(\Composer\Plugin\CommandEvent $event)
141  {
142  $command = $event->getCommandName();
143  }
144 
150  public function onNewCodeEvent(\Composer\Script\Event $event)
151  {
152  if ($this->io->isDebug()) {
153  $this->io->write('start magento deploy via deployManager');
154  }
155 
156  $this->deployManager->doDeploy();
157  $this->deployLibraries();
158  $this->saveVendorDirPath($event->getComposer());
159  $this->requestRegeneration();
160  $this->setFilePermissions();
161  }
162 
168  private function setFilePermissions()
169  {
170  $packages = $this->composer->getRepositoryManager()->getLocalRepository()->getPackages();
171  $message = 'Check "chmod" section in composer.json of %s package.';
172 
173  foreach ($packages as $package) {
174  $extra = $package->getExtra();
175  if (!isset($extra['chmod']) || !is_array($extra['chmod'])) {
176  continue;
177  }
178 
179  $error = false;
180  foreach ($extra['chmod'] as $chmod) {
181  if (!isset($chmod['mask']) || !isset($chmod['path']) || strpos($chmod['path'], '..') !== false) {
182  $error = true;
183  continue;
184  }
185 
186  $file = $this->installer->getTargetDir() . '/' . $chmod['path'];
187  if (file_exists($file)) {
188  chmod($file, octdec($chmod['mask']));
189  } else {
190  $this->io->writeError([
191  'File doesn\'t exist: ' . $chmod['path'],
192  sprintf($message, $package->getName())
193  ]);
194  }
195  }
196 
197  if ($error) {
198  $this->io->writeError([
199  'Incorrect mask or file path.',
200  sprintf($message, $package->getName())
201  ]);
202  }
203  }
204  }
205 
206  protected function deployLibraries()
207  {
208  $packages = $this->composer->getRepositoryManager()->getLocalRepository()->getPackages();
209  $autoloadDirectories = array();
210 
211  $libraryPath = $this->config->getLibraryPath();
212  if ($libraryPath === null) {
213  if ($this->io->isDebug()) {
214  $this->io->write('jump over deployLibraries as no Magento libraryPath is set');
215  }
216  return;
217  }
218 
219 
220  $vendorDir = rtrim($this->composer->getConfig()->get('vendor-dir'), '/');
221 
223  $filesystem->removeDirectory($libraryPath);
224  $filesystem->ensureDirectoryExists($libraryPath);
225 
226  foreach ($packages as $package) {
228  $packageConfig = $this->config->getLibraryConfigByPackagename($package->getName());
229  if ($packageConfig === null) {
230  continue;
231  }
232  if (!isset($packageConfig['autoload'])) {
233  $packageConfig['autoload'] = array('/');
234  }
235  foreach ($packageConfig['autoload'] as $path) {
236  $autoloadDirectories[] = $libraryPath . '/' . $package->getName() . "/" . $path;
237  }
238  if ($this->io->isDebug()) {
239  $this->io->write('Magento deployLibraries executed for ' . $package->getName());
240  }
241  $libraryTargetPath = $libraryPath . '/' . $package->getName();
242  $filesystem->removeDirectory($libraryTargetPath);
243  $filesystem->ensureDirectoryExists($libraryTargetPath);
244  $this->copyRecursive($vendorDir . '/' . $package->getPrettyName(), $libraryTargetPath);
245 
246  }
247 
248  $autoloadGenerator = new AutoloadGenerator(new EventDispatcher($this->composer, $this->io));
249  $classmap = ClassMapGenerator::createMap($libraryPath);
250  $executable = $this->composer->getConfig()->get('bin-dir') . '/phpab';
251  if (!file_exists($executable)) {
252  $executable = $this->composer->getConfig()->get('vendor-dir') . '/theseer/autoload/composer/bin/phpab';
253  }
254  if (file_exists($executable)) {
255  if ($this->io->isDebug()) {
256  $this->io->write('Magento deployLibraries executes autoload generator');
257  }
258  $process = new Process($executable . " -o {$libraryPath}/autoload.php " . implode(' ', $autoloadDirectories));
259  $process->run();
260  } else {
261  if ($this->io->isDebug()) {
262  $this->io->write('Magento deployLibraries autoload generator not availabel, you should require "theseer/autoload"');
263  var_dump($executable, getcwd());
264 
265  }
266  }
267 
268 
269  }
270 
271 
283  protected function copyRecursive($source, $target)
284  {
285  $it = new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS);
286  $ri = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::SELF_FIRST);
287  $this->filesystem->ensureDirectoryExists($target);
288 
289  foreach ($ri as $file) {
290  $targetPath = $target . DIRECTORY_SEPARATOR . $ri->getSubPathName();
291  if ($file->isDir()) {
292  $this->filesystem->ensureDirectoryExists($targetPath);
293  } else {
294  copy($file->getPathname(), $targetPath);
295  }
296  }
297 
298  }
299 
306  private function saveVendorDirPath(Composer $composer)
307  {
308  $magentoDir = $this->installer->getTargetDir();
309  $vendorDirPath = $this->filesystem->findShortestPath(
310  $magentoDir,
311  realpath($composer->getConfig()->get('vendor-dir')),
312  true
313  );
314  $vendorPathFile = $magentoDir . '/app/etc/vendor_path.php';
315  $content = <<<AUTOLOAD
316 <?php
320 return '$vendorDirPath';
321 
322 AUTOLOAD;
323  file_put_contents($vendorPathFile, $content);
324  }
325 
331  private function requestRegeneration()
332  {
333  if (is_writable($this->installer->getTargetDir() . $this->varFolder)) {
334  $filename = $this->installer->getTargetDir() . $this->varFolder . $this->regenerate;
335  touch($filename);
336  }
337  }
338 }
if(!file_exists(VENDOR_PATH)) $vendorDir
Definition: autoload.php:25
$source
Definition: source.php:23
activate(Composer $composer, IOInterface $io)
Definition: Plugin.php:84
$target
Definition: skip.phtml:8
$message
onCommandEvent(\Composer\Plugin\CommandEvent $event)
Definition: Plugin.php:140
onNewCodeEvent(\Composer\Script\Event $event)
Definition: Plugin.php:150
is_writable($path)
Definition: io.php:25
onPackageUnistall(\Composer\Installer\PackageEvent $event)
Definition: Plugin.php:118
if(isset($opts->l)) $libraryPath
initDeployManager(Composer $composer, IOInterface $io)
Definition: Plugin.php:73
if( $_orders &&count( $_orders))( 'Orders') ?></caption >< thead >< tr >< th scopeforeach( $_orders as $_order)(__( 'Order #')) ?>" class $extra
Definition: history.phtml:32