Paragraphs Editor
ItemGenerator.php
Go to the documentation of this file.
1 <?php
2 
4 
12 
13 /**
14  * Generates edit buffer item models for the widget binder library.
15  *
16  * The edit buffer item model contains the markup and information about editable
17  * child fields.
18  */
20 
21  /**
22  * {@inheritdoc}
23  */
24  public function id() {
25  return 'item';
26  }
27 
28  /**
29  * {@inheritdoc}
30  */
31  public function initialize(WidgetBinderData $data, WidgetBinderDataCompilerState $state, ParagraphInterface $root_paragraph) {
32  $state->set('field_map', []);
33  $state->set('field_map_stack', []);
34  }
35 
36  /**
37  * {@inheritdoc}
38  */
39  public function processParagraph(WidgetBinderData $data, WidgetBinderDataCompilerState $state, ParagraphInterface $paragraph) {
40  $top = $this->topPath($state);
41  if (!empty($top)) {
42  $this->pushPath($state, [
43  'type' => 'widget',
44  'uuid' => $paragraph->uuid(),
45  ]);
46  $this->savePath($state);
47  }
48  }
49 
50  /**
51  * {@inheritdoc}
52  */
53  public function postprocessParagraph(WidgetBinderData $data, WidgetBinderDataCompilerState $state, ParagraphInterface $paragraph) {
54  $this->popPath($state);
55  }
56 
57  /**
58  * {@inheritdoc}
59  */
60  public function processField(WidgetBinderData $data, WidgetBinderDataCompilerState $state, EntityReferenceFieldItemListInterface $items, $is_editor_field) {
61  $field_definition = TypeUtility::ensureFieldConfig($items->getFieldDefinition());
62  $path = [
63  'type' => 'field',
64  'name' => $field_definition->getName(),
65  ];
66 
67  $context_id = $data->getContextId($items->getEntity()->uuid(), $field_definition->id());
68  if ($context_id) {
69  $path['context'] = $context_id;
70  }
71 
72  $this->pushPath($state, $path);
73  if ($is_editor_field) {
74  $this->savePath($state);
75  }
76  }
77 
78  /**
79  * {@inheritdoc}
80  */
81  public function postprocessField(WidgetBinderData $data, WidgetBinderDataCompilerState $state, EntityReferenceFieldItemListInterface $items, $is_editor_field) {
82  $this->popPath($state);
83  }
84 
85  /**
86  * {@inheritdoc}
87  */
88  public function complete(WidgetBinderData $data, WidgetBinderDataCompilerState $state, RenderContext $render_context, $markup) {
89  $context = $state->getItemContext();
90  $paragraph = $state->getItem()->getEntity();
91 
92  $item_model = [
93  'contextId' => $context->getContextString(),
94  'markup' => $markup,
95  'type' => $paragraph->bundle(),
96  'fields' => $state->get('field_map'),
97  ];
98  if ($context->getAdditionalContext('command') == 'insert') {
99  $item_model['insert'] = 'true';
100  }
101 
102  $data->addModel('editBufferItem', $paragraph->uuid(), $item_model);
103  }
104 
105  /**
106  * Pushes a path node to the top of the map stack.
107  *
108  * @param \Drupal\paragraphs_editor\WidgetBinder\WidgetBinderDataCompilerState $state
109  * The current compiler state.
110  * @param array $data
111  * The path node to push.
112  */
113  protected function pushPath(WidgetBinderDataCompilerState $state, array $data) {
114  $stack = $state->get('field_map_stack');
115  $stack[] = $data;
116  $state->set('field_map_stack', $stack);
117  }
118 
119  /**
120  * Gets the path node at the top of the stack.
121  *
122  * @param \Drupal\paragraphs_editor\WidgetBinder\WidgetBinderDataCompilerState $state
123  * The current compiler state.
124  *
125  * @return array
126  * The top path node or NULL if no node exists.
127  */
128  protected function topPath(WidgetBinderDataCompilerState $state) {
129  $stack = $state->get('field_map_stack');
130  return $stack ? end($stack) : NULL;
131  }
132 
133  /**
134  * Pops a path node off the top of the map stack.
135  *
136  * @param \Drupal\paragraphs_editor\WidgetBinder\WidgetBinderDataCompilerState $state
137  * The current compiler state.
138  *
139  * @return array
140  * The popped path node or NULL if no node exists.
141  */
142  protected function popPath(WidgetBinderDataCompilerState $state) {
143  $stack = $state->get('field_map_stack');
144  $data = array_pop($stack);
145  $state->set('field_map_stack', $stack);
146  return $data;
147  }
148 
149  /**
150  * Saves a path to the compiled field map in the compiler state.
151  *
152  * @param \Drupal\paragraphs_editor\WidgetBinder\WidgetBinderDataCompilerState $state
153  * The current compiler state.
154  */
155  protected function savePath(WidgetBinderDataCompilerState $state) {
156  $node_path = $state->get('field_map_stack');
157  $field_map = $state->get('field_map');
158 
159  $map = &$field_map;
160  foreach ($node_path as $node) {
161 
162  if ($node['type'] == 'field') {
163  $node_id = $node['name'];
164  }
165  else {
166  $node_id = $node['uuid'];
167  }
168 
169  if (!isset($map[$node_id])) {
170  $map[$node_id] = $node;
171  }
172  else {
173  $map[$node_id] += $node;
174  }
175 
176  if (!isset($map[$node_id]['children'])) {
177  $map[$node_id]['children'] = [];
178  }
179 
180  $map = &$map[$node_id]['children'];
181  }
182 
183  $state->set('field_map', $field_map);
184  }
185 
186 }
pushPath(WidgetBinderDataCompilerState $state, array $data)
static ensureFieldConfig(FieldDefinitionInterface $field_definition=NULL)
Definition: TypeUtility.php:39
initialize(WidgetBinderData $data, WidgetBinderDataCompilerState $state, ParagraphInterface $root_paragraph)
processParagraph(WidgetBinderData $data, WidgetBinderDataCompilerState $state, ParagraphInterface $paragraph)
complete(WidgetBinderData $data, WidgetBinderDataCompilerState $state, RenderContext $render_context, $markup)
postprocessField(WidgetBinderData $data, WidgetBinderDataCompilerState $state, EntityReferenceFieldItemListInterface $items, $is_editor_field)
postprocessParagraph(WidgetBinderData $data, WidgetBinderDataCompilerState $state, ParagraphInterface $paragraph)
processField(WidgetBinderData $data, WidgetBinderDataCompilerState $state, EntityReferenceFieldItemListInterface $items, $is_editor_field)