3 namespace Drupal\ctools\Wizard;
5 use Drupal\Core\Form\FormBuilderInterface;
6 use Drupal\Core\Form\FormState;
7 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
9 class WizardFactory implements WizardFactoryInterface {
14 * @var \Drupal\Core\Form\FormBuilderInterface
19 * The event dispatcher.
21 * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
23 protected $dispatcher;
26 * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
28 * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
29 * The event dispatcher.
31 public function __construct(FormBuilderInterface $form_builder, EventDispatcherInterface $event_dispatcher) {
32 $this->builder = $form_builder;
33 $this->dispatcher = $event_dispatcher;
39 public function getWizardForm(FormWizardInterface $wizard, array $parameters = [], $ajax = FALSE) {
40 $form_state = $this->getFormState($wizard, $parameters, $ajax);
41 $form = $this->builder->buildForm($wizard, $form_state);
44 $form['#attached']['library'][] = 'core/drupal.dialog.ajax';
45 $status_messages = array('#type' => 'status_messages');
46 // @todo properly inject the renderer. Core should really be doing this work.
47 if ($messages = \Drupal::service('renderer')->renderRoot($status_messages)) {
48 if (!empty($form['#prefix'])) {
49 // Form prefix is expected to be a string. Prepend the messages to
51 $form['#prefix'] = '<div class="wizard-messages">' . $messages . '</div>' . $form['#prefix'];
59 * @param string $class
60 * A class name implementing FormWizardInterface.
61 * @param array $parameters
62 * The array of parameters specific to this wizard.
64 * @return \Drupal\ctools\Wizard\FormWizardInterface
66 public function createWizard($class, array $parameters) {
68 $reflection = new \ReflectionClass($class);
69 $constructor = $reflection->getMethod('__construct');
70 foreach ($constructor->getParameters() as $parameter) {
71 if (array_key_exists($parameter->name, $parameters)) {
72 $arguments[] = $parameters[$parameter->name];
74 elseif ($parameter->isDefaultValueAvailable()) {
75 $arguments[] = $parameter->getDefaultValue();
78 /** @var $wizard \Drupal\ctools\Wizard\FormWizardInterface */
79 $wizard = $reflection->newInstanceArgs($arguments);
84 * Get the wizard form state.
86 * @param \Drupal\ctools\Wizard\FormWizardInterface $wizard
88 * @param array $parameters
89 * The array of parameters specific to this wizard.
92 * @return \Drupal\Core\Form\FormState
94 public function getFormState(FormWizardInterface $wizard, array $parameters, $ajax = FALSE) {
95 $form_state = new FormState();
96 // If a wizard has no values, initialize them.
97 if (!$wizard->getMachineName() || !$wizard->getTempstore()->get($wizard->getMachineName())) {
98 $cached_values = $wizard->initValues();
99 // Save the cached values that were initialized.
100 if ($wizard->getMachineName()) {
101 $wizard->getTempstore()->set($wizard->getMachineName(), $cached_values);
105 $cached_values = $wizard->getTempstore()->get($wizard->getMachineName());
107 $form_state->setTemporaryValue('wizard', $cached_values);
108 $form_state->set('ajax', $ajax);
110 $parameters['form'] = [];
111 $parameters['form_state'] = $form_state;
112 $method = new \ReflectionMethod($wizard, 'buildForm');
114 foreach ($method->getParameters() as $parameter) {
115 if (array_key_exists($parameter->name, $parameters)) {
116 $arguments[] = $parameters[$parameter->name];
118 elseif ($parameter->isDefaultValueAvailable()) {
119 $arguments[] = $parameter->getDefaultValue();
122 unset($parameters['form'], $parameters['form_state']);
123 // Remove $form and $form_state from the arguments, and re-index them.
124 unset($arguments[0], $arguments[1]);
125 $form_state->addBuildInfo('args', array_values($arguments));