You are here

class FormConverter in Drupal 7 to 8/9 Module Upgrader 8

Converts a form from a set of callback functions to a class implementing \Drupal\Core\Form\FormInterface.

Hierarchy

Expanded class hierarchy of FormConverter

File

src/Utility/FormConverter.php, line 21

Namespace

Drupal\drupalmoduleupgrader\Utility
View source
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 bool
   */
  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;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
FormConverter::$builder protected property
FormConverter::$controller protected property
FormConverter::$formID protected property
FormConverter::$formStateRewriter protected property
FormConverter::$isConfig protected property
FormConverter::$submitHandler protected property
FormConverter::$target protected property
FormConverter::$validator protected property
FormConverter::addMethod protected function
FormConverter::build public function
FormConverter::render public function
FormConverter::__construct public function
StringTransformTrait::deleteLegacyWildcards public function Deletes %wildcards from a route path.
StringTransformTrait::deleteWildcards public function Deletes {wildcards} from a route path.
StringTransformTrait::getIdentifier public function Generates an identifier (prefixed with the module name, if $this->module exists) from an arbitrary string.
StringTransformTrait::getIdentifierFromLegacyPath public function Generates an identifier from a Drupal 7 path.
StringTransformTrait::getIdentifierFromPath public function Generates an identifier from a path.
StringTransformTrait::toCamelCase public function Converts a string toCamelCase :)
StringTransformTrait::toTitleCase public function Converts a string ToTitleCase.
StringTransformTrait::unPrefix public function Trims a prefix (as well as leading or trailing underscore, if any) from a string.
StringTransformTrait::unSuffix public function Trims a suffix (as well as leading underscore, if any) from a string.