Further modules included.
[yaffs-website] / web / modules / contrib / drupalmoduleupgrader / src / Utility / FormConverter.php
diff --git a/web/modules/contrib/drupalmoduleupgrader/src/Utility/FormConverter.php b/web/modules/contrib/drupalmoduleupgrader/src/Utility/FormConverter.php
new file mode 100644 (file)
index 0000000..9baf2ac
--- /dev/null
@@ -0,0 +1,178 @@
+<?php
+
+namespace Drupal\drupalmoduleupgrader\Utility;
+
+use Drupal\drupalmoduleupgrader\RewriterInterface;
+use Drupal\drupalmoduleupgrader\TargetInterface;
+use Pharborist\Filter;
+use Pharborist\Functions\FunctionCallNode;
+use Pharborist\Functions\FunctionDeclarationNode;
+use Pharborist\Functions\ParameterNode;
+use Pharborist\Objects\ClassMethodNode;
+use Pharborist\Objects\ClassNode;
+use Pharborist\Parser;
+use Pharborist\Token;
+use Pharborist\TokenNode;
+
+/**
+ * Converts a form from a set of callback functions to a class implementing
+ * \Drupal\Core\Form\FormInterface.
+ */
+class FormConverter {
+
+  use StringTransformTrait;
+
+  /**
+   * @var \Drupal\drupalmoduleupgrader\TargetInterface
+   */
+  protected $target;
+
+  /**
+   * @var string
+   */
+  protected $formID;
+
+  /**
+   * @var \Pharborist\Functions\FunctionDeclarationNode
+   */
+  protected $builder;
+
+  /**
+   * @var \Pharborist\Functions\FunctionDeclarationNode
+   */
+  protected $validator;
+
+  /**
+   * @var \Pharborist\Functions\FunctionDeclarationNode
+   */
+  protected $submitHandler;
+
+  /**
+   * @var boolean
+   */
+  protected $isConfig;
+
+  /**
+   * @var \Drupal\drupalmoduleupgrader\RewriterInterface
+   */
+  protected $formStateRewriter;
+
+  /**
+   * @var \Pharborist\Objects\ClassNode
+   */
+  protected $controller;
+
+  public function __construct(TargetInterface $target, $form_id, RewriterInterface $rewriter) {
+    $indexer = $target->getIndexer('function');
+
+    $this->target = $target;
+    $this->formID = $form_id;
+
+    $this->builder = $indexer->get($form_id);
+
+    $validator = $form_id . '_validate';
+    if ($indexer->has($validator)) {
+      $this->validator = $indexer->get($validator);
+    }
+    $submit_handler = $form_id . '_submit';
+    if ($indexer->has($submit_handler)) {
+      $this->submitHandler = $indexer->get($submit_handler);
+    }
+
+    $this->isConfig = $this->builder->has(Filter::isFunctionCall('system_settings_form'));
+    $this->formStateRewriter = $rewriter;
+  }
+
+  /**
+   * @return \Pharborist\Objects\ClassNode
+   */
+  public function render() {
+    if (empty($this->controller)) {
+      $render = [
+        '#theme' => 'dmu_form',
+        '#module' => $this->target->id(),
+        '#form_id' => $this->formID,
+        '#class' => $this->toTitleCase($this->formID),
+        '#config' => $this->isConfig,
+      ];
+      $source = \Drupal::service('renderer')->renderPlain($render);
+      $this->controller = Parser::parseSource($source)
+        ->find(Filter::isClass($render['#class']))->get(0);
+    }
+    return $this->controller;
+  }
+
+  /**
+   * @return \Pharborist\Objects\ClassNode
+   */
+  public function build() {
+    $controller = $this->render();
+
+    $builder = $this->addMethod($this->builder, $controller, 'buildForm');
+    if ($this->isConfig) {
+      $builder
+        ->find(Filter::isFunctionCall('system_settings_form'))
+        ->each(function(FunctionCallNode $call) {
+          $call
+            ->setName('parent::buildForm')
+            ->appendArgument(Token::variable('$form_state'));
+        });
+    }
+
+    if ($this->validator) {
+      $this
+        ->addMethod($this->validator, $controller, 'validateForm')
+        ->getParameterAtIndex(0)
+        ->setReference(TRUE)
+        ->setTypeHint('array');
+    }
+    if ($this->submitHandler) {
+      $this
+        ->addMethod($this->submitHandler, $controller, ($this->isConfig ? '_submitForm' : 'submitForm'))
+        ->getParameterAtIndex(0)
+        ->setReference(TRUE)
+        ->setTypeHint('array');
+    }
+
+    return $controller;
+  }
+
+  /**
+   * @return \Pharborist\Objects\ClassMethodNode
+   */
+  protected function addMethod(FunctionDeclarationNode $function, ClassNode $class, $alias = NULL) {
+    $method = ClassMethodNode::fromFunction($function);
+    if ($alias) {
+      $method->setName($alias);
+    }
+    $class->appendMethod($method);
+
+    // Add the parameters required for FormInterface conformance.
+    $parameters = $method->getParameters()->toArray();
+    if (empty($parameters)) {
+      $parameters[0] = ParameterNode::create('$form');
+      $method->appendParameter($parameters[0]);
+    }
+    if (sizeof($parameters) == 1) {
+      $parameters[1] = ParameterNode::create('$form_state');
+      $method->appendParameter($parameters[1]);
+    }
+
+    // The $form parameter must have the array type hint.
+    $parameters[0]->setTypeHint('array');
+
+    // The form state is never passed by reference.
+    $parameters[1]->setReference(FALSE);
+
+    // Additional parameters MUST have a default value of NULL in order to conform
+    // to FormInterface.
+    for ($i = 2; $i < sizeof($parameters); $i++) {
+      $parameters[$i]->setValue(new TokenNode(T_STRING, 'NULL'));
+    }
+
+    $this->formStateRewriter->rewrite($parameters[1]);
+
+    return $method;
+  }
+
+}