76b5ec2da310bb78745410bea7b001ef3d009486
[yaffs-website] / web / modules / contrib / ctools / src / Form / RequiredContext.php
1 <?php
2
3 namespace Drupal\ctools\Form;
4
5 use Drupal\Component\Plugin\PluginManagerInterface;
6 use Drupal\Core\Ajax\AjaxResponse;
7 use Drupal\Core\Ajax\OpenModalDialogCommand;
8 use Drupal\Core\Form\FormBase;
9 use Drupal\Core\Form\FormStateInterface;
10 use Drupal\Core\Url;
11 use Symfony\Component\DependencyInjection\ContainerInterface;
12
13 abstract class RequiredContext extends FormBase {
14
15   /**
16    * @var \Drupal\Core\TypedData\TypedDataManager
17    */
18   protected $typedDataManager;
19
20   /**
21    * @var string
22    */
23   protected $machine_name;
24
25   /**
26    * {@inheritdoc}
27    */
28   public static function create(ContainerInterface $container) {
29     return new static($container->get('typed_data_manager'));
30   }
31
32   public function __construct(PluginManagerInterface $typed_data_manager) {
33     $this->typedDataManager = $typed_data_manager;
34   }
35
36   /**
37    * {@inheritdoc}
38    */
39   public function getFormId() {
40     return 'ctools_required_context_form';
41   }
42
43   /**
44    * {@inheritdoc}
45    */
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';
50     $options = [];
51     foreach ($this->typedDataManager->getDefinitions() as $plugin_id => $definition) {
52       $options[$plugin_id] = (string) $definition['label'];
53     }
54     $form['items'] = array(
55       '#type' => 'markup',
56       '#prefix' => '<div id="configured-contexts">',
57       '#suffix' => '</div>',
58       '#theme' => 'table',
59       '#header' => array($this->t('Information'), $this->t('Description'), $this->t('Operations')),
60       '#rows' => $this->renderContexts($cached_values),
61       '#empty' => $this->t('No required contexts have been configured.')
62     );
63     $form['contexts'] = [
64       '#type' => 'select',
65       '#options' => $options,
66     ];
67     $form['add'] = [
68       '#type' => 'submit',
69       '#name' => 'add',
70       '#value' => $this->t('Add required context'),
71       '#ajax' => [
72         'callback' => [$this, 'add'],
73         'event' => 'click',
74       ],
75       '#submit' => [
76         'callback' => [$this, 'submitform'],
77       ]
78     ];
79     return $form;
80   }
81
82   /**
83    * {@inheritdoc}
84    */
85   public function submitForm(array &$form, FormStateInterface $form_state) {
86     $cached_values = $form_state->getTemporaryValue('wizard');
87     list($route_name, $route_parameters) = $this->getOperationsRouteInfo($cached_values, $this->machine_name, $form_state->getValue('contexts'));
88     $form_state->setRedirect($route_name . '.edit', $route_parameters);
89   }
90
91   /**
92    * Custom ajax form submission handler.
93    *
94    * @param array $form
95    * @param \Drupal\Core\Form\FormStateInterface $form_state
96    *
97    * @return \Drupal\Core\Ajax\AjaxResponse
98    */
99   public function add(array &$form, FormStateInterface $form_state) {
100     $context = $form_state->getValue('contexts');
101     $content = \Drupal::formBuilder()->getForm($this->getContextClass(), $context, $this->getTempstoreId(), $this->machine_name);
102     $content['#attached']['library'][] = 'core/drupal.dialog.ajax';
103     $response = new AjaxResponse();
104     $response->addCommand(new OpenModalDialogCommand($this->t('Configure Required Context'), $content, array('width' => '700')));
105     return $response;
106   }
107
108   /**
109    * @param $cached_values
110    *
111    * @return array
112    */
113   public function renderContexts($cached_values) {
114     $configured_contexts = array();
115     foreach ($this->getContexts($cached_values) as $row => $context) {
116       list($plugin_id, $label, $machine_name, $description) = array_values($context);
117       list($route_name, $route_parameters) = $this->getOperationsRouteInfo($cached_values, $cached_values['id'], $row);
118       $build = array(
119         '#type' => 'operations',
120         '#links' => $this->getOperations($route_name, $route_parameters),
121       );
122       $configured_contexts[] = array(
123         $this->t('<strong>Label:</strong> @label<br /> <strong>Type:</strong> @type', ['@label' => $label, '@type' => $plugin_id]),
124         $this->t('@description', ['@description' => $description]),
125         'operations' => [
126           'data' => $build,
127         ],
128       );
129     }
130     return $configured_contexts;
131   }
132
133   protected function getOperations($route_name_base, array $route_parameters = array()) {
134     $operations['edit'] = array(
135       'title' => $this->t('Edit'),
136       'url' => new Url($route_name_base . '.edit', $route_parameters),
137       'weight' => 10,
138       'attributes' => array(
139         'class' => array('use-ajax'),
140         'data-accepts' => 'application/vnd.drupal-modal',
141         'data-dialog-options' => json_encode(array(
142           'width' => 700,
143         )),
144       ),
145       'ajax' => [
146         ''
147       ],
148     );
149     $route_parameters['id'] = $route_parameters['context'];
150     $operations['delete'] = array(
151       'title' => $this->t('Delete'),
152       'url' => new Url($route_name_base . '.delete', $route_parameters),
153       'weight' => 100,
154       'attributes' => array(
155         'class' => array('use-ajax'),
156         'data-accepts' => 'application/vnd.drupal-modal',
157         'data-dialog-options' => json_encode(array(
158           'width' => 700,
159         )),
160       ),
161     );
162     return $operations;
163   }
164
165   /**
166    * Return a subclass of '\Drupal\ctools\Form\ContextConfigure'.
167    *
168    * The ContextConfigure class is designed to be subclassed with custom route
169    * information to control the modal/redirect needs of your use case.
170    *
171    * @return string
172    */
173   abstract protected function getContextClass();
174
175   /**
176    * Provide the tempstore id for your specified use case.
177    *
178    * @return string
179    */
180   abstract protected function getTempstoreId();
181
182   /**
183    * Document the route name and parameters for edit/delete context operations.
184    *
185    * The route name returned from this method is used as a "base" to which
186    * ".edit" and ".delete" are appeneded in the getOperations() method.
187    * Subclassing '\Drupal\ctools\Form\ContextConfigure' and
188    * '\Drupal\ctools\Form\RequiredContextDelete' should set you up for using
189    * this approach quite seamlessly.
190    *
191    * @param mixed $cached_values
192    *
193    * @param string $machine_name
194    *
195    * @param string $row
196    *
197    * @return array
198    *   In the format of
199    *   return ['route.base.name', ['machine_name' => $machine_name, 'context' => $row]];
200    */
201   abstract protected function getOperationsRouteInfo($cached_values, $machine_name, $row);
202
203   /**
204    * Custom logic for retrieving the contexts array from cached_values.
205    *
206    * @param $cached_values
207    *
208    * @return array
209    */
210   abstract protected function getContexts($cached_values);
211
212 }