Newer
Older
<?php
namespace LakeDrops\Docker4Drupal;
use Composer\Package\PackageInterface;
use Composer\Composer;
use Composer\IO\IOInterface;
use Composer\Script\Event as ScriptEvent;
use LakeDrops\Component\Dotenv\Dotenv;
use LakeDrops\DockerTraefik\Traefik;

jurgenhaas
committed
use Symfony\Component\Yaml\Yaml;
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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
* @param bool $overwrite
public function configureProject($event, $overwrite = FALSE) {
// We only do the fancy stuff for developers
if (!$event->isDevMode()) {
return;
}
$options = $this->getOptions();
$fs = new Filesystem();
$installationManager = $this->composer->getInstallationManager();
if (isset($options['webroot'])) {
if (!$fs->exists($options['webroot'])) {
return;
}
$webRoot = $options['webroot'];
}
else {
$drupalCorePackage = $this->getDrupalCorePackage();
if (!$drupalCorePackage) {
// We are called too early, Drupal core is not available yet.
return;
}
$corePath = $installationManager->getInstallPath($drupalCorePackage);
// Directory where Drupal's index.php is located
$webRoot = dirname($corePath);
// Directory where the root project is being created
$projectRoot = getcwd();
// Directory where this plugin is being installed
$pluginRoot = $installationManager->getInstallPath($this->getPackage('lakedrops/docker4drupal'));

jurgenhaas
committed
// 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';
}
$twig_loader = new \Twig_Loader_Array([]);
$twig = new \Twig_Environment($twig_loader);

jurgenhaas
committed
foreach ($this->getFiles($projectRoot, $webRoot, $settingsPath) as $template => $def) {
if ($overwrite || !$fs->exists($file)) {
$twig_loader->setTemplate($template, file_get_contents($pluginRoot . '/templates/' . $template . '.twig'));
$rendered = $twig->render($template, $options);
if (!empty($def['add2yaml']) && isset($options[$template])) {
$yaml = Yaml::parse($rendered);
$yaml = array_merge_recursive($yaml, $options[$template]);
$rendered = Yaml::dump($yaml, 9, 2);
}
if ($fs->exists($file)) {
if (md5_file($file) == md5($rendered)) {
continue;
}
$orig_file = $file . '.orig';
if ($fs->exists($orig_file)) {
$fs->remove($orig_file);
}
$fs->rename($file, $orig_file);
if (!$orig_ignored) {
$this->git('ignore *.orig');
$orig_ignored = TRUE;
}
}
else {
$this->git('ignore ' . $template);
}

jurgenhaas
committed
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

jurgenhaas
committed
$settingsPhpFile = $settingsPath . '/settings.php';
if ($fs->exists(($settingsPhpFile))) {
$settingsPhp = file_get_contents($settingsPhpFile);
if (strpos($settingsPhp, 'settings.docker.php') === FALSE) {

jurgenhaas
committed
$settingsPhp .= "\n\nif (file_exists(__DIR__ . '/settings.docker.php')) {\n include __DIR__ . '/settings.docker.php';\n}\n";

jurgenhaas
committed
file_put_contents($settingsPhpFile, $settingsPhp);
}
$traefik = new Traefik($options['projectname']);
$traefik->update();

jurgenhaas
committed
protected function getFiles($projectRoot, $webRoot, $settingsPath) {

jurgenhaas
committed
'dest' => $projectRoot . '/' . $settingsPath,
'add2yaml' => TRUE,

jurgenhaas
committed
'aliases.drushrc.php' => [
'dest' => $projectRoot . '/drush',
],
'drushrc.php' => [
'dest' => $projectRoot . '/drush',
],
'aliases.yml' => [
'dest' => $projectRoot . '/drush',
'add2yaml' => TRUE,
],
'drush.yml' => [
'dest' => $projectRoot . '/drush',
'add2yaml' => TRUE,
];
}
/**
* Retrieve excludes from optional "extra" configuration.
*
* @return array
*/
protected function getOptions() {
$projectname = str_replace([' ', '-', '_', '.'], '', basename(getcwd()));
$env = new Dotenv('docker4drupal', $this->io);
$env->put('COMPOSE_PROJECT_NAME', $projectname);
$extra = $this->composer->getPackage()->getExtra() + ['docker4drupal' => []];
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
$options = NestedArray::mergeDeep([
'projectname' => $projectname,
'docker0' => [
'ip' => $this->getLocalIpv4('docker0'),
],
'live' => [
'root' => '',
'uri' => '',
'host' => '',
'user' => $env->receive('live_host_username', 'Remote username for host of the live site', getenv('USER')),
],
'drupal' => [
'version' => '8',
],
'php' => [
'version' => '7.0',
'xdebug' => 1,
],
'webserver' => [
'type' => 'nginx',
'version' => '1.13',
],
'varnish' => [
'enable' => 0,
],
'redis' => [
'version' => '4.0',
],
'adminer' => [
'version' => '4.3',
],
'solr' => [
'enable' => 0,
'version' => '6.6',
],
'node' => [
'enable' => 0,
'key' => '',
'path' => '',
],
'memcached' => [
'enable' => 0,
],
'rsyslog' => [
'enable' => 0,
],
'athenapdf' => [
'enable' => 0,
'key' => '',
],
'blackfire' => [
'enable' => 0,
'id' => '',
'token' => '',
],
'webgrind' => [
'enable' => 0,
],
], $extra['docker4drupal']);
return $options;
}
/**
* Wrapper for git command in the root directory.
*
* @param $command
* Git command name, arguments and/or options.
*/
protected function git($command) {
passthru(escapeshellcmd('git -c "user.email=d8-project@lakedrops.com" ' . $command));
private function getLocalIpv4($interface = NULL) {
$out = explode(PHP_EOL, shell_exec('LC_ALL=C /sbin/ifconfig'));
$local_addrs = array();
$ifname = 'unknown';
foreach ($out as $str) {
$matches = array();
if (preg_match('/^([a-z0-9]+)(:\d{1,2})?(\s)+Link/', $str, $matches)) {
$ifname = $matches[1];
if(strlen($matches[2])>0) {
$ifname .= $matches[2];
}
} elseif (preg_match('/inet addr:((?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:[.](?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3})\s/', $str, $matches)) {
$local_addrs[$ifname] = $matches[1];
}
}
if (!isset($interface)) {
return $local_addrs;
}
return isset($local_addrs[$interface]) ? $local_addrs[$interface] : '127.0.0.1';
}