3 namespace Drupal\ctools\Form;
6 use Drupal\Component\Plugin\PluginManagerInterface;
7 use Drupal\Component\Serialization\Json;
8 use Drupal\Core\Ajax\AjaxResponse;
9 use Drupal\Core\Ajax\OpenModalDialogCommand;
10 use Drupal\Core\Form\FormBase;
11 use Drupal\Core\Form\FormBuilderInterface;
12 use Drupal\Core\Form\FormStateInterface;
14 use Symfony\Component\DependencyInjection\ContainerInterface;
16 abstract class ManageConditions extends FormBase {
19 * @var \Drupal\Core\Condition\ConditionManager
26 protected $machine_name;
28 public static function create(ContainerInterface $container) {
29 return new static($container->get('plugin.manager.condition'));
32 function __construct(PluginManagerInterface $manager) {
33 $this->manager = $manager;
39 public function getFormId() {
40 return 'ctools_manage_conditions_form';
46 public function buildForm(array $form, FormStateInterface $form_state) {
47 $cached_values = $form_state->getTemporaryValue('wizard');
48 $this->machine_name = $cached_values['id'];
49 $form['#attached']['library'][] = 'core/drupal.dialog.ajax';
51 $contexts = $this->getContexts($cached_values);
52 foreach ($this->manager->getDefinitionsForContexts($contexts) as $plugin_id => $definition) {
53 $options[$plugin_id] = (string) $definition['label'];
55 $form['items'] = array(
57 '#prefix' => '<div id="configured-conditions">',
58 '#suffix' => '</div>',
60 '#header' => array($this->t('Plugin Id'), $this->t('Summary'), $this->t('Operations')),
61 '#rows' => $this->renderRows($cached_values),
62 '#empty' => $this->t('No required conditions have been configured.')
64 $form['conditions'] = [
66 '#options' => $options,
71 '#value' => $this->t('Add Condition'),
73 'callback' => [$this, 'add'],
77 'callback' => [$this, 'submitForm'],
86 public function submitForm(array &$form, FormStateInterface $form_state) {
87 $cached_values = $form_state->getTemporaryValue('wizard');
88 list(, $route_parameters) = $this->getOperationsRouteInfo($cached_values, $this->machine_name, $form_state->getValue('conditions'));
89 $form_state->setRedirect($this->getAddRoute($cached_values), $route_parameters);
92 public function add(array &$form, FormStateInterface $form_state) {
93 $condition = $form_state->getValue('conditions');
94 $content = \Drupal::formBuilder()->getForm($this->getConditionClass(), $condition, $this->getTempstoreId(), $this->machine_name);
95 $content['#attached']['library'][] = 'core/drupal.dialog.ajax';
96 $cached_values = $form_state->getTemporaryValue('wizard');
97 list(, $route_parameters) = $this->getOperationsRouteInfo($cached_values, $this->machine_name, $form_state->getValue('conditions'));
98 $content['submit']['#attached']['drupalSettings']['ajax'][$content['submit']['#id']]['url'] = $this->url($this->getAddRoute($cached_values), $route_parameters, ['query' => [FormBuilderInterface::AJAX_FORM_REQUEST => TRUE]]);
99 $response = new AjaxResponse();
100 $response->addCommand(new OpenModalDialogCommand($this->t('Configure Required Context'), $content, array('width' => '700')));
105 * @param $cached_values
109 public function renderRows($cached_values) {
110 $configured_conditions = array();
111 foreach ($this->getConditions($cached_values) as $row => $condition) {
112 /** @var $instance \Drupal\Core\Condition\ConditionInterface */
113 $instance = $this->manager->createInstance($condition['id'], $condition);
114 list($route_name, $route_parameters) = $this->getOperationsRouteInfo($cached_values, $cached_values['id'], $row);
116 '#type' => 'operations',
117 '#links' => $this->getOperations($route_name, $route_parameters),
119 $configured_conditions[] = array(
120 $instance->getPluginId(),
121 $instance->summary(),
127 return $configured_conditions;
130 protected function getOperations($route_name_base, array $route_parameters = array()) {
131 $operations['edit'] = array(
132 'title' => $this->t('Edit'),
133 'url' => new Url($route_name_base . '.edit', $route_parameters),
135 'attributes' => array(
136 'class' => ['use-ajax'],
137 'data-dialog-type' => 'modal',
138 'data-dialog-options' => Json::encode([
143 $route_parameters['id'] = $route_parameters['condition'];
144 $operations['delete'] = array(
145 'title' => $this->t('Delete'),
146 'url' => new Url($route_name_base . '.delete', $route_parameters),
148 'attributes' => array(
149 'class' => array('use-ajax'),
150 'data-dialog-type' => 'modal',
151 'data-dialog-options' => Json::encode([
160 * Return a subclass of '\Drupal\ctools\Form\ConditionConfigure'.
162 * The ConditionConfigure class is designed to be subclassed with custom
163 * route information to control the modal/redirect needs of your use case.
167 abstract protected function getConditionClass();
170 * The route to which condition 'add' actions should submit.
172 * @param mixed $cached_values
176 abstract protected function getAddRoute($cached_values);
179 * Provide the tempstore id for your specified use case.
183 abstract protected function getTempstoreId();
186 * Document the route name and parameters for edit/delete context operations.
188 * The route name returned from this method is used as a "base" to which
189 * ".edit" and ".delete" are appeneded in the getOperations() method.
190 * Subclassing '\Drupal\ctools\Form\ConditionConfigure' and
191 * '\Drupal\ctools\Form\ConditionDelete' should set you up for using this
192 * approach quite seamlessly.
194 * @param mixed $cached_values
196 * @param string $machine_name
202 * return ['route.base.name', ['machine_name' => $machine_name, 'context' => $row]];
204 abstract protected function getOperationsRouteInfo($cached_values, $machine_name, $row);
207 * Custom logic for retrieving the conditions array from cached_values.
209 * @param $cached_values
213 abstract protected function getConditions($cached_values);
216 * Custom logic for retrieving the contexts array from cached_values.
218 * @param $cached_values
220 * @return \Drupal\Core\Plugin\Context\ContextInterface[]
222 abstract protected function getContexts($cached_values);