3 namespace Drupal\ctools\Form;
5 use Drupal\Component\Serialization\Json;
6 use Drupal\Core\Ajax\AjaxResponse;
7 use Drupal\Core\Ajax\OpenModalDialogCommand;
8 use Drupal\Core\Form\FormBase;
9 use Drupal\Core\Form\FormBuilderInterface;
10 use Drupal\Core\Form\FormStateInterface;
13 abstract class ManageResolverRelationships extends FormBase {
18 protected $machine_name;
21 * An array of property types that are eligible as relationships.
25 protected $property_types = [];
30 public function getFormId() {
31 return 'ctools_manage_resolver_relationships_form';
37 public function buildForm(array $form, FormStateInterface $form_state) {
38 $cached_values = $form_state->getTemporaryValue('wizard');
39 $this->machine_name = $cached_values['id'];
40 $form['items'] = array(
42 '#prefix' => '<div id="configured-relationships">',
43 '#suffix' => '</div>',
45 '#header' => array($this->t('Context ID'), $this->t('Label'), $this->t('Data Type'), $this->t('Options')),
46 '#rows' => $this->renderRows($cached_values),
47 '#empty' => $this->t('No relationships have been added.')
50 $form['relationships'] = [
52 '#title' => $this->t('Add a relationship'),
53 '#options' => $this->getAvailableRelationships($cached_values),
55 $form['add_relationship'] = [
58 '#value' => $this->t('Add Relationship'),
60 'callback' => [$this, 'addRelationship'],
64 'callback' => [$this, 'submitForm'],
73 public function submitForm(array &$form, FormStateInterface $form_state) {
74 if ($form_state->getTriggeringElement()['#name'] == 'add') {
75 $cached_values = $form_state->getTemporaryValue('wizard');
76 list(, $route_parameters) = $this->getRelationshipOperationsRouteInfo($cached_values, $this->machine_name, $form_state->getValue('relationships'));
77 $form_state->setRedirect($this->getAddRoute($cached_values), $route_parameters);
81 public function addRelationship(array &$form, FormStateInterface $form_state) {
82 $relationship = $form_state->getValue('relationships');
83 $content = \Drupal::formBuilder()->getForm($this->getContextClass(), $relationship, $this->getTempstoreId(), $this->machine_name);
84 $content['#attached']['library'][] = 'core/drupal.dialog.ajax';
85 $cached_values = $form_state->getTemporaryValue('wizard');
86 list(, $route_parameters) = $this->getRelationshipOperationsRouteInfo($cached_values, $this->machine_name, $relationship);
87 $content['submit']['#attached']['drupalSettings']['ajax'][$content['submit']['#id']]['url'] = $this->url($this->getAddRoute($cached_values), $route_parameters, ['query' => [FormBuilderInterface::AJAX_FORM_REQUEST => TRUE]]);
88 $response = new AjaxResponse();
89 $response->addCommand(new OpenModalDialogCommand($this->t('Configure Relationship'), $content, array('width' => '700')));
93 protected function getAvailableRelationships($cached_values) {
94 /** @var \Drupal\ctools\TypedDataResolver $resolver */
95 $resolver = \Drupal::service('ctools.typed_data.resolver');
96 return $resolver->getTokensForContexts($this->getContexts($cached_values));
100 * @param $cached_values
104 protected function renderRows($cached_values) {
106 foreach ($this->getContexts($cached_values) as $row => $context) {
107 list($route_name, $route_parameters) = $this->getRelationshipOperationsRouteInfo($cached_values, $this->machine_name, $row);
109 '#type' => 'operations',
110 '#links' => $this->getOperations($cached_values, $row, $route_name, $route_parameters),
112 $contexts[$row] = array(
114 $context->getContextDefinition()->getLabel(),
115 $context->getContextDefinition()->getDataType(),
125 * @param array $cached_values
127 * @param string $route_name_base
128 * @param array $route_parameters
132 protected function getOperations($cached_values, $row, $route_name_base, array $route_parameters = array()) {
133 // Base contexts will not be a : separated and generated relationships should have 3 parts.
134 if (count(explode(':', $row)) < 2) {
137 $operations['edit'] = array(
138 'title' => $this->t('Edit'),
139 'url' => new Url($route_name_base . '.edit', $route_parameters),
141 'attributes' => array(
142 'class' => ['use-ajax'],
143 'data-dialog-type' => 'modal',
144 'data-dialog-options' => Json::encode([
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),
154 'attributes' => array(
155 'class' => array('use-ajax'),
156 'data-dialog-type' => 'modal',
157 'data-dialog-options' => Json::encode([
166 * Return a subclass of '\Drupal\ctools\Form\ResolverRelationshipConfigure'.
168 * The ConditionConfigure class is designed to be subclassed with custom
169 * route information to control the modal/redirect needs of your use case.
173 abstract protected function getContextClass($cached_values);
176 * The route to which relationship 'add' actions should submit.
180 abstract protected function getAddRoute($cached_values);
183 * Provide the tempstore id for your specified use case.
187 abstract protected function getTempstoreId();
190 * @param $cached_values
192 * @return \Drupal\Core\Plugin\Context\ContextInterface[]
194 abstract protected function getContexts($cached_values);
197 * @param string $cached_values
198 * @param string $machine_name
203 abstract protected function getRelationshipOperationsRouteInfo($cached_values, $machine_name, $row);