From 9ffbd882dbd941ca874d31daace80e86dbb60382 Mon Sep 17 00:00:00 2001
From: Rajab Natshah <rajabn@gmail.com>
Date: Sat, 31 Dec 2016 18:45:38 +0200
Subject: [PATCH] Issue #2839841: Updated [Varbase 8.4.x] Profile: Updated the
 Installation process  with [Extra components, Assemble extra components] to
 let site builders enable listed features on install

---
 src/Form/AssemblerForm.php       | 142 +++++++++++++++++++++++++++++++
 src/Form/AssemblerFormHelper.php |  45 ++++++++++
 varbase.profile                  |  53 +++++++++++-
 varbase.services.yml             |   5 ++
 4 files changed, 243 insertions(+), 2 deletions(-)
 create mode 100644 src/Form/AssemblerForm.php
 create mode 100644 src/Form/AssemblerFormHelper.php
 create mode 100644 varbase.services.yml

diff --git a/src/Form/AssemblerForm.php b/src/Form/AssemblerForm.php
new file mode 100644
index 00000000..4458fb8d
--- /dev/null
+++ b/src/Form/AssemblerForm.php
@@ -0,0 +1,142 @@
+<?php
+
+namespace Drupal\varbase\Form;
+
+use Drupal\Core\Extension\ExtensionDiscovery;
+use Drupal\Core\Extension\InfoParserInterface;
+use Drupal\Core\Form\FormBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\Element;
+use Drupal\Core\StringTranslation\TranslationInterface;
+use Drupal\varbase\Form\AssemblerFormHelper;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Defines a form for selecting Varbase's extra compoennts for the assembler to install.
+ */
+class AssemblerForm extends FormBase {
+
+  /**
+   * The Drupal application root.
+   *
+   * @var string
+   */
+  protected $root;
+
+  /**
+   * The info parser service.
+   *
+   * @var \Drupal\Core\Extension\InfoParserInterface
+   */
+  protected $infoParser;
+
+  /**
+   * The form helper.
+   *
+   * @var \Drupal\varbase\AssemblerFormHelper
+   */
+  protected $formHelper;
+
+  /**
+   * AssemblerForm constructor.
+   *
+   * @param \Drupal\varbase\Extender $extender
+   *   The Varbase extender configuration object.
+   * @param string $root
+   *   The Drupal application root.
+   * @param \Drupal\Core\Extension\InfoParserInterface $info_parser
+   *   The info parser service.
+   * @param \Drupal\Core\StringTranslation\TranslationInterface $translator
+   *   The string translation service.
+   * @param \Drupal\varbase\FormHelper $form_helper
+   *   The form helper.
+   */
+  public function __construct($root, InfoParserInterface $info_parser, TranslationInterface $translator, AssemblerFormHelper $assembler_form_helper) {
+    $this->root = $root;
+    $this->infoParser = $info_parser;
+    $this->stringTranslation = $translator;
+    $this->formHelper = $assembler_form_helper;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+    $container->get('app.root'),
+    $container->get('info_parser'),
+    $container->get('string_translation'),
+    $container->get('varbase.assembler_form_helper')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'varbase_extra_components';
+  }
+
+  /**
+   * Get info for each of Varbase's Extra Components.
+   * And make sure that we do have the extra component in the files.
+   */
+  protected function getExtraComponentsInfo() {
+    $component_discovery = new ExtensionDiscovery($this->root);
+    $extra_components_to_assemble = array(
+      'varbase_development',
+    );
+
+    $combined_extra_components = array_combine($extra_components_to_assemble, $extra_components_to_assemble);
+    $extra_components = array_intersect_key($component_discovery->scan('module'),$combined_extra_components);
+
+    foreach ($extra_components as $key => $extra_component) {
+      $extra_component_info = $this->infoParser->parse($extra_component->getPathname());
+      yield $key => $extra_component_info;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state, array &$install_state = NULL) {
+    $form['#title'] = $this->t('Extra components');
+    $form['extra_components_introduction'] = [
+      '#weight' => -1,
+      '#prefix' => '<p>',
+      '#markup' => $this->t("Select extra components, so that they will be assembled and installed."),
+      '#suffix' => '</p>',
+    ];
+    $form['extra_components'] = [
+      '#type' => 'checkboxes',
+      '#weight' => 0,
+      '#options' => array(),
+    ];
+    $form['actions'] = [
+      'continue' => [
+        '#type' => 'submit',
+        '#value' => $this->t('Assemble and install'),
+      ],
+      '#type' => 'actions',
+      '#weight' => 5,
+    ];
+
+
+    foreach ($this->getExtraComponentsInfo() as $key => $info) {
+      $form['extra_components']['#options'][$key] = $info['name'];
+    }
+
+    return $form;
+  }
+
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    $extra_components = $form_state->getValue('extra_components');
+    $extra_components = array_filter($extra_components);
+    $GLOBALS['install_state']['varbase']['extra_components'] = $extra_components;
+  }
+
+}
diff --git a/src/Form/AssemblerFormHelper.php b/src/Form/AssemblerFormHelper.php
new file mode 100644
index 00000000..d1b87627
--- /dev/null
+++ b/src/Form/AssemblerFormHelper.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace Drupal\varbase\Form;
+
+use Drupal\Core\Render\ElementInfoManagerInterface;
+
+/**
+ * Assembler form helper.
+ */
+class AssemblerFormHelper {
+
+  /**
+   * The element info plugin manager.
+   *
+   * @var \Drupal\Core\Render\ElementInfoManagerInterface
+   */
+  protected $elementInfo;
+
+  /**
+   * AssemblerFormHelper constructor.
+   *
+   * @param \Drupal\Core\Render\ElementInfoManagerInterface $element_info
+   *   Element info plugin manager.
+   */
+  public function __construct(ElementInfoManagerInterface $element_info) {
+    $this->elementInfo = $element_info;
+  }
+
+  /**
+   * Applies standard process for elements in the assembler form.
+   *
+   * @param array $element
+   *   Form element.
+   */
+  public function applyStandardProcessing(array &$element) {
+    if (empty($element['#process'])) {
+      $info = $this->elementInfo->getInfo($element['#type']);
+
+      if (isset($info['#process'])) {
+        $element['#process'] = $info['#process'];
+      }
+    }
+  }
+
+}
diff --git a/varbase.profile b/varbase.profile
index 2e51d277..99bfb4be 100644
--- a/varbase.profile
+++ b/varbase.profile
@@ -5,6 +5,7 @@
  */
 
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\varbase\Form\AssemblerForm;
 
 /**
  * Implements hook_form_FORM_ID_alter() for install_configure_form().
@@ -18,10 +19,58 @@ function varbase_form_install_configure_form_alter(&$form, FormStateInterface $f
   // Default site email noreply@vardot.com .
   $form['site_information']['site_mail']['#default_value'] = 'noreply@vardot.com';
   $form['site_information']['site_mail']['#attributes']['style'] = 'width: 25em;';
-  
+
   // Default user 1 username should be 'webmaster'.
   $form['admin_account']['account']['name']['#default_value'] = 'webmaster';
   $form['admin_account']['account']['name']['#attributes']['disabled'] = TRUE;
   $form['admin_account']['account']['mail']['#default_value'] = 'webmaster@vardot.com';
   $form['admin_account']['account']['mail']['#description'] = t('In most case, and for <a target="_blank" href="@link">Vardot</a> specific use, we recommend this to always be <em>webmaster@vardot.com</em>.', array('@link' => 'http://vardot.com'));
-}
\ No newline at end of file
+}
+
+/**
+ * Implements hook_install_tasks().
+ */
+function varbase_install_tasks() {
+  return array(
+    'varbase_extra_components' => array(
+      'display_name' => t('Extra components'),
+      'display' => TRUE,
+      'type' => 'form',
+      'function' => AssemblerForm::class,
+    ),
+    'varbase_assemble_extra_components' => array(
+      'display_name' => t('Assemble extra components'),
+      'display' => TRUE,
+      'type' => 'batch',
+    ),
+  );
+}
+
+/**
+ * Batch job to assemble Varbase extra components.
+ *
+ * @param array $install_state
+ *   The current install state.
+ *
+ * @return array
+ *   The batch job definition.
+ */
+function varbase_assemble_extra_components(array &$install_state) {
+  $batch = array();
+  foreach ($install_state['varbase']['extra_components'] as $extra_component) {
+    $batch['operations'][] = ['varbase_assemble_extra_component_then_install', (array) $extra_component];
+  }
+  return $batch;
+}
+
+/**
+ * Batch function to assemble needed extra components then install them.
+ *
+ * @param string|array $extra_component
+ *   Name of the extra component
+ */
+function varbase_assemble_extra_component_then_install($extra_component) {
+  // TODO: Add the function of fetching extra components
+  // if they are not attached with Varbase Core.
+  \Drupal::service('module_installer')->install((array) $extra_component);
+}
diff --git a/varbase.services.yml b/varbase.services.yml
new file mode 100644
index 00000000..b4bc27be
--- /dev/null
+++ b/varbase.services.yml
@@ -0,0 +1,5 @@
+services:
+  varbase.assembler_form_helper:
+    class: '\Drupal\varbase\Form\AssemblerFormHelper'
+    arguments:
+      - '@element_info'
-- 
GitLab