You are here

Media.php in GridStack 8.2

File

src/Plugin/gridstack/stylizer/Media.php
View source
<?php

namespace Drupal\gridstack\Plugin\gridstack\stylizer;

use Drupal\Component\Serialization\Json;
use Drupal\media\Entity\Media as MediaEntity;
use Drupal\gridstack\GridStackDefault;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides the media styles for front-end.
 *
 * @GridStackStylizer(
 *   id = "media",
 *   label = @Translation("Media")
 * )
 */
class Media extends Background {

  /**
   * The field name to store media.
   *
   * @var string
   */
  protected $fieldName;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
    if (!empty($configuration['field_name'])) {
      $instance
        ->setFieldName($configuration['field_name']);
    }
    return $instance;
  }

  /**
   * Returns the selected field name.
   */
  public function getFieldName() {
    return $this->fieldName;
  }

  /**
   * Sets the field name.
   */
  public function setFieldName($name) {
    $this->fieldName = $name;
    return $this;
  }

  /**
   * Returns the formatted media as Blazy CSS background.
   */
  public function buildMedia(array &$attributes, array &$settings) {
    $data = $this
      ->prepareMedia($settings);
    $config = $data['settings'];
    if (isset($config['media_id']) && ($mid = $config['media_id'])) {
      $media = MediaEntity::load($mid);

      // @todo remove post blazy:2.1+.
      if (isset($config['responsive_image_style']) && ($resimage = $config['responsive_image_style'])) {
        $data['settings']['resimage'] = $this->blazyEntity
          ->blazyManager()
          ->entityLoad($resimage, 'responsive_image_style');
      }

      // Pass results to \Drupal\blazy\BlazyEntity.
      $settings['has_media'] = TRUE;
      $attributes['class'][] = 'is-gs-media';
      return $this->blazyEntity
        ->build($data, $media, $media
        ->label());
    }
    return [];
  }

  /**
   * Returns the formatted media as Blazy output.
   */
  protected function prepareMedia(array $settings) {
    $build = [];
    $data = $this
      ->mediaSettings($settings);
    if (!empty($data['media_id'])) {

      // Unlike Bootstrap, Foundation wants large-12, etc., not cell-12.
      // Specific for this, Foundation is less efficient than Bootstrap.
      $build['wrapper_attributes']['class'][] = 'box__bg';
      $build['attributes']['class'][] = 'b-noratio b-gs';
      $build['attributes']['class'][] = $this
        ->getStyle('background', $settings) ? 'b-gs--bg' : 'b-gs--media';
      if ($animations = $this
        ->getAnimation($settings, 'all')) {
        foreach ($animations as $key => $value) {
          $key = str_replace('_', '-', $key);
          $key = $key == 'animation' ? $key : 'animation-' . $key;

          // @todo pos blazy 2.1:
          if ($key == 'animation') {
            $data['fx'] = $value;
          }
          else {
            $build['attributes']['data-' . $key] = $value;
          }
        }

        // @todo $build['media_attributes']['class'][] = 'box__animated';
      }

      // Overlay is only applicable to image, not video, of course.
      if ($data['media_source'] == 'image') {
        $this
          ->prepareOverlay($data, $settings);
      }

      // Image opacity.
      if (!empty($data['opacity']) && $data['opacity'] < 1) {
        $build['attributes']['style'] = 'opacity: ' . $data['opacity'] . ';';
      }

      // Disable any effect, we'll toggle by JS till required instead.
      // @todo figure out to make multiple animations work.
      // @todo if (!empty($settings['_ipe'])) {
      // @todo  $data['_fx'] = '';
      // @todo }
    }
    $build['settings'] = $data;
    return $build;
  }

  /**
   * Returns the media overlay.
   */
  protected function prepareOverlay(array &$data, array $settings) {
    $bg = $this
      ->getBackgroundColor($settings, FALSE);
    $use_overlay = $this
      ->getStyle('overlay', $settings);

    // Always output for admin for live preview to work.
    // @todo use ::pseudo selector for front-end.
    $overlay = [
      '#theme' => 'container',
      '#attributes' => [
        'class' => [
          'media__overlay',
        ],
      ],
    ];

    // Only inline CSS at admin pages, front-end should be cleaner.
    if ($use_overlay && $bg && !empty($settings['_ipe'])) {
      $overlay['#attributes']['style'] = $bg;
    }

    // @todo post blazy 2.1
    // @todo $build['overlay']['gridstack'] = $overlay;
    // @todo $build['overlay']['gridstack']['#weight'] = 100;
    $data['icon']['gridstack_overlay'] = $overlay;
    $data['icon']['gridstack_overlay']['#weight'] = 100;

    // Remove from front-end if not configured so.
    if (empty($settings['_ipe'])) {
      if ($use_overlay && empty($bg)) {
        unset($data['icon']['gridstack_overlay']);
      }
    }
  }

  /**
   * Returns the data understood by Blazy for CSS background.
   */
  protected function mediaSettings(array $settings) {
    $styles = empty($settings['styles']) ? [] : $settings['styles'];
    $data = empty($styles['metadata']) ? [] : Json::decode($styles['metadata']);

    // Hard-code settings for now to limit too many possibilities.
    if ($data) {
      $data['background'] = $this
        ->getStyle('background', $settings);
      $data['media_switch'] = 'media';
      $data['ratio'] = '';
      $data['_detached'] = FALSE;
      $data = array_merge($styles, $data);
      return array_merge(GridStackDefault::entitySettings(), $data);
    }
    return [];
  }

}

Classes

Namesort descending Description
Media Provides the media styles for front-end.