Пример #1
0
 /**
  * The callback function of the event `ScriptEvents::PRE_AUTOLOAD_DUMP`
  *
  * @param Event $event The Composer event
  *
  * @return void
  *
  * @throws \InvalidArgumentException with Symfony\Component\Finder\Finder
  * @throws \RuntimeException with Composer\Config
  */
 public function findRewrite(Event $event)
 {
     $toRewrite = array();
     $composer = $event->getComposer();
     $config = $this->config;
     $allPath = array();
     $packages = $composer->getRepositoryManager()->getLocalRepository()->getPackages();
     $autoloads = $composer->getAutoloadGenerator()->parseAutoloads($composer->getAutoloadGenerator()->buildPackageMap($composer->getInstallationManager(), $composer->getPackage(), $packages), $composer->getPackage());
     $worker = new Worker();
     $worker->setCacheDir($config->has('rewrite-dir') ? $config->get('rewrite-dir') : $config->get('vendor-dir') . DIRECTORY_SEPARATOR . '_rewrite');
     $this->output('very-verbose', 'Clear rewriters cache');
     $worker->clearCache();
     foreach ($autoloads as $loaderType => $package) {
         if (!in_array($loaderType, array('psr-4', 'psr-0'), true)) {
             continue;
         }
         foreach ($package as $packageName => $paths) {
             $this->output('very-verbose', 'Analysing namespace "%s" (%s)', array($packageName, $loaderType));
             if (in_array($packageName, $this->getIgnoreNamespace($composer), true)) {
                 $this->output('very-verbose', '  <info>(skipped)</info>');
                 continue;
             }
             /**
              * The file in reading
              *
              * @var SplFileInfo $file
              */
             foreach (Finder::create()->in(array_values($paths))->exclude($worker->getCacheDir())->name('*.php')->ignoreDotFiles(true)->ignoreVCS(true)->ignoreUnreadableDirs(true)->files() as $file) {
                 $this->output('debug', '- On file "%s"', array($file->getRealPath()));
                 if (in_array(Rewriter::class, Getter::readFromFile($file->getRealPath(), Getter::TYPE_INTERFACES), true)) {
                     $this->output('very-verbose', ' - Find "<info>%s</info>" rewriting "<comment>%s</comment>"', array(Getter::getFQCN($file->getRealPath()), Getter::readFromFile($file->getRealPath(), Getter::TYPE_PARENT_NAME)));
                     /**
                      * The FQCN of the parent class (the rewritten FQCN)
                      *
                      * @var string $parentFQCN
                      */
                     $parentFQCN = Getter::readFromFile($file->getRealPath(), Getter::TYPE_PARENT_NAME);
                     $toRewrite[$parentFQCN] = $file->getRealPath();
                     continue;
                 }
                 $allPath[$file->getRealPath()] = Getter::getFQCN($file->getRealPath());
             }
         }
     }
     $allPath = array_filter($allPath, function ($value) use($toRewrite) {
         return array_key_exists($value, $toRewrite);
     });
     $this->output('verbose', 'Build rewrite class cache');
     $allPath = array_flip($allPath);
     foreach ($toRewrite as $parentClassName => $rewriteFile) {
         $this->output('very-verbose', ' - For class "<info>%s</info>" (rewriting "<comment>%s</comment>")', array(Getter::getFQCN($rewriteFile), $parentClassName));
         $worker->rewriteClass($allPath[$parentClassName], $rewriteFile);
     }
     $this->output('verbose', 'Add rewrite class in Composer Autoload');
     $autoload = $composer->getPackage()->getAutoload();
     $autoload['classmap'][] = $worker->getCacheDir();
     $composer->getPackage()->setAutoload($autoload);
 }
Пример #2
0
 /**
  * Rewrite a class
  *
  * @param string $parentFile      The path to the parent class (rewritten class)
  * @param string $replacementFile The path to the replacement class (rewriter class)
  *
  * @return void
  */
 public function rewriteClass($parentFile, $replacementFile)
 {
     // Adding a 'C' at the begin to avoid issue with '\' (namespace separator)
     $parentHash = 'C' . sha1_file($parentFile);
     // Adding a 'C' at the begin to avoid issue with '\' (namespace separator)
     $replacementHash = 'C' . sha1_file($replacementFile);
     $namespace = Getter::readFromFile($parentFile, Getter::TYPE_NAMESPACE);
     $className = Getter::readFromFile($parentFile, Getter::TYPE_SHORT_NAME);
     $parentFCQN = $namespace . '\\' . $parentHash;
     file_put_contents($this->cacheDir . DIRECTORY_SEPARATOR . $parentHash . '.php', $this->rebuildClass($parentFile, null, $parentHash));
     file_put_contents($this->cacheDir . DIRECTORY_SEPARATOR . $replacementHash . '.php', $this->rebuildClass($replacementFile, null, $className, '\\' . $parentFCQN));
     $this->rewritten[$replacementHash . '.php'] = $namespace . '\\' . $className;
 }