You are here

class SocialMediaLinksBlock in Social Media Links Block and Field 8.2

Provides the Social Media Links Block.

Plugin annotation


@Block(
  id="social_media_links_block",
  admin_label = @Translation("Social Media Links"),
)

Hierarchy

Expanded class hierarchy of SocialMediaLinksBlock

File

src/Plugin/Block/SocialMediaLinksBlock.php, line 28

Namespace

Drupal\social_media_links\Plugin\Block
View source
class SocialMediaLinksBlock extends BlockBase implements ContainerFactoryPluginInterface {

  /**
   * {@inheritdoc}
   */
  protected $platformManager;

  /**
   * {@inheritdoc}
   */
  protected $iconsetManager;

  /**
   * {@inheritdoc}
   */
  protected $iconsetFinderService;

  /**
   * {@inheritdoc}
   */
  protected $renderer;

  /**
   * {@inheritdoc}
   */
  protected $logger;

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, SocialMediaLinksPlatformManager $platform_manager, SocialMediaLinksIconsetManager $iconset_manager, IconsetFinderService $finder_service, RendererInterface $renderer, LoggerInterface $logger) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->platformManager = $platform_manager;
    $this->iconsetManager = $iconset_manager;
    $this->iconsetFinderService = $finder_service;
    $this->renderer = $renderer;
    $this->logger = $logger;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static($configuration, $plugin_id, $plugin_definition, $container
      ->get('plugin.manager.social_media_links.platform'), $container
      ->get('plugin.manager.social_media_links.iconset'), $container
      ->get('social_media_links.finder'), $container
      ->get('renderer'), $container
      ->get('logger.channel.social_media_links'));
  }

  /**
   * {@inheritdoc}
   */
  public function blockForm($form, FormStateInterface $form_state) {
    $form = parent::blockForm($form, $form_state);
    $config = $this
      ->getConfiguration();

    // Platforms.
    $form['platforms'] = [
      '#type' => 'table',
      '#header' => [
        $this
          ->t('Platform'),
        $this
          ->t('Platform URL'),
        $this
          ->t('Description'),
        $this
          ->t('Weight'),
      ],
      '#tabledrag' => [
        [
          'action' => 'order',
          'relationship' => 'sibling',
          'group' => 'platform-order-weight',
        ],
      ],
    ];

    // Keep a note of the highest weight.
    $max_weight = 10;
    $platforms = $this->platformManager
      ->getPlatformsSortedByWeight($this
      ->getConfiguration());
    foreach ($platforms as $platform_id => $platform) {
      $form['platforms'][$platform_id]['#attributes']['class'][] = 'draggable';
      $form['platforms'][$platform_id]['#weight'] = $platform['weight'];
      if ($platform['weight'] > $max_weight) {
        $max_weight = $platform['weight'];
      }
      $form['platforms'][$platform_id]['label'] = [
        '#markup' => '<strong>' . $platform['name']
          ->render() . '</strong>',
      ];
      $form['platforms'][$platform_id]['value'] = [
        '#type' => 'textfield',
        '#title' => $platform['name']
          ->render(),
        '#title_display' => 'invisible',
        '#size' => 40,
        '#default_value' => isset($config['platforms'][$platform_id]['value']) ? $config['platforms'][$platform_id]['value'] : '',
        '#field_prefix' => $platform['instance']
          ->getUrlPrefix(),
        '#field_suffix' => $platform['instance']
          ->getUrlSuffix(),
        '#element_validate' => [
          [
            get_class($platform['instance']),
            'validateValue',
          ],
        ],
      ];
      if (!empty($platform['instance']
        ->getFieldDescription())) {
        $form['platforms'][$platform_id]['value']['#description'] = $platform['instance']
          ->getFieldDescription();
      }
      $form['platforms'][$platform_id]['description'] = [
        '#type' => 'textfield',
        '#title' => $platform['name']
          ->render(),
        '#title_display' => 'invisible',
        '#description' => $this
          ->t('The description is used for the title and WAI-ARIA attribute.'),
        '#size' => 40,
        '#placeholder' => $this
          ->t('Find / Follow us on %platform', [
          '%platform' => $platform['name']
            ->render(),
        ]),
        '#default_value' => isset($config['platforms'][$platform_id]['description']) ? $config['platforms'][$platform_id]['description'] : '',
      ];
      $form['platforms'][$platform_id]['weight'] = [
        '#type' => 'weight',
        '#title' => $this
          ->t('Weight for @title', [
          '@title' => $platform['name']
            ->render(),
        ]),
        '#title_display' => 'invisible',
        '#default_value' => $platform['weight'],
        '#attributes' => [
          'class' => [
            'platform-order-weight',
          ],
        ],
        // Delta: We need to use the max weight + number of platforms,
        // because if they get re-ordered it could start the count again from
        // the max weight, when the last item is dragged to be the first item.
        '#delta' => $max_weight + count($platforms),
      ];
    }

    // Appearance.
    $form['appearance'] = [
      '#type' => 'details',
      '#title' => $this
        ->t('Appearance'),
      '#tree' => TRUE,
    ];
    $form['appearance']['orientation'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Orientation'),
      '#options' => [
        'v' => $this
          ->t('vertical'),
        'h' => $this
          ->t('horizontal'),
      ],
      '#default_value' => isset($config['appearance']['orientation']) ? $config['appearance']['orientation'] : 'h',
    ];
    $form['appearance']['show_name'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Show name'),
      '#description' => $this
        ->t('Show the platform name next to the icon.'),
      '#default_value' => isset($config['appearance']['show_name']) ? $config['appearance']['show_name'] : 0,
    ];
    $form['appearance']['suggestion'] = [
      '#type' => 'machine_name',
      '#title' => $this
        ->t('Theme hook suggestion'),
      '#default_value' => isset($config['appearance']['suggestion']) ? $config['appearance']['suggestion'] : '',
      '#required' => FALSE,
      '#field_prefix' => '<code>social_media_links_platforms__</code>',
      '#description' => $this
        ->t('A theme hook suggestion can be used to override the default HTML and CSS found in <code>social-media-links-platforms.html</code>.'),
      '#machine_name' => [
        'error' => $this
          ->t('The theme hook suggestion must contain only lowercase letters, numbers, and underscores.'),
        'exists' => [
          $this,
          'suggestionExists',
        ],
      ],
    ];

    // Link Attributes.
    $form['link_attributes'] = [
      '#type' => 'details',
      '#title' => $this
        ->t('Link attributes'),
      '#tree' => TRUE,
    ];
    $form['link_attributes']['target'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Default target'),
      '#default_value' => isset($config['link_attributes']['target']) ? $config['link_attributes']['target'] : '<none>',
      '#options' => [
        '<none>' => $this
          ->t('Remove target attribute'),
        '_blank' => $this
          ->t('Open in a new browser window or tab (_blank)'),
        '_self' => $this
          ->t('Open in the current window (_self)'),
        '_parent' => $this
          ->t('Open in the frame that is superior to the frame the link is in (_parent)'),
        '_top' => $this
          ->t('Cancel all frames and open in full browser window (_top)'),
      ],
    ];
    $form['link_attributes']['rel'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Default rel'),
      '#default_value' => isset($config['link_attributes']['rel']) ? $config['link_attributes']['rel'] : '<none>',
      '#options' => [
        '<none>' => $this
          ->t('Remove rel attribute'),
        'nofollow' => $this
          ->t('Set nofollow'),
      ],
    ];

    // Icon Sets.
    $iconsetStyles = $this->iconsetManager
      ->getStyles();
    $form['iconset'] = [
      '#type' => 'details',
      '#title' => $this
        ->t('Icon Sets'),
      '#open' => TRUE,
      '#attributes' => [
        'class' => [
          'iconsets-wrapper',
        ],
      ],
    ];
    $form['iconset']['style'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Icon Style'),
      '#default_value' => isset($config['iconset']['style']) ? $config['iconset']['style'] : '',
      '#options' => $iconsetStyles,
    ];

    // Get the possible libarary install locations.
    // We use it maybe later in the form process, if a iconset is not installed.
    $installDirs = $this->iconsetFinderService
      ->getInstallDirs();
    $installedIconsets = [];
    foreach ($this->iconsetManager
      ->getIconsets() as $iconset_id => $iconset) {
      if (isset($iconset['downloadUrl'])) {
        $name = Link::fromTextAndUrl($iconset['name'], Url::fromUri($iconset['downloadUrl']))
          ->toString();
      }
      else {
        $name = $iconset['name'];
      }
      $publisher = '';
      if (isset($iconset['publisher'])) {
        $publisher = $this
          ->t('by') . ' ';
        if (isset($iconset['publisherUrl'])) {
          $publisher .= Link::fromTextAndUrl($iconset['publisher'], Url::fromUri($iconset['publisherUrl']))
            ->toString();
        }
        else {
          $publisher .= $iconset['publisher'];
        }
      }
      $installedIconsets[$iconset_id]['name'] = [
        '#markup' => '<strong>' . $name . '</strong><br />' . $publisher,
      ];
      $installedIconsets[$iconset_id]['styles'] = [
        '#markup' => implode('<br />', $iconsetStyles[$iconset_id]),
      ];
      if ($iconset['instance']
        ->getPath()) {
        $installedIconsets[$iconset_id]['examples'] = [
          '#type' => 'table',
        ];

        // Use the first iconset style for the sample table.
        $style = key($iconsetStyles[$iconset_id]);
        $style = IconsetBase::explodeStyle($style);
        $style = $style['style'];
        if ($iconset['instance']
          ->getPath() === 'library' && ($library = $iconset['instance']
          ->getLibrary())) {
          $installedIconsets[$iconset_id]['examples']['#attached']['library'] = (array) $library;
        }
        foreach ($this->platformManager
          ->getPlatforms() as $platform_id => $platform) {
          $installedIconsets[$iconset_id]['examples']['#header'][] = $platform['name']
            ->render();
          $iconElement = $iconset['instance']
            ->getIconElement($platform['instance'], $style);
          $installedIconsets[$iconset_id]['examples'][1][$platform_id] = [
            '#type' => 'markup',
            '#markup' => $this->renderer
              ->render($iconElement),
          ];
        }
      }
      else {
        $examples = '<strong>' . $this
          ->t('Not installed.') . '</strong><br />';
        $examples .= $this
          ->t('To install: @download and copy it to one of these directories:', [
          '@download' => Link::fromTextAndUrl($this
            ->t('Download'), Url::fromUri($iconset['downloadUrl']))
            ->toString(),
        ]);
        $installDirsIconset = [];
        foreach ($installDirs as $dir) {
          $installDirsIconset[] = $dir . '/' . $iconset_id;
        }
        $examples .= '<br /><code>' . preg_replace('/,([^,]+) ?$/', " " . 'or' . " \$1", implode(',<br />', $installDirsIconset), 1) . '</code>';
        $installedIconsets[$iconset_id]['examples'] = [
          '#markup' => $examples,
        ];
      }

      // Add a weigth to the iconset for sorting.
      $installedIconsets[$iconset_id]['#weight'] = $iconset['instance']
        ->getPath() ? 0 : 1;
    }

    // Sort the array so that installed iconsets shown first.
    uasort($installedIconsets, [
      'Drupal\\Component\\Utility\\SortArray',
      'sortByWeightProperty',
    ]);
    $form['iconset']['installed_iconsets'] = [
      '#type' => 'table',
      '#header' => [
        $this
          ->t('Name'),
        $this
          ->t('Sizes'),
        $this
          ->t('Icon examples and download instructions'),
      ],
    ] + $installedIconsets;
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function blockSubmit($form, FormStateInterface $form_state) {
    $this
      ->setConfigurationValue('platforms', $form_state
      ->getValue('platforms'));
    $this
      ->setConfigurationValue('appearance', $form_state
      ->getValue('appearance'));
    $this
      ->setConfigurationValue('link_attributes', $form_state
      ->getValue('link_attributes'));
    $iconset = $form_state
      ->getValue('iconset');
    unset($iconset['iconset']['installed_iconsets']);
    $this
      ->setConfigurationValue('iconset', $iconset);
  }

  /**
   * {@inheritdoc}
   */
  public function build() {
    $config = $this
      ->getConfiguration();
    $platforms = $this->platformManager
      ->getPlatformsWithValue($config['platforms']);
    if (count($platforms) < 1) {
      return [];
    }
    $iconset = IconsetBase::explodeStyle($config['iconset']['style']);
    try {
      $iconsetInstance = $this->iconsetManager
        ->createInstance($iconset['iconset']);
    } catch (PluginException $exception) {
      $this->logger
        ->error('The selected "@iconset" iconset plugin does not exist.', [
        '@iconset' => $iconset['iconset'],
      ]);
      return [];
    }
    foreach ($config['link_attributes'] as $key => $value) {
      if ($value === '<none>') {
        unset($config['link_attributes'][$key]);
      }
    }

    // Set the attributes for the individual links.
    //
    // We use two different types of link attributes:
    // * "global" attributes that affects all links (e.g. target or rel)
    // which are set in $config['link_attributes'];
    // * "individual" attributes for each link (e.g. title) which are defined
    // in $platforms[$platform_id]['attributes'].
    foreach ($platforms as $platform_id => $platform) {
      $platforms[$platform_id]['element'] = (array) $iconsetInstance
        ->getIconElement($platform['instance'], $iconset['style']);
      $platforms[$platform_id]['attributes'] = new Attribute($config['link_attributes']);
      if (!empty($platform['instance']
        ->getDescription())) {
        $platforms[$platform_id]['attributes']
          ->setAttribute('aria-label', $platform['instance']
          ->getDescription());
        $platforms[$platform_id]['attributes']
          ->setAttribute('title', $platform['instance']
          ->getDescription());
      }
    }
    $output = [
      '#theme' => 'social_media_links_platforms',
      '#platforms' => $platforms,
      '#appearance' => $config['appearance'],
      '#attached' => [
        'library' => [
          'social_media_links/social_media_links.theme',
        ],
      ],
    ];
    if ($iconsetInstance
      ->getPath() === 'library' && (array) ($library = $iconsetInstance
      ->getLibrary())) {
      $output['#attached']['library'] = array_merge_recursive($output['#attached']['library'], $library);
    }
    return [
      $output,
    ];
  }

  /**
   * Checks for an existing theme hook suggestion.
   *
   * @return bool
   *   Returns FALSE because there is no need of validation by unique value.
   */
  public function suggestionExists() {
    return FALSE;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
BlockPluginInterface::BLOCK_LABEL_VISIBLE constant Indicates the block label (title) should be displayed to end users.
BlockPluginTrait::$transliteration protected property The transliteration service.
BlockPluginTrait::access public function
BlockPluginTrait::baseConfigurationDefaults protected function Returns generic default configuration for block plugins.
BlockPluginTrait::blockAccess protected function Indicates whether the block should be shown. 16
BlockPluginTrait::blockValidate public function 3
BlockPluginTrait::buildConfigurationForm public function Creates a generic configuration form for all block types. Individual block plugins can add elements to this form by overriding BlockBase::blockForm(). Most block plugins should not override this method unless they need to alter the generic form elements. 2
BlockPluginTrait::calculateDependencies public function
BlockPluginTrait::defaultConfiguration public function 19
BlockPluginTrait::getConfiguration public function 1
BlockPluginTrait::getMachineNameSuggestion public function 1
BlockPluginTrait::getPreviewFallbackString public function 3
BlockPluginTrait::label public function
BlockPluginTrait::setConfiguration public function
BlockPluginTrait::setConfigurationValue public function
BlockPluginTrait::setTransliteration public function Sets the transliteration service.
BlockPluginTrait::submitConfigurationForm public function Most block plugins should not override this method. To add submission handling for a specific block type, override BlockBase::blockSubmit().
BlockPluginTrait::transliteration protected function Wraps the transliteration service.
BlockPluginTrait::validateConfigurationForm public function Most block plugins should not override this method. To add validation for a specific block type, override BlockBase::blockValidate(). 1
ContextAwarePluginAssignmentTrait::addContextAssignmentElement protected function Builds a form element for assigning a context to a given slot.
ContextAwarePluginAssignmentTrait::contextHandler protected function Wraps the context handler.
ContextAwarePluginBase::$context protected property The data objects representing the context of this plugin.
ContextAwarePluginBase::$contexts Deprecated private property Data objects representing the contexts passed in the plugin configuration.
ContextAwarePluginBase::createContextFromConfiguration protected function Overrides ContextAwarePluginBase::createContextFromConfiguration
ContextAwarePluginBase::getCacheContexts public function The cache contexts associated with this object. Overrides CacheableDependencyInterface::getCacheContexts 9
ContextAwarePluginBase::getCacheMaxAge public function The maximum age for which this object may be cached. Overrides CacheableDependencyInterface::getCacheMaxAge 7
ContextAwarePluginBase::getCacheTags public function The cache tags associated with this object. Overrides CacheableDependencyInterface::getCacheTags 4
ContextAwarePluginBase::getContext public function This code is identical to the Component in order to pick up a different Context class. Overrides ContextAwarePluginBase::getContext
ContextAwarePluginBase::getContextDefinition public function Overrides ContextAwarePluginBase::getContextDefinition
ContextAwarePluginBase::getContextDefinitions public function Overrides ContextAwarePluginBase::getContextDefinitions
ContextAwarePluginBase::getContextMapping public function Gets a mapping of the expected assignment names to their context names. Overrides ContextAwarePluginInterface::getContextMapping
ContextAwarePluginBase::getContexts public function Gets the defined contexts. Overrides ContextAwarePluginInterface::getContexts
ContextAwarePluginBase::getContextValue public function Gets the value for a defined context. Overrides ContextAwarePluginInterface::getContextValue
ContextAwarePluginBase::getContextValues public function Gets the values for all defined contexts. Overrides ContextAwarePluginInterface::getContextValues
ContextAwarePluginBase::setContext public function Set a context on this plugin. Overrides ContextAwarePluginBase::setContext
ContextAwarePluginBase::setContextMapping public function Sets a mapping of the expected assignment names to their context names. Overrides ContextAwarePluginInterface::setContextMapping
ContextAwarePluginBase::setContextValue public function Sets the value for a defined context. Overrides ContextAwarePluginBase::setContextValue
ContextAwarePluginBase::validateContexts public function Validates the set values for the defined contexts. Overrides ContextAwarePluginInterface::validateContexts
ContextAwarePluginBase::__get public function Implements magic __get() method.
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 3
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
PluginWithFormsTrait::getFormClass public function
PluginWithFormsTrait::hasFormClass public function
SocialMediaLinksBlock::$iconsetFinderService protected property
SocialMediaLinksBlock::$iconsetManager protected property
SocialMediaLinksBlock::$logger protected property
SocialMediaLinksBlock::$platformManager protected property
SocialMediaLinksBlock::$renderer protected property
SocialMediaLinksBlock::blockForm public function Overrides BlockPluginTrait::blockForm
SocialMediaLinksBlock::blockSubmit public function Overrides BlockPluginTrait::blockSubmit
SocialMediaLinksBlock::build public function Builds and returns the renderable array for this block plugin. Overrides BlockPluginInterface::build
SocialMediaLinksBlock::create public static function Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface::create
SocialMediaLinksBlock::suggestionExists public function Checks for an existing theme hook suggestion.
SocialMediaLinksBlock::__construct public function Overrides BlockPluginTrait::__construct
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.
TypedDataTrait::$typedDataManager protected property The typed data manager used for creating the data types.
TypedDataTrait::getTypedDataManager public function Gets the typed data manager. 2
TypedDataTrait::setTypedDataManager public function Sets the typed data manager. 2