You are here

public function AcsfInitCommands::init in Acquia Cloud Site Factory Connector 8.2

Make this repository compatible with Acquia Site Factory.

Installs/updates the non-standard Drupal components for this repository to be compatible with Acquia Site Factory. This command will update in place, so there is no harm in running it multiple times.

@command acsf-init @option skip-default-settings Do not edit the default settings.php file. Use this option when the edited default settings.php is causing issues in a local environment. @bootstrap root

Parameters

array $options: The command options supplied to the executed command.

Throws

\Drupal\acsf\AcsfException If the command cannot be executed.

File

acsf_init/src/Commands/AcsfInitCommands.php, line 84

Class

AcsfInitCommands
Provides drush commands to set up a codebase for Acquia Cloud Site Factory.

Namespace

Drush\Commands

Code

public function init(array $options = [
  'skip-default-settings' => FALSE,
]) {
  $drupal_root = realpath(DRUPAL_ROOT);
  if (basename($drupal_root) !== 'docroot') {

    // If for some reason we wanted to enable this command to run on directory
    // structures where no /docroot exists, that's possible in theory... but
    // we need to to audit / change the code in this file to
    // - derive the repo root in a good way;
    // - properly distinguish the repo root from the drupal root;
    // - figure out what to do with remaining instances of "docroot", if any;
    // - figure out what to do when drupal root and repo root are equal...
    //   like not copy hook files?
    throw new AcsfException(dt("Drupal must be installed in a subdirectory of your code repository, named 'docroot'."));
  }
  $repo_root = dirname($drupal_root);
  $skip_default_settings = $options['skip-default-settings'];
  $this
    ->output()
    ->writeln(dt('Installing ACSF requirements.'));

  // Create the required directories.
  foreach ($this
    ->getRequiredDirs($repo_root) as $name => $dir) {

    // Skip '../sites/default' if --skip-default-settings is set.
    if ($skip_default_settings && $name == 'site env default') {
      continue;
    }
    $this
      ->output()
      ->writeln(dt('Creating directory for !name at !dir', [
      '!name' => $name,
      '!dir' => $dir,
    ]));
    if (!file_exists($dir)) {
      if (mkdir($dir, 0755, TRUE)) {
        $this
          ->logger()
          ->success(dt('Success'));
      }
      else {
        $this
          ->logger()
          ->error(dt('Error'));
      }
    }
    else {
      $this
        ->logger()
        ->notice(dt('Already Exists'));
    }
  }

  // Copy the required files.
  $lib_path = sprintf('%s/lib', dirname(dirname(dirname(__FILE__))));
  foreach ($this
    ->getRequiredFiles($repo_root) as $location) {
    $file = $location['filename'];
    $dest = sprintf('%s/%s', $location['dest'], $file);

    // Some files only contain a destination as they are already in place.
    if (isset($location['source']) && isset($location['dest'])) {
      $source = sprintf('%s/%s/%s', $lib_path, $location['source'], $file);
      $this
        ->output()
        ->writeln(dt('Copying !file to !dest.', [
        '!file' => $source,
        '!dest' => $dest,
      ]));
      if (file_exists($dest)) {
        $confirm = $this
          ->io()
          ->confirm(dt('Destination file exists, continue?'));
        if ($confirm === FALSE) {
          continue;
        }
      }

      // Copy the file into the destination.
      if (copy($source, $dest)) {
        $this
          ->logger()
          ->success(dt('Copy Success: !file', [
          '!file' => $file,
        ]));
      }
      else {
        $this
          ->logger()
          ->error(dt('Copy Error: !file', [
          '!file' => $file,
        ]));
      }

      // If the file exists, it could be set to 0444, so we have to ensure
      // that it is writable before overwriting it. The copy would fail
      // otherwise.
      if (!is_writable($dest)) {
        if (!chmod($dest, 0666)) {
          $this
            ->logger()
            ->error(dt('Chmod Error: !file', [
            '!file' => $file,
          ]));
        }
      }
    }

    // Chmod the file if required.
    $mod = isset($location['mod']) ? $location['mod'] : FALSE;
    if ($mod && chmod($dest, $mod)) {
      $this
        ->logger()
        ->success(dt('Chmod Success: !file', [
        '!file' => $file,
      ]));
    }
    elseif ($mod) {
      $this
        ->logger()
        ->error(dt('Chmod Error: !file', [
        '!file' => $file,
      ]));
    }
  }
  try {
    $this
      ->patchHtaccess();
  } catch (AcsfInitHtaccessException $e) {
    $this
      ->logger()
      ->error($e
      ->getMessage());
  }

  // The default settings.php file needs special handling. On the ACSF
  // infrastructure our own business logic needs to execute while on ACE or on
  // a local environment the default settings.php could be used to drive other
  // sites. For this reason the ACSF specific code will be included in the
  // file instead of rewriting it to contain only our code.
  if (!$skip_default_settings) {
    $this
      ->output()
      ->writeln(dt('Updating the default settings.php file with the ACSF specific business logic.'));
    $edit_allowed = TRUE;
    $default_settings_php_path = $repo_root . '/docroot/sites/default/settings.php';
    if (file_exists($default_settings_php_path)) {
      $edit_allowed = $this
        ->io()
        ->confirm(dt('Destination file exists, continue?'));
    }
    if ($edit_allowed !== FALSE) {

      // If the file exists, it could be set to 0444, so we have to ensure
      // that it is writable.
      if (file_exists($default_settings_php_path) && !is_writable($default_settings_php_path)) {
        if (!chmod($default_settings_php_path, 0666)) {
          $this
            ->logger()
            ->error(dt('Chmod Error: !file', [
            '!file' => $default_settings_php_path,
          ]));
        }
      }
      if (file_exists($default_settings_php_path)) {

        // If the current default settings.php file has the same content as
        // acsf.legacy.default.settings.php then this file can be rewritten
        // according to the new approach. A simple strict equality check
        // should be enough since the acsf-init-verify checked the deployed
        // files by comparing md5 hashes, so even a single character
        // difference would have caused an error in the code deployment
        // process.
        $current_default_settings_php = file_get_contents($default_settings_php_path);
        $legacy_default_settings_php = file_get_contents($lib_path . '/sites/default/acsf.legacy.default.settings.php');
        if ($current_default_settings_php === $legacy_default_settings_php) {
          $this
            ->defaultSettingsPhpCreate($default_settings_php_path);
        }
        else {

          // Update the default settings.php file with the latest ACSF code.
          $this
            ->defaultSettingsPhpUpdate($default_settings_php_path);
        }
      }
      else {

        // The default settings.php file does not exist yet, so create a new
        // file with the necessary include.
        $this
          ->defaultSettingsPhpCreate($default_settings_php_path);
      }
    }
  }

  // Verify that the files are in sync.
  clearstatcache();
  try {
    $this
      ->initVerify($options);
    $this
      ->output()
      ->writeln(dt("Be sure to commit any changes to your repository before deploying. This includes files like sites/default/settings.php; you can use 'git status --ignored' to make sure no changes are inadvertantly ignored by a custom git configuration."));
  } catch (AcsfException $e) {
    $this
      ->logger()
      ->error($e
      ->getMessage());
  }
}