You are here

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

Connect a site to a factory by setting up the right database variables.

@command acsf-connect-factory @aliases acsf-cf @option site-admin-mail The email address of the Site Factory admin / Gardens admin user. This is typically the "Site Factory admin" user on the factory. These email addresses have to match in order for the initial OpenID connection to bind these accounts. @option site-owner-name The name of the site owner. @option site-owner-mail The email address of the site owner. @option site-owner-roles A list of comma-separated roles (machine names) that should be granted to the site owner (optional). @usage drush acsf-connect-factory --site-admin-mail="user3@example.com" --site-owner-name="John Smith" --site-owner-mail="john.smith@example.com" Connect the site to the factory and sets the owner to John Smith. @bootstrap full

Parameters

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

Throws

\Drupal\acsf\AcsfException If the provided email address is invalid.

\InvalidArgumentException If one or more arguments are missing or invalid.

\Drush\Exceptions\UserAbortException If the customer does not allow the creation of a new account.

File

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

Class

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

Namespace

Drush\Commands

Code

public function connectFactory(array $options = [
  'site-admin-mail' => NULL,
  'site-owner-name' => NULL,
  'site-owner-mail' => NULL,
  'site-owner-roles' => NULL,
]) {

  // Preliminary validation before starting to modify the database.
  $site_admin_mail = trim($options['site-admin-mail']);
  $site_owner_name = trim($options['site-owner-name']);
  $site_owner_mail = trim($options['site-owner-mail']);
  $site_owner_roles = array_filter(explode(',', $options['site-owner-roles']));

  // Validate email addresses.
  $validator = \Drupal::service('email.validator');
  if (!$validator
    ->isValid($site_admin_mail)) {
    throw new \InvalidArgumentException(dt('The site-admin-mail value is not a valid email address.'));
  }
  if (!$validator
    ->isValid($site_owner_mail)) {
    throw new \InvalidArgumentException(dt('The site-owner-mail value is not a valid email address.'));
  }
  $user_storage = \Drupal::entityTypeManager()
    ->getStorage('user');

  // Make sure there is no regular user account with the admin email address.
  $site_admin_mail_accounts = $user_storage
    ->loadByProperties([
    'mail' => $site_admin_mail,
  ]);
  $site_admin_mail_account = reset($site_admin_mail_accounts);
  if ($site_admin_mail_account && $site_admin_mail_account
    ->id() > 1) {
    throw new AcsfException(dt('Unable to sync the admin account, the email address @mail is already used by the user account @uid.', [
      '@mail' => $site_admin_mail,
      '@uid' => $site_admin_mail_account
        ->id(),
    ]));
  }

  // The site owner's email address may have been changed on the factory (for
  // instance, if the user updated their email address on the factory and the
  // new email address has not yet been synced to the site). First, try to
  // locate the user account by site-owner-mail.
  $site_owner_accounts = $user_storage
    ->loadByProperties([
    'mail' => $site_owner_mail,
  ]);
  $site_owner_account = reset($site_owner_accounts);
  if ($site_owner_account && $site_owner_account
    ->getAccountName() !== $site_owner_name) {
    throw new AcsfException(dt('The site-owner-name value does not match the name of the user loaded by site-owner-mail.'));
  }

  // If the site owner user account is not found, try to locate it by
  // site-owner-name.
  if (!$site_owner_account) {
    $site_owner_accounts = $user_storage
      ->loadByProperties([
      'name' => $site_owner_name,
    ]);
    $site_owner_account = reset($site_owner_accounts);
  }

  // If the site owner account is still not found then either the customer has
  // made a typo or maybe there is going to be a new owner who needs a new
  // account. Ask for confirmation to create a new account.
  if (!$site_owner_account) {
    if (!$this
      ->io()
      ->confirm(dt('The site owner name or email address that you provided does not correspond to any account on the site. Do you want to create a new account?'))) {
      throw new UserAbortException();
    }
  }

  // Clear all caches ahead of time so Drupal has a chance to rebuild
  // registries.
  drupal_flush_all_caches();
  acsf_build_registry();
  $this
    ->logger()
    ->info(dt('Cleared all caches.'));

  // Set default settings for user accounts.
  $admin_role_ids = \Drupal::EntityQuery('user_role')
    ->condition('is_admin', TRUE)
    ->execute();

  // Take over uid 1 with our Site Factory admin user.
  $admin_account = User::load(1);

  // Create a new user if uid 1 doesn't exist.
  if (!$admin_account) {
    $admin_account = User::create([
      'uid' => 1,
    ]);
  }

  // Ensure the default admin role is added to the account.
  $admin_account
    ->addRole(reset($admin_role_ids));

  // Set login time to avoid e-mail verification needed error.
  $admin_account
    ->setLastLoginTime(1)
    ->setUsername('Site Factory admin')
    ->setEmail($site_admin_mail)
    ->setPassword(user_password())
    ->activate()
    ->save();

  // Create or update site owner account.
  // Prepare roles for site owner.
  if (!$site_owner_account) {
    $site_owner_account = User::create();
  }
  foreach ($site_owner_roles as $owner_role) {
    if (Role::load($owner_role)) {
      $site_owner_account
        ->addRole($owner_role);
    }
    else {
      $this
        ->logger()
        ->warning(dt('The role @role does not exist; not adding it to the site owner.', [
        '@role' => $owner_role,
      ]));
    }
  }

  // Site owners also get the default administrator role.
  $site_owner_account
    ->addRole(reset($admin_role_ids));
  $site_owner_account
    ->setLastLoginTime(1)
    ->setUsername($site_owner_name)
    ->setEmail($site_owner_mail)
    ->setPassword(user_password())
    ->activate()
    ->save();
  $this
    ->logger()
    ->info(dt('Synched Site Factory admin and site owner accounts.'));

  // Remove acsf variable so that it can be repopulated with the right value
  // on the next acsf-site-sync.
  \Drupal::service('acsf.variable_storage')
    ->delete('acsf_site_info');

  // Reset the local site data and run acsf-site-sync to fetch factory data
  // about the site.
  $site = AcsfSite::load();
  $site
    ->clean();
  \Drupal::service('acsf.commands')
    ->siteSync();
  $this
    ->logger()
    ->info(dt('Executed acsf-site-sync to gather site data from factory and reset all acsf variables.'));

  // Clear all caches.
  drupal_flush_all_caches();
  $this
    ->logger()
    ->info(dt('Cleared all caches.'));

  // Send a theme event notification to the Factory.
  \Drupal::service('acsf.theme_notification')
    ->sendNotification('site', 'create');
}