This repository has been archived on 2025-01-19. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
drupalcampbristol/web/vendor/drupal-composer/drupal-scaffold/src/Handler.php
2017-03-16 15:11:34 +00:00

365 lines
9.7 KiB
PHP

<?php
/**
* @file
* Contains \DrupalComposer\DrupalScaffold\Handler.
*/
namespace DrupalComposer\DrupalScaffold;
use Composer\Composer;
use Composer\DependencyResolver\Operation\InstallOperation;
use Composer\DependencyResolver\Operation\UpdateOperation;
use Composer\IO\IOInterface;
use Composer\Package\PackageInterface;
use Composer\EventDispatcher\EventDispatcher;
use Composer\Util\Filesystem;
use Composer\Util\RemoteFilesystem;
use Symfony\Component\Filesystem\Filesystem as SymfonyFilesystem;
class Handler {
const PRE_DRUPAL_SCAFFOLD_CMD = 'pre-drupal-scaffold-cmd';
const POST_DRUPAL_SCAFFOLD_CMD = 'post-drupal-scaffold-cmd';
/**
* @var \Composer\Composer
*/
protected $composer;
/**
* @var \Composer\IO\IOInterface
*/
protected $io;
/**
* @var \Composer\Package\PackageInterface
*/
protected $drupalCorePackage;
/**
* Handler constructor.
*
* @param Composer $composer
* @param IOInterface $io
*/
public function __construct(Composer $composer, IOInterface $io) {
$this->composer = $composer;
$this->io = $io;
}
/**
* @param $operation
* @return mixed
*/
protected function getCorePackage($operation) {
if ($operation instanceof InstallOperation) {
$package = $operation->getPackage();
}
elseif ($operation instanceof UpdateOperation) {
$package = $operation->getTargetPackage();
}
if (isset($package) && $package instanceof PackageInterface && $package->getName() == 'drupal/core') {
return $package;
}
return NULL;
}
/**
* Marks scaffolding to be processed after an install or update command.
*
* @param \Composer\Installer\PackageEvent $event
*/
public function onPostPackageEvent(\Composer\Installer\PackageEvent $event){
$package = $this->getCorePackage($event->getOperation());
if ($package) {
// By explicitly setting the core package, the onPostCmdEvent() will
// process the scaffolding automatically.
$this->drupalCorePackage = $package;
}
}
/**
* Post install command event to execute the scaffolding.
*
* @param \Composer\Script\Event $event
*/
public function onPostCmdEvent(\Composer\Script\Event $event) {
// Only install the scaffolding if drupal/core was installed,
// AND there are no scaffolding files present.
if (isset($this->drupalCorePackage)) {
$this->downloadScaffold();
// Generate the autoload.php file after generating the scaffold files.
$this->generateAutoload();
}
}
/**
* Downloads drupal scaffold files for the current process.
*/
public function downloadScaffold() {
$drupalCorePackage = $this->getDrupalCorePackage();
$webroot = realpath($this->getWebRoot());
// Collect options, excludes and settings files.
$options = $this->getOptions();
$files = array_diff($this->getIncludes(), $this->getExcludes());
// Call any pre-scaffold scripts that may be defined.
$dispatcher = new EventDispatcher($this->composer, $this->io);
$dispatcher->dispatch(self::PRE_DRUPAL_SCAFFOLD_CMD);
$version = $this->getDrupalCoreVersion($drupalCorePackage);
$remoteFs = new RemoteFilesystem($this->io);
$fetcher = new FileFetcher($remoteFs, $options['source'], $files);
$fetcher->fetch($version, $webroot);
$initialFileFetcher = new InitialFileFetcher($remoteFs, $options['source'], $this->getInitial());
$initialFileFetcher->fetch($version, $webroot);
// Call post-scaffold scripts.
$dispatcher->dispatch(self::POST_DRUPAL_SCAFFOLD_CMD);
}
/**
* Generate the autoload file at the project root. Include the
* autoload file that Composer generated.
*/
public function generateAutoload() {
$vendorPath = $this->getVendorPath();
$webroot = $this->getWebRoot();
// Calculate the relative path from the webroot (location of the
// project autoload.php) to the vendor directory.
$fs = new SymfonyFilesystem();
$relativeVendorPath = $fs->makePathRelative($vendorPath, realpath($webroot));
$fs->dumpFile($webroot . "/autoload.php", $this->autoLoadContents($relativeVendorPath));
}
/**
* Build the contents of the autoload file.
*
* @return string
*/
protected function autoLoadContents($relativeVendorPath) {
$relativeVendorPath = rtrim($relativeVendorPath, '/');
$autoloadContents = <<<EOF
<?php
/**
* @file
* Includes the autoloader created by Composer.
*
* This file was generated by drupal-composer/drupal-scaffold.
* https://github.com/drupal-composer/drupal-scaffold
*
* @see composer.json
* @see index.php
* @see core/install.php
* @see core/rebuild.php
* @see core/modules/statistics/statistics.php
*/
return require __DIR__ . '/$relativeVendorPath/autoload.php';
EOF;
return $autoloadContents;
}
/**
* Get the path to the 'vendor' directory.
*
* @return string
*/
public function getVendorPath() {
$config = $this->composer->getConfig();
$filesystem = new Filesystem();
$filesystem->ensureDirectoryExists($config->get('vendor-dir'));
$vendorPath = $filesystem->normalizePath(realpath($config->get('vendor-dir')));
return $vendorPath;
}
/**
* Look up the Drupal core package object, or return it from where we cached
* it in the $drupalCorePackage field.
*
* @return PackageInterface
*/
public function getDrupalCorePackage() {
if (!isset($this->drupalCorePackage)) {
$this->drupalCorePackage = $this->getPackage('drupal/core');
}
return $this->drupalCorePackage;
}
/**
* Returns the Drupal core version for the given package.
*
* @param \Composer\Package\PackageInterface $drupalCorePackage
*
* @return string
*/
protected function getDrupalCoreVersion(PackageInterface $drupalCorePackage) {
$version = $drupalCorePackage->getPrettyVersion();
if ($drupalCorePackage->getStability() == 'dev' && substr($version, -4) == '-dev') {
$version = substr($version, 0, -4);
return $version;
}
return $version;
}
/**
* Retrieve the path to the web root.
*
* @return string
*/
public function getWebRoot() {
$drupalCorePackage = $this->getDrupalCorePackage();
$installationManager = $this->composer->getInstallationManager();
$corePath = $installationManager->getInstallPath($drupalCorePackage);
// Webroot is the parent path of the drupal core installation path.
$webroot = dirname($corePath);
return $webroot;
}
/**
* 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, '*');
}
/**
* Retrieve excludes from optional "extra" configuration.
*
* @return array
*/
protected function getExcludes() {
return $this->getNamedOptionList('excludes', 'getExcludesDefault');
}
/**
* Retrieve list of additional settings files from optional "extra" configuration.
*
* @return array
*/
protected function getIncludes() {
return $this->getNamedOptionList('includes', 'getIncludesDefault');
}
/**
* Retrieve list of initial files from optional "extra" configuration.
*
* @return array
*/
protected function getInitial() {
return $this->getNamedOptionList('initial', 'getInitialDefault');
}
/**
* Retrieve a named list of options from optional "extra" configuration.
* Respects 'omit-defaults', and either includes or does not include the
* default values, as requested.
*
* @return array
*/
protected function getNamedOptionList($optionName, $defaultFn) {
$options = $this->getOptions($this->composer);
$result = array();
if (empty($options['omit-defaults'])) {
$result = $this->$defaultFn();
}
$result = array_merge($result, (array) $options[$optionName]);
return $result;
}
/**
* Retrieve excludes from optional "extra" configuration.
*
* @return array
*/
protected function getOptions() {
$extra = $this->composer->getPackage()->getExtra() + ['drupal-scaffold' => []];
$options = $extra['drupal-scaffold'] + [
'omit-defaults' => FALSE,
'excludes' => [],
'includes' => [],
'initial' => [],
'source' => 'http://cgit.drupalcode.org/drupal/plain/{path}?h={version}',
// Github: https://raw.githubusercontent.com/drupal/drupal/{version}/{path}
];
return $options;
}
/**
* Holds default excludes.
*/
protected function getExcludesDefault() {
return [];
}
/**
* Holds default settings files list.
*/
protected function getIncludesDefault() {
$version = $this->getDrupalCoreVersion($this->getDrupalCorePackage());
list($major, $minor) = explode('.', $version, 3);
$version = "$major.$minor";
/**
* Files from 8.3.x
*
* @see http://cgit.drupalcode.org/drupal/tree/?h=8.3.x
*/
$common = [
'.csslintrc',
'.editorconfig',
'.eslintignore',
'.eslintrc.json',
'.gitattributes',
'.htaccess',
'index.php',
'robots.txt',
'sites/default/default.settings.php',
'sites/default/default.services.yml',
'sites/development.services.yml',
'sites/example.settings.local.php',
'sites/example.sites.php',
'update.php',
'web.config'
];
// Version specific variations.
switch ($version) {
case '8.0':
case '8.1':
case '8.2':
$common[] = '.eslintrc';
$common = array_diff($common, ['.eslintrc.json']);
break;
}
sort($common);
return $common;
}
/**
* Holds default initial files.
*/
protected function getInitialDefault() {
return [];
}
}