Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / web / core / modules / migrate_drupal_ui / src / Form / CredentialForm.php
index cd767cc3d1d73c56fca61f07b650f5d97a09a983..169ac8c92297a0a8ade29993e26794514fc86058 100644 (file)
@@ -2,9 +2,12 @@
 
 namespace Drupal\migrate_drupal_ui\Form;
 
+use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\RendererInterface;
 use Drupal\Core\TempStore\PrivateTempStoreFactory;
+use GuzzleHttp\ClientInterface;
+use GuzzleHttp\Exception\TransferException;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -21,6 +24,20 @@ class CredentialForm extends MigrateUpgradeFormBase {
    */
   protected $renderer;
 
+  /**
+   * The HTTP client to fetch the files with.
+   *
+   * @var \GuzzleHttp\ClientInterface
+   */
+  protected $httpClient;
+
+  /**
+   * An array of error information.
+   *
+   * @var array
+   */
+  protected $errors = [];
+
   /**
    * CredentialForm constructor.
    *
@@ -28,10 +45,13 @@ class CredentialForm extends MigrateUpgradeFormBase {
    *   The renderer service.
    * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $tempstore_private
    *   The private tempstore factory.
+   * @param \GuzzleHttp\ClientInterface $http_client
+   *   A Guzzle client object.
    */
-  public function __construct(RendererInterface $renderer, PrivateTempStoreFactory $tempstore_private) {
+  public function __construct(RendererInterface $renderer, PrivateTempStoreFactory $tempstore_private, ClientInterface $http_client) {
     parent::__construct($tempstore_private);
     $this->renderer = $renderer;
+    $this->httpClient = $http_client;
   }
 
   /**
@@ -40,7 +60,8 @@ class CredentialForm extends MigrateUpgradeFormBase {
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('renderer'),
-      $container->get('tempstore.private')
+      $container->get('tempstore.private'),
+      $container->get('http_client')
     );
   }
 
@@ -75,6 +96,11 @@ class CredentialForm extends MigrateUpgradeFormBase {
 
     $default_options = [];
 
+    $form['help'] = [
+      '#type' => 'item',
+      '#description' => $this->t('Provide the information to access the Drupal site you want to upgrade. Files can be imported into the upgraded site as well.  See the <a href=":url">Upgrade documentation for more detailed instructions</a>.', [':url' => 'https://www.drupal.org/upgrade/migrate']),
+    ];
+
     $form['version'] = [
       '#type' => 'radios',
       '#default_value' => 7,
@@ -145,6 +171,7 @@ class CredentialForm extends MigrateUpgradeFormBase {
           ':input[name="version"]' => ['value' => '6'],
         ],
       ],
+      '#element_validate' => ['::validatePaths'],
     ];
 
     $form['source']['source_base_path'] = [
@@ -156,11 +183,12 @@ class CredentialForm extends MigrateUpgradeFormBase {
           ':input[name="version"]' => ['value' => '7'],
         ],
       ],
+      '#element_validate' => ['::validatePaths'],
     ];
 
     $form['source']['source_private_file_path'] = [
       '#type' => 'textfield',
-      '#title' => $this->t('Private file directory'),
+      '#title' => $this->t('Private files directory'),
       '#default_value' => '',
       '#description' => $this->t('To import private files from your current Drupal site, enter a local file directory containing your site (e.g. /var/www/docroot).'),
       '#states' => [
@@ -168,6 +196,7 @@ class CredentialForm extends MigrateUpgradeFormBase {
           ':input[name="version"]' => ['value' => '7'],
         ],
       ],
+      '#element_validate' => ['::validatePaths'],
     ];
 
     return $form;
@@ -177,7 +206,6 @@ class CredentialForm extends MigrateUpgradeFormBase {
    * {@inheritdoc}
    */
   public function validateForm(array &$form, FormStateInterface $form_state) {
-
     // Retrieve the database driver from the form, use reflection to get the
     // namespace, and then construct a valid database array the same as in
     // settings.php.
@@ -194,35 +222,61 @@ class CredentialForm extends MigrateUpgradeFormBase {
     // Validate the driver settings and just end here if we have any issues.
     if ($errors = $drivers[$driver]->validateDatabaseSettings($database)) {
       foreach ($errors as $name => $message) {
-        $form_state->setErrorByName($name, $message);
+        $this->errors[$name] = $message;
       }
-      return;
     }
-
-    try {
-      $connection = $this->getConnection($database);
-      $version = (string) $this->getLegacyDrupalVersion($connection);
-      if (!$version) {
-        $form_state->setErrorByName($database['driver'] . '][0', $this->t('Source database does not contain a recognizable Drupal version.'));
+    else {
+      try {
+        $connection = $this->getConnection($database);
+        $version = (string) $this->getLegacyDrupalVersion($connection);
+        if (!$version) {
+          $this->errors[$database['driver'] . '][database'] = $this->t('Source database does not contain a recognizable Drupal version.');
+        }
+        elseif ($version !== (string) $form_state->getValue('version')) {
+          $this->errors['version'] = $this->t('Source database is Drupal version @version but version @selected was selected.',
+            [
+              '@version' => $version,
+              '@selected' => $form_state->getValue('version'),
+            ]);
+        }
+        else {
+          // Setup migrations and save form data to private store.
+          $this->setupMigrations($database, $form_state);
+        }
       }
-      elseif ($version !== (string) $form_state->getValue('version')) {
-        $form_state->setErrorByName($database['driver'] . '][0', $this->t('Source database is Drupal version @version but version @selected was selected.', [
-          '@version' => $version,
-          '@selected' => $form_state->getValue('version'),
-        ]));
+      catch (\Exception $e) {
+        $this->errors[$database['driver'] . '][database'] = $e->getMessage();
       }
-      else {
-        // Setup migrations and save form data to private store.
-        $this->setupMigrations($database, $form_state);
+    }
+
+    // Display all errors as a list of items.
+    if ($this->errors) {
+      $form_state->setError($form, $this->t('<h3>Resolve all issues below to continue the upgrade.</h3>'));
+      foreach ($this->errors as $name => $message) {
+        $form_state->setErrorByName($name, $message);
       }
     }
-    catch (\Exception $e) {
-      $error_message = [
-        '#title' => $this->t('Resolve the issue below to continue the upgrade.'),
-        '#theme' => 'item_list',
-        '#items' => [$e->getMessage()],
-      ];
-      $form_state->setErrorByName($database['driver'] . '][0', $this->renderer->renderPlain($error_message));
+  }
+
+  /**
+   * The #element_validate handler for the source path elements.
+   *
+   * Ensures that entered path can be read.
+   */
+  public function validatePaths($element, FormStateInterface $form_state) {
+    if ($source = $element['#value']) {
+      $msg = $this->t('Unable to read from @title.', ['@title' => $element['#title']]);
+      if (UrlHelper::isExternal($source)) {
+        try {
+          $this->httpClient->head($source);
+        }
+        catch (TransferException $e) {
+          $this->errors[$element['#name']] = $msg . ' ' . $e->getMessage();
+        }
+      }
+      elseif (!file_exists($source) || (!is_dir($source)) || (!is_readable($source))) {
+        $this->errors[$element['#name']] = $msg;
+      }
     }
   }