<?php /** * @file * Contains \LakeDrops\Docker4Drupal\Handler. */ namespace LakeDrops\Docker4Drupal; use Composer\Package\PackageInterface; use Composer\Composer; use Composer\IO\IOInterface; use Composer\Script\Event as ScriptEvent; use Symfony\Component\Filesystem\Filesystem; use Rych\Random\Random; use Rych\Random\Encoder\Base64Encoder; class Handler { /** * @var \Composer\Composer */ protected $composer; /** * @var \Composer\IO\IOInterface */ protected $io; /** * @var PackageInterface */ protected $drupalCorePackage; /** * Handler constructor. * * @param Composer $composer * @param IOInterface $io */ public function __construct(Composer $composer, IOInterface $io) { $this->composer = $composer; $this->io = $io; } /** * Look up the Drupal core package object, or return it from where we cached * it in the $drupalCorePackage field. * * @return PackageInterface */ protected function getDrupalCorePackage() { if (!isset($this->drupalCorePackage)) { $this->drupalCorePackage = $this->getPackage('drupal/core'); } return $this->drupalCorePackage; } /** * Retrieve a package from the current composer process. * * @param string $name * Name of the package to get from the current composer installation. * * @return PackageInterface */ protected function getPackage($name) { return $this->composer->getRepositoryManager()->getLocalRepository()->findPackage($name, '*'); } /** * Configure Drupal Project for Docker. * * @param ScriptEvent $event */ public function configureProject($event) { // We only do the fancy stuff for developers if (!$event->isDevMode()) { return; } $options = $this->getOptions(); $fs = new Filesystem(); $installationManager = $this->composer->getInstallationManager(); $drupalCorePackage = $this->getDrupalCorePackage(); $corePath = $installationManager->getInstallPath($drupalCorePackage); // Directory where the root project is being created $projectRoot = getcwd(); // Directory where Drupal's index.php is located $webRoot = dirname($corePath); // Directory where this plugin is being installed $pluginRoot = $installationManager->getInstallPath($this->getPackage('lakedrops/docker4drupal')); // If the d8-project-scaffold plugin is present we only execute this one // if $force is TRUE. This way we can make sure that we get executed after // d8-project-scaffold. $settingsPath = $webRoot . '/sites/default'; if ($this->getPackage('lakedrops/d8-project-scaffold')) { if (!$fs->exists($projectRoot . '/settings/default')) { return; } $settingsPath = 'settings/default'; } // Link Drupal site's settings files $twig_loader = new \Twig_Loader_Array([]); $twig = new \Twig_Environment($twig_loader); foreach ($this->getFiles($projectRoot, $webRoot, $settingsPath) as $template => $def) { $file = $def['dest'] . '/' . $template; if (!$fs->exists($file)) { $twig_loader->setTemplate($template, file_get_contents($pluginRoot . '/templates/' . $template . '.twig')); $rendered = $twig->render($template, $options); file_put_contents($file, $rendered); } if (isset($def['link']) && ($def['link'] != $settingsPath)) { $link = $def['link'] . '/' . $template; if (!$fs->exists($link)) { $rel = substr($fs->makePathRelative($file, $projectRoot . '/' . $link), 3, -1); $fs->symlink($rel, $link); } } $fs->chmod($file, 0664); } // Make sure that settings.docker.php gets called from settings.php $settingsPhpFile = $settingsPath . '/settings.php'; if ($fs->exists(($settingsPhpFile))) { $settingsPhp = file_get_contents($settingsPhpFile); if (strpos($settingsPhp, 'settings.docker.php') === FALSE) { $settingsPhp .= "\n\nif (file_exists(__DIR__ . '/settings.docker.php')) {include __DIR__ . '/settings.docker.php';}\n"; file_put_contents($settingsPhpFile, $settingsPhp); } } // Initialize local git working copy try { $this->git('ignore docker-compose.yml'); $this->git('ignore settings.docker.php'); } catch (\Exception $ex) { // We're ignoring this for now } } protected function getFiles($projectRoot, $webRoot, $settingsPath) { return [ 'settings.docker.php' => [ 'dest' => $projectRoot . '/' . $settingsPath, 'link' => $webRoot . '/sites/default', ], 'docker-compose.yml' => [ 'dest' => $projectRoot, ], ]; } /** * Retrieve excludes from optional "extra" configuration. * * @return array */ protected function getOptions() { $extra = $this->composer->getPackage()->getExtra() + ['docker4drupal' => []]; $options = $extra['docker4drupal'] + [ 'port' => 8000, 'drupal' => [ 'version' => '8', ], 'php' => [ 'version' => '7.0',# 5.3|5.6|7.1 'xdebug' => 1, ], 'nginx' => [ 'version' => '1.10', ], 'varnish' => [ 'enable' => 0, ], 'solr' => [ 'enable' => 0, ], 'node' => [ 'enable' => 0, ], ]; return $options; } /** * Wrapper for git command in the root directory. * * @param $command * Git command name, arguments and/or options. * @throws \Exception */ protected function git($command) { passthru(escapeshellcmd('git -c "user.email=d8-project@lakedrops.com" ' . $command), $exit_code); if ($exit_code !== 0) { throw new \Exception('Git returned a non-zero exit code'); } } }