Paragraphs Editor
CommandContextFactory.php
Go to the documentation of this file.
1 <?php
2 
4 
11 
12 /**
13  * The default command context factory.
14  *
15  * @see Drupal\paragraphs_editor\EditorCommand\CommandContextFactoryInterface
16  */
18 
19  /**
20  * The entity type manager for looking up entity info.
21  *
22  * @var \Drupal\Core\Entity\EntityTypeManagerInterface
23  */
24  protected $entityTypeManager;
25 
26  /**
27  * The buffer cache for looking up existing edit buffers.
28  *
29  * @var \Drupal\paragraphs_editor\EditBuffer\EditBufferCacheInterface
30  */
31  protected $bufferCache;
32 
33  /**
34  * The field config storage handler.
35  *
36  * @var \Drupal\Core\Entity\EntityStorageInterface
37  */
39 
40  /**
41  * A map of plugin types to plugin managers.
42  *
43  * @var array
44  */
45  protected $pluginManagers;
46 
47  /**
48  * The entity bundle info service.
49  *
50  * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
51  */
52  protected $bundleInfo;
53 
54  /**
55  * Create a command context factory object.
56  *
57  * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
58  * The entity type manager to use for looking up the entities and fields.
59  * @param \Drupal\paragraphs_editor\EditBuffer\EditBufferCacheInterface $buffer_cache
60  * The edit buffer cache to use for looking up existing edit buffers that
61  * have been persisted in the database cache.
62  * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_info
63  * The bundle manager service for creating paragraph bundle filters.
64  * @param array $plugin_managers
65  * A key value pair of paragraphs editor plugin managers. This should
66  * include a 'bundle_selector' and 'delivery_provider'.
67  */
68  public function __construct(EntityTypeManagerInterface $entity_type_manager, EditBufferCacheInterface $buffer_cache, EntityTypeBundleInfoInterface $bundle_info, array $plugin_managers) {
69  $this->entityTypeManager = $entity_type_manager;
70  $this->bufferCache = $buffer_cache;
71  $this->fieldConfigStorage = $entity_type_manager->getStorage('field_config');
72  $this->pluginManagers = $plugin_managers;
73  $this->bundleInfo = $bundle_info;
74  }
75 
76  /**
77  * {@inheritdoc}
78  */
79  public function parseContextString($context_string) {
80  $context_params = explode(':', $context_string);
81  $field_config_id = array_shift($context_params);
82  $widget_build_id = array_shift($context_params);
83  $entity_id = array_shift($context_params);
84  return [$field_config_id, $widget_build_id, $entity_id];
85  }
86 
87  /**
88  * {@inheritdoc}
89  */
90  public function get($context_id) {
91  list($field_config_id, $widget_build_id, $entity_id) = $this->parseContextString($context_id);
92  return $field_config_id && $widget_build_id ? $this->create($field_config_id, $entity_id, [], $widget_build_id) : NULL;
93  }
94 
95  /**
96  * {@inheritdoc}
97  */
98  public function create($field_config_id, $entity_id, array $settings = [], $widget_build_id = NULL, $edit_buffer_prototype = NULL) {
99 
100  // If a widget build id isn't specified, we create a new one.
101  if (empty($widget_build_id)) {
102  $widget_build_id = $this->generateBuildId();
103  }
104 
105  // If any exceptions are thrown while initializing any of the properties, we
106  // return an "Invalid Command" context to signal that something is wrong
107  // with the command and execution should be aborted. We do this instead of
108  // bubbling the exception so that the controller access handler can deal
109  // with it instead of the core exception handling.
110  try {
111  $context_keys = [$field_config_id, $widget_build_id];
112  $field_config = TypeUtility::ensureFieldConfig($this->fieldConfigStorage->load($field_config_id));
113  $entity_type = $field_config->getTargetEntityTypeId();
114  $entity_storage = $this->entityTypeManager->getStorage($entity_type);
115 
116  if ($entity_id) {
117  $entity = $entity_storage->load($entity_id);
118  $context_keys[] = $entity_id;
119  }
120  else {
121  $entity = NULL;
122  }
123 
124  $context_string = implode(':', $context_keys);
125  if ($edit_buffer_prototype) {
126  $edit_buffer = $edit_buffer_prototype->createCopy($context_string);
127  }
128  else {
129  $edit_buffer = $this->bufferCache->get($context_string);
130  }
131  $bundle_filter = $this->createBundleFilter($field_config);
132  $context = new CommandContext($entity, $field_config, $edit_buffer, $bundle_filter, $settings);
133  $this->attachPlugin('delivery_provider', $settings, $context);
134  $this->attachPlugin('bundle_selector', $settings, $context);
135  }
136  catch (\Exception $e) {
137  return new InvalidCommandContext();
138  }
139  return $context;
140  }
141 
142  /**
143  * {@inheritdoc}
144  */
145  public function regenerate(CommandContextInterface $from) {
146  $field_config_id = $from->getFieldConfig()->id();
147  $entity_id = $from->getEntity() ? $from->getEntity()->id() : NULL;
148  $settings = $from->getSettings();
149  $widget_build_id = $this->generateBuildId();
150  $to = $this->create($field_config_id, $entity_id, $settings, $widget_build_id, $from->getEditBuffer());
151  $to->getEditBuffer()->save();
152  $this->free($from);
153  return $to;
154  }
155 
156  /**
157  * {@inheritdoc}
158  */
159  public function free(CommandContextInterface $context) {
160  $this->bufferCache->delete($context->getContextString());
161  }
162 
163  /**
164  * {@inheritdoc}
165  */
166  public function getPluginManager($type) {
167  return isset($this->pluginManagers[$type]) ? $this->pluginManagers[$type] : NULL;
168  }
169 
170  /**
171  * {@inheritdoc}
172  */
173  public function createBundleFilter(FieldConfigInterface $field_config) {
174  return new ParagraphBundleFilter($this->bundleInfo, $field_config);
175  }
176 
177  /**
178  * Helper function for instantiating plugin instances for a command context.
179  *
180  * @param string $type
181  * The type of plugin to be attached.
182  * @param array $settings
183  * The field widget settings specifying which plugin to use.
184  * @param \Drupal\paragraphs_editor\EditorCommand\CommandContextInterface $context
185  * The context to attach the instantiated plugin to.
186  */
187  protected function attachPlugin($type, array $settings, CommandContextInterface $context) {
188  $plugin_name = isset($settings[$type]) ? $settings[$type] : '';
189  if ($plugin_name) {
190  $plugin = $this->getPluginManager($type)->createInstance($plugin_name, [
191  'context' => $context,
192  ]);
193  $context->setPlugin($type, $plugin);
194  }
195  }
196 
197  /**
198  * Generates a build id when new contexts are created.
199  *
200  * @return string
201  * The newly created build id.
202  */
203  protected function generateBuildId() {
204  return Crypt::randomBytesBase64();
205  }
206 
207 }
__construct(EntityTypeManagerInterface $entity_type_manager, EditBufferCacheInterface $buffer_cache, EntityTypeBundleInfoInterface $bundle_info, array $plugin_managers)
static ensureFieldConfig(FieldDefinitionInterface $field_definition=NULL)
Definition: TypeUtility.php:39
create($field_config_id, $entity_id, array $settings=[], $widget_build_id=NULL, $edit_buffer_prototype=NULL)
attachPlugin($type, array $settings, CommandContextInterface $context)