CommandContextFactory   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 188
Duplicated Lines 0 %

Test Coverage

Coverage 11.11%

Importance

Changes 0
Metric Value
dl 0
loc 188
ccs 7
cts 63
cp 0.1111
rs 10
c 0
b 0
f 0
wmc 20

10 Methods

Rating   Name   Duplication   Size   Complexity  
B create() 0 42 5
A getPluginManager() 0 2 2
A generateBuildId() 0 2 1
A free() 0 2 1
A regenerate() 0 9 2
A attachPlugin() 0 7 3
A get() 0 3 3
A parseContextString() 0 6 1
A createBundleFilter() 0 2 1
A __construct() 0 6 1
1
<?php
2
3
namespace Drupal\paragraphs_editor\EditorCommand;
4
5
use Drupal\Component\Utility\Crypt;
6
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
7
use Drupal\Core\Entity\EntityTypeManagerInterface;
8
use Drupal\Core\Field\FieldConfigInterface;
9
use Drupal\paragraphs_editor\EditBuffer\EditBufferCacheInterface;
10
use Drupal\paragraphs_editor\Utility\TypeUtility;
11
12
/**
13
 * The default command context factory.
14
 *
15
 * @see Drupal\paragraphs_editor\EditorCommand\CommandContextFactoryInterface
16
 */
17
class CommandContextFactory implements CommandContextFactoryInterface {
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
   */
38
  protected $fieldConfigStorage;
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 1
  public function __construct(EntityTypeManagerInterface $entity_type_manager, EditBufferCacheInterface $buffer_cache, EntityTypeBundleInfoInterface $bundle_info, array $plugin_managers) {
69 1
    $this->entityTypeManager = $entity_type_manager;
70 1
    $this->bufferCache = $buffer_cache;
71 1
    $this->fieldConfigStorage = $entity_type_manager->getStorage('field_config');
72 1
    $this->pluginManagers = $plugin_managers;
73 1
    $this->bundleInfo = $bundle_info;
74 1
  }
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));
0 ignored issues
show
Bug introduced by
It seems like $this->fieldConfigStorage->load($field_config_id) can also be of type Drupal\Core\Entity\EntityInterface; however, parameter $field_definition of Drupal\paragraphs_editor...ty::ensureFieldConfig() does only seem to accept null|Drupal\Core\Field\FieldDefinitionInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

112
      $field_config = TypeUtility::ensureFieldConfig(/** @scrutinizer ignore-type */ $this->fieldConfigStorage->load($field_config_id));
Loading history...
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
}
208