Paragraphs Editor
ParagraphEntityForm.php
Go to the documentation of this file.
1 <?php
2 
4 
15 
16 /**
17  * The form that is shown for editing paragraph entities in ckeditor.
18  *
19  * This is basically just the core content entity form with a few overrides to
20  * ajaxify the experience and integrate with the delivery provider plugin
21  * system.
22  */
23 class ParagraphEntityForm extends ContentEntityForm {
24 
25  /**
26  * The context the editor command is being executed in.
27  *
28  * @var \Drupal\paragraphs_editor\EditorCommand\CommandContextInterface
29  */
30  protected $context;
31 
32  /**
33  * The buffer item being edited by this form.
34  *
35  * @var \Drupal\paragraphs_editor\EditBuffer\EditBufferItemInterface
36  */
37  protected $bufferItem;
38 
39  /**
40  * The widget binder data compiler service.
41  *
42  * @var \Drupal\paragraphs_editor\WidgetBinder\WidgetBinderDataCompilerInterface
43  */
44  protected $dataCompiler;
45 
46  /**
47  * Creates a ParagraphEntityForm object.
48  *
49  * @param \Drupal\paragraphs_editor\EditorCommand\CommandContextInterface $context
50  * The context of the command that is invoking this form.
51  * @param \Drupal\paragraphs_editor\EditBuffer\EditBufferItemInterface $item
52  * An editor item (wrapped paragraph entity) to show the edit form for.
53  * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
54  * The module handler service.
55  * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
56  * The entity type manager service.
57  * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
58  * The entity manager service.
59  * @param \Drupal\paragraphs_editor\WidgetBinder\WidgetBinderDataCompilerInterface $data_compiler
60  * The widget binder data compiler service.
61  */
64  ModuleHandlerInterface $module_handler,
65  EntityTypeManagerInterface $entity_type_manager,
66  EntityManagerInterface $entity_manager,
67  WidgetBinderDataCompilerInterface $data_compiler) {
68 
69  // The ContentEntityForm class actually has a whole bunch of hidden
70  // dependendencies. They are injected by core via setters, however we
71  // explicitly use constructor injection here to make them clear. I realize
72  // this is ugly, but at least its clear (I hope).
73  // The code we rely on still uses the old (deprecated) EntityManager. We
74  // will rely on the standard EntityTypeManager within this class.
75  parent::__construct($entity_manager);
76 
77  // Inject dependencies for parent classes.
78  $this->setEntityTypeManager($entity_type_manager);
79  $this->setModuleHandler($module_handler);
80  $this->setEntity($item->getEntity());
81 
82  // Set dependencies for this class.
83  $this->context = $context;
84  $this->bufferItem = $item;
85  $this->dataCompiler = $data_compiler;
86  }
87 
88  /**
89  * Rebuilds the additional temporary context key value pairs in the context.
90  *
91  * @param \Drupal\Core\Form\FormStateInterface $form_state
92  * The form state to bootstrap the additional context from.
93  *
94  * @return \Drupal\paragraphs_editor\EditorCommand\CommandContextInterface
95  * The bootstrapped context.
96  */
97  protected function bootstrapContext(FormStateInterface $form_state) {
98  $saved = $form_state->getValue('paragraphs_editor_additional_context');
99  if ($saved) {
100  $saved = unserialize($saved);
101  foreach ($saved as $key => $value) {
102  $this->context->addAdditionalContext($key, $value);
103  }
104  }
105 
106  return $this->context;
107  }
108 
109  /**
110  * {@inheritdoc}
111  */
112  public function form(array $form, FormStateInterface $form_state) {
113  $form = parent::form($form, $form_state);
114  $form['paragraphs_editor_additional_context'] = [
115  '#type' => 'hidden',
116  '#default_value' => serialize($this->bootstrapContext($form_state)->getAdditionalContext()),
117  ];
118  return $form;
119  }
120 
121  /**
122  * {@inheritdoc}
123  */
124  public function save(array $form, FormStateInterface $form_state) {
125  $context = $this->bootstrapContext($form_state);
126 
127  // Save the changes to the editor buffer.
128  $this->bufferItem->overwrite(TypeUtility::ensureParagraph($this->entity));
129  $this->bufferItem->save();
130 
131  // Make properties available to the static ajax handler.
132  $form_state->setTemporaryValue(['paragraphs_editor', 'data'], $this->dataCompiler->compile($context, $this->bufferItem));
133  $form_state->setTemporaryValue(['paragraphs_editor', 'context'], $this->context);
134  }
135 
136  /**
137  * {@inheritdoc}
138  */
139  protected function actions(array $form, FormStateInterface $form_state) {
140  $actions = parent::actions($form, $form_state);
141 
142  // Make the default entity save button submit via ajax.
143  $actions['submit']['#ajax'] = [
144  'callback' => [get_class($this), 'ajaxSubmit'],
145  ];
146 
147  // Provide a cancel link for users to cancel the edit operation.
148  $url = $this->context->createCommandUrl('cancel');
149  $actions['cancel'] = [
150  '#type' => 'button',
151  '#value' => $this->t('Cancel'),
152  '#weight' => 10,
153  '#ajax' => [
154  'url' => $url,
155  'options' => $url->getOptions(),
156  ],
157  ];
158 
159  unset($actions['delete']);
160 
161  return $actions;
162  }
163 
164  /**
165  * Handles submissions via ajax.
166  *
167  * @param array $form
168  * The complete form render array.
169  * @param \Drupal\Core\Form\FormStateInterface $form_state
170  * The associated form state.
171  *
172  * @return \Drupal\Core\Ajax\AjaxResponse
173  * An ajax response object that delivers a rendered paragraph.
174  */
175  public static function ajaxSubmit(array $form, FormStateInterface $form_state) {
176  // Retrieve class mambers needed to build a response.
177  $data = $form_state->getTemporaryValue(['paragraphs_editor', 'data']);
178  $delivery = $form_state->getTemporaryValue(['paragraphs_editor', 'context'])->getPlugin('delivery_provider');
179 
180  // Create a response that includes the rendered paragraph and signal that
181  // the ajax workflow is completed.
182  $response = new AjaxResponse();
183  $delivery->sendData($response, $data);
184  $delivery->close($response);
185 
186  return $response;
187  }
188 
189 }
static ensureParagraph(EntityInterface $entity=NULL)
Definition: TypeUtility.php:23
actions(array $form, FormStateInterface $form_state)
__construct(CommandContextInterface $context, EditBufferItemInterface $item, ModuleHandlerInterface $module_handler, EntityTypeManagerInterface $entity_type_manager, EntityManagerInterface $entity_manager, WidgetBinderDataCompilerInterface $data_compiler)
save(array $form, FormStateInterface $form_state)
static ajaxSubmit(array $form, FormStateInterface $form_state)
form(array $form, FormStateInterface $form_state)