EditorSelector.php 3.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
<?php

/**
 * @file
 * Contains \Drupal\edit\EditorSelector.
 */

namespace Drupal\edit;

use Drupal\Component\Plugin\PluginManagerInterface;
11
use Drupal\Component\Utility\NestedArray;
12
use Drupal\Core\Entity\Field\FieldDefinitionInterface;
13
use Drupal\Core\Field\FormatterPluginManager;
14 15

/**
16
 * Selects an in-place editor (an Editor plugin) for a field.
17 18 19 20
 */
class EditorSelector implements EditorSelectorInterface {

  /**
21
   * The manager for editor plugins.
22 23 24
   *
   * @var \Drupal\Component\Plugin\PluginManagerInterface
   */
25
  protected $editorManager;
26

27 28 29
  /**
   * The manager for formatter plugins.
   *
30
   * @var \Drupal\Core\Field\FormatterPluginManager.
31 32 33
   */
  protected $formatterManager;

34
  /**
35
   * A list of alternative editor plugin IDs, keyed by editor plugin ID.
36
   *
37
   * @var array
38
   */
39
  protected $alternatives;
40 41 42 43

  /**
   * Constructs a new EditorSelector.
   *
44
   * @param \Drupal\Component\Plugin\PluginManagerInterface
45
   *   The manager for editor plugins.
46
   * @param \Drupal\Core\Field\FormatterPluginManager
47
   *   The manager for formatter plugins.
48
   */
49
  public function __construct(PluginManagerInterface $editor_manager, FormatterPluginManager $formatter_manager) {
50
    $this->editorManager = $editor_manager;
51
    $this->formatterManager = $formatter_manager;
52 53 54
  }

  /**
55
   * {@inheritdoc}
56
   */
57
  public function getEditor($formatter_type, FieldDefinitionInterface $field_definition, array $items) {
58 59 60 61 62 63 64 65 66 67 68 69 70
    // Build a static cache of the editors that have registered themselves as
    // alternatives to a certain editor.
    if (!isset($this->alternatives)) {
      $editors = $this->editorManager->getDefinitions();
      foreach ($editors as $alternative_editor_id => $editor) {
        if (isset($editor['alternativeTo'])) {
          foreach ($editor['alternativeTo'] as $original_editor_id) {
            $this->alternatives[$original_editor_id][] = $alternative_editor_id;
          }
        }
      }
    }

71 72 73 74 75
    // Check if the formatter defines an appropriate in-place editor. For
    // example, text formatters displaying untrimmed text can choose to use the
    // 'direct' editor. If the formatter doesn't specify, fall back to the
    // 'form' editor, since that can work for any field. Formatter definitions
    // can use 'disabled' to explicitly opt out of in-place editing.
76
    $formatter_info = $this->formatterManager->getDefinition($formatter_type);
77
    $editor_id = $formatter_info['edit']['editor'];
78
    if ($editor_id === 'disabled') {
79 80
      return;
    }
81 82 83
    elseif ($editor_id === 'form') {
      return 'form';
    }
84

85 86 87 88 89 90 91 92 93
    // No early return, so create a list of all choices.
    $editor_choices = array($editor_id);
    if (isset($this->alternatives[$editor_id])) {
      $editor_choices = array_merge($editor_choices, $this->alternatives[$editor_id]);
    }

    // Make a choice.
    foreach ($editor_choices as $editor_id) {
      $editor = $this->editorManager->createInstance($editor_id);
94
      if ($editor->isCompatible($field_definition, $items)) {
95
        return $editor_id;
96 97 98
      }
    }

99 100
    // We still don't have a choice, so fall back to the default 'form' editor.
    return 'form';
101 102 103
  }

  /**
104
   * {@inheritdoc}
105
   */
106
  public function getEditorAttachments(array $editor_ids) {
107
    $attachments = array();
108
    $editor_ids = array_unique($editor_ids);
109 110 111 112

    // Editor plugins' attachments.
    foreach ($editor_ids as $editor_id) {
      $editor = $this->editorManager->createInstance($editor_id);
113
      $attachments[] = $editor->getAttachments();
114 115
    }

116
    return NestedArray::mergeDeepArray($attachments);
117
  }
118

119
}