You are here

BackgroundMedia.php in Bootstrap Styles 1.0.x

File

src/Plugin/BootstrapStyles/Style/BackgroundMedia.php
View source
<?php

namespace Drupal\bootstrap_styles\Plugin\BootstrapStyles\Style;

use Drupal\bootstrap_styles\Style\StylePluginBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\media\Entity\Media;
use Drupal\file\Entity\File;

/**
 * Class BackgroundMedia.
 *
 * @package Drupal\bootstrap_styles\Plugin\Style
 *
 * @Style(
 *   id = "background_media",
 *   title = @Translation("Background Media"),
 *   group_id = "background",
 *   weight = 2
 * )
 */
class BackgroundMedia extends StylePluginBase implements ContainerFactoryPluginInterface {

  /**
   * The entity type bundle info.
   *
   * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
   */
  protected $entityTypeBundleInfo;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Constructs a BackgroundMedia object.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin ID for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The configuration factory.
   * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
   *   The entity type bundle info.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config_factory, EntityTypeBundleInfoInterface $entity_type_bundle_info, EntityTypeManagerInterface $entity_type_manager) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $config_factory);
    $this->entityTypeBundleInfo = $entity_type_bundle_info;
    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static($configuration, $plugin_id, $plugin_definition, $container
      ->get('config.factory'), $container
      ->get('entity_type.bundle.info'), $container
      ->get('entity_type.manager'));
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $config = $this
      ->config();

    // Background image media bundle.
    $media_bundles = [];
    $media_bundles_info = $this->entityTypeBundleInfo
      ->getBundleInfo('media');

    // Ignore if match any of the following names.
    $disabled_bundles = [
      'audio',
      'audio_file',
      'instagram',
      'tweet',
      'document',
      'remote_video',
    ];
    foreach ($media_bundles_info as $key => $bundle) {
      if (!in_array($key, $disabled_bundles)) {
        $media_bundles[$key] = $bundle['label'] . ' (' . $key . ')';
      }
    }
    $form['background']['background_image_bundle'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Image background media bundle'),
      '#options' => $media_bundles,
      '#description' => $this
        ->t('Image background media entity bundle.'),
      '#default_value' => $config
        ->get('background_image.bundle'),
      '#ajax' => [
        'callback' => __CLASS__ . '::getFields',
        'event' => 'change',
        'method' => 'html',
        'wrapper' => 'media_image_bundle_fields',
        'progress' => [
          'type' => 'throbber',
          'message' => NULL,
        ],
      ],
    ];
    $form['background']['background_image_field'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Image background media field'),
      '#options' => $this
        ->getFieldsByBundle($config
        ->get('background_image.bundle')),
      '#description' => $this
        ->t('Image background media entity field.'),
      '#default_value' => $config
        ->get('background_image.field'),
      '#attributes' => [
        'id' => 'media_image_bundle_fields',
      ],
      '#validated' => TRUE,
    ];
    $form['background']['background_local_video_bundle'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Local video background media bundle'),
      '#options' => $media_bundles,
      '#description' => $this
        ->t('Background for local video media entity bundle.'),
      '#default_value' => $config
        ->get('background_local_video.bundle'),
      '#ajax' => [
        'callback' => __CLASS__ . '::getFields',
        'event' => 'change',
        'method' => 'html',
        'wrapper' => 'media_local_video_bundle_fields',
        'progress' => [
          'type' => 'throbber',
          'message' => NULL,
        ],
      ],
    ];
    $form['background']['background_local_video_field'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Local video background media field'),
      '#options' => $this
        ->getFieldsByBundle($config
        ->get('background_local_video.bundle')),
      '#description' => $this
        ->t('Local video background media entity field.'),
      '#default_value' => $config
        ->get('background_local_video.field'),
      '#attributes' => [
        'id' => 'media_local_video_bundle_fields',
      ],
      '#validated' => TRUE,
    ];
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function getFieldsByBundle($bundle) {
    $field_map = \Drupal::service('entity_field.manager')
      ->getFieldMap();
    $media_field_map = $field_map['media'];
    $fields = [];
    foreach ($media_field_map as $field_name => $field_info) {
      if (in_array($bundle, $field_info['bundles']) && in_array($field_info['type'], [
        'image',
        'file',
      ]) && $field_name !== 'thumbnail') {
        $fields[$field_name] = $field_name;
      }
    }
    return $fields;
  }

  /**
   * {@inheritdoc}
   */
  public function getFields(array &$element, FormStateInterface $form_state) {
    $triggering_element = $form_state
      ->getTriggeringElement();
    $bundle = $triggering_element['#value'];
    $wrapper_id = $triggering_element["#ajax"]["wrapper"];
    $rendered_field = '';
    $field_map = \Drupal::service('entity_field.manager')
      ->getFieldMap();
    $media_field_map = $field_map['media'];
    foreach ($media_field_map as $field_name => $field_info) {
      if (in_array($bundle, $field_info['bundles']) && in_array($field_info['type'], [
        'image',
        'file',
      ]) && $field_name !== 'thumbnail') {
        $rendered_field .= '<option value="' . $field_name . '">' . $field_name . '</option>';
      }
    }
    $response = new AjaxResponse();
    $response
      ->addCommand(new HtmlCommand('#' . $wrapper_id, $rendered_field));
    return $response;
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    $this
      ->config()
      ->set('background_image.bundle', $form_state
      ->getValue('background_image_bundle'))
      ->set('background_image.field', $form_state
      ->getValue('background_image_field'))
      ->set('background_local_video.bundle', $form_state
      ->getValue('background_local_video_bundle'))
      ->set('background_local_video.field', $form_state
      ->getValue('background_local_video_field'))
      ->save();
  }

  /**
   * {@inheritdoc}
   */
  public function buildStyleFormElements(array &$form, FormStateInterface $form_state, $storage) {
    $icon_path = drupal_get_path('module', 'bootstrap_styles') . '/images/';
    $form['background_type']['#options']['image'] = $this
      ->getSvgIconMarkup($icon_path . 'plugins/background/background-image.svg');
    $form['background_type']['#options']['video'] = $this
      ->getSvgIconMarkup($icon_path . 'plugins/background/background-video.svg');
    if (!$form['background_type']['#default_value']) {
      $form['background_type']['#default_value'] = $storage['background']['background_type'] ?? 'image';
    }

    // Background media.
    $config = $this
      ->config();

    // Check if the bundle exist.
    if ($config
      ->get('background_image.bundle') && $this->entityTypeManager
      ->getStorage('media_type')
      ->load($config
      ->get('background_image.bundle'))) {
      $form['background_image'] = [
        '#type' => 'media_library',
        '#title' => $this
          ->t('Background image'),
        '#description' => $this
          ->t('Background image'),
        '#allowed_bundles' => [
          $config
            ->get('background_image.bundle'),
        ],
        '#default_value' => $storage['background_media']['image']['media_id'] ?? NULL,
        '#states' => [
          'visible' => [
            ':input.bs_background--type' => [
              'value' => 'image',
            ],
          ],
        ],
      ];
    }

    // Check if the bundle exist.
    if ($config
      ->get('background_local_video.bundle') && $this->entityTypeManager
      ->getStorage('media_type')
      ->load($config
      ->get('background_local_video.bundle'))) {
      $form['background_video'] = [
        '#type' => 'media_library',
        '#title' => $this
          ->t('Background video'),
        '#description' => $this
          ->t('Background video'),
        '#allowed_bundles' => [
          $config
            ->get('background_local_video.bundle'),
        ],
        '#default_value' => $storage['background_media']['video']['media_id'] ?? NULL,
        '#states' => [
          'visible' => [
            ':input.bs_background--type' => [
              'value' => 'video',
            ],
          ],
        ],
      ];
    }
    $form['background_options'] = [
      '#type' => 'container',
      '#attributes' => [
        'class' => [
          'bs_background--options bs_row',
        ],
      ],
      '#states' => [
        'visible' => [
          ':input.bs_background--type' => [
            'value' => 'image',
          ],
        ],
      ],
    ];
    $form['background_options']['background_position'] = [
      '#type' => 'radios',
      '#title' => $this
        ->t('Position'),
      '#options' => [
        'left top' => $this
          ->t('Left Top'),
        'center top' => $this
          ->t('Center Top'),
        'right top' => $this
          ->t('Right Top'),
        'left center' => $this
          ->t('Left Center'),
        'center' => $this
          ->t('Center'),
        'right center' => $this
          ->t('Right Center'),
        'left bottom' => $this
          ->t('Left Bottom'),
        'center bottom' => $this
          ->t('Center Bottom'),
        'right bottom' => $this
          ->t('Right Bottom'),
      ],
      '#default_value' => $storage['background_media']['background_options']['background_position'] ?? 'center',
      '#attributes' => [
        'class' => [
          'bs_background--position bs_col bs_col--50',
        ],
      ],
    ];
    $form['background_options']['background_repeat'] = [
      '#type' => 'radios',
      '#title' => $this
        ->t('Repeat'),
      '#options' => [
        'no-repeat' => $this
          ->getSvgIconMarkup($icon_path . 'plugins/background-repeat/background-no-repeat.svg'),
        'repeat' => $this
          ->getSvgIconMarkup($icon_path . 'plugins/background-repeat/background-repeat.svg'),
        'repeat-x' => $this
          ->getSvgIconMarkup($icon_path . 'plugins/background-repeat/background-repeat-xy.svg'),
        'repeat-y' => $this
          ->getSvgIconMarkup($icon_path . 'plugins/background-repeat/background-repeat-xy.svg'),
      ],
      '#default_value' => $storage['background_media']['background_options']['background_repeat'] ?? 'no-repeat',
      '#attributes' => [
        'class' => [
          'bs_background--repeat bs_col bs_col--50',
        ],
      ],
    ];
    $form['background_options']['background_attachment'] = [
      '#type' => 'radios',
      '#title' => $this
        ->t('Attachment'),
      '#options' => [
        'not_fixed' => $this
          ->t('Not Fixed'),
        'fixed' => $this
          ->t('Fixed'),
      ],
      '#default_value' => $storage['background_media']['background_options']['background_attachment'] ?? 'not_fixed',
      '#attributes' => [
        'class' => [
          'bs_background--attachment bs_col bs_col--100',
        ],
      ],
      '#prefix' => '<hr class="bs_divider"/>',
      '#suffix' => '<hr class="bs_divider"/>',
    ];
    $form['background_options']['background_size'] = [
      '#type' => 'radios',
      '#title' => $this
        ->t('Size'),
      '#options' => [
        'cover' => $this
          ->t('Cover'),
        'contain' => $this
          ->t('Contain'),
        'auto' => $this
          ->t('Auto'),
      ],
      '#default_value' => $storage['background_media']['background_options']['background_size'] ?? 'cover',
      '#attributes' => [
        'class' => [
          'bs_background--size bs_col bs_col--100',
        ],
      ],
      '#suffix' => '<hr class="bs_divider"/>',
    ];
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitStyleFormElements(array $group_elements) {
    return [
      'background_media' => [
        'image' => [
          'media_id' => $group_elements['background_image'],
        ],
        'video' => [
          'media_id' => $group_elements['background_video'],
        ],
        'background_options' => [
          'background_position' => $group_elements['background_options']['background_position'],
          'background_repeat' => $group_elements['background_options']['background_repeat'],
          'background_attachment' => $group_elements['background_options']['background_attachment'],
          'background_size' => $group_elements['background_options']['background_size'],
        ],
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function build(array $build, array $storage, $theme_wrapper = NULL) {
    $config = $this
      ->config();

    // Backwards compatibility for layouts created on the 1.x version.
    if (isset($storage['background_media']['media_id'])) {
      $media_id = $storage['background_media']['media_id'];
      $background_type = $storage['background']['background_type'];
      $storage['background_media'][$background_type]['media_id'] = $media_id;
    }
    if (isset($storage['background']['background_type'])) {
      if ($config
        ->get('background_image.bundle') && $storage['background']['background_type'] == 'image' && isset($storage['background_media']['image']['media_id']) && ($media_id = $storage['background_media']['image']['media_id'])) {
        $media_entity = Media::load($media_id);
        $media_field_name = $config
          ->get('background_image.field');

        // Check if the field exist.
        if ($media_entity && $media_entity
          ->hasField($media_field_name)) {
          $background_image_style = $this
            ->buildBackgroundMediaImage($media_entity, $media_field_name, $storage);

          // Assign the style to element or its theme wrapper if exist.
          if ($theme_wrapper && isset($build['#theme_wrappers'][$theme_wrapper])) {
            $build['#theme_wrappers'][$theme_wrapper]['#attributes']['style'][] = $background_image_style;
          }
          else {
            $build['#attributes']['style'][] = $background_image_style;
          }
        }
      }
      elseif ($config
        ->get('background_local_video.bundle') && $storage['background']['background_type'] == 'video' && isset($storage['background_media']['video']['media_id']) && ($media_id = $storage['background_media']['video']['media_id'])) {
        $media_entity = Media::load($media_id);
        $media_field_name = $config
          ->get('background_local_video.field');

        // Check if the field exist.
        if ($media_entity && $media_entity
          ->hasField($media_field_name)) {
          $background_video_url = $this
            ->buildBackgroundMediaLocalVideo($media_entity, $media_field_name);
          $build['#theme_wrappers']['bs_video_background'] = [
            '#video_background_url' => $background_video_url,
          ];
        }
      }
    }
    return $build;
  }

  /**
   * Helper function to the background media image style.
   *
   * @param object $media_entity
   *   A media entity object.
   * @param object $field_name
   *   The Media entity local video field name.
   * @param object $storage
   *   The styles storage.
   *
   * @return string
   *   Background media image style.
   */
  public function buildBackgroundMediaImage($media_entity, $field_name, $storage) {
    $fid = $media_entity
      ->get($field_name)->target_id;
    $file = File::load($fid);
    $background_url = $file
      ->createFileUrl();
    $style = 'background-image: url(' . $background_url . ');';
    $background_position = 'background-position: center;';
    $background_repeat = 'background-repeat: no-repeat;';
    $background_size = 'background-size: cover;';
    $background_attachment = '';
    if (isset($storage['background_media']['background_options'])) {

      // Background position.
      if (isset($storage['background_media']['background_options']['background_position']) && !empty($storage['background_media']['background_options']['background_position'])) {
        $background_position = 'background-position: ' . $storage['background_media']['background_options']['background_position'] . ';';
      }

      // Background repeat.
      if (isset($storage['background_media']['background_options']['background_repeat']) && !empty($storage['background_media']['background_options']['background_repeat'])) {
        $background_repeat = 'background-repeat: ' . $storage['background_media']['background_options']['background_repeat'] . ';';
      }

      // Background attachment.
      if (isset($storage['background_media']['background_options']['background_attachment']) && !empty($storage['background_media']['background_options']['background_attachment'])) {
        if ($storage['background_media']['background_options']['background_attachment'] != 'not_fixed') {
          $background_attachment = 'background-attachment: ' . $storage['background_media']['background_options']['background_attachment'] . ';';
        }
      }

      // Background size.
      if (isset($storage['background_media']['background_options']['background_size']) && !empty($storage['background_media']['background_options']['background_size'])) {
        $background_size = 'background-size: ' . $storage['background_media']['background_options']['background_size'] . ';';
      }
    }
    $style .= ' ' . $background_position;
    $style .= ' ' . $background_repeat;
    $style .= ' ' . $background_size;
    if ($background_attachment) {
      $style .= ' ' . $background_attachment;
    }
    return $style;
  }

  /**
   * Helper function to the background media local video style.
   *
   * @param object $media_entity
   *   A media entity object.
   * @param object $field_name
   *   The Media entity local video field name.
   *
   * @return string
   *   Background media local video style.
   */
  public function buildBackgroundMediaLocalVideo($media_entity, $field_name) {
    $fid = $media_entity
      ->get($field_name)->target_id;
    $file = File::load($fid);
    return $file
      ->createFileUrl();
  }

}

Classes

Namesort descending Description
BackgroundMedia Class BackgroundMedia.