You are here

lightning_media.install in Lightning Media 8.3

Contains install and update routines for Lightning Media.

File

lightning_media.install
View source
<?php

/**
 * @file
 * Contains install and update routines for Lightning Media.
 */
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Core\File\Exception\FileException;
use Drupal\Core\Utility\UpdateException;
use Drupal\editor\Entity\Editor;
use Drupal\embed\Entity\EmbedButton;
use Drupal\entity_browser\Entity\EntityBrowser;
use Drupal\file\Entity\File;
use Drupal\lightning_core\ConfigHelper as Config;
use Drupal\lightning_core\Element;
use Drupal\lightning_core\Entity\EntityViewMode;
use Drupal\media\Entity\MediaType;
use Drupal\views\Entity\View;

/**
 * Implements hook_install().
 */
function lightning_media_install() {

  // Don't do anything during config sync.
  if (\Drupal::isConfigSyncing()) {
    return;
  }
  user_role_grant_permissions('anonymous', [
    'view media',
  ]);
  user_role_grant_permissions('authenticated', [
    'view media',
  ]);

  // Set the icon for the media_browser embed button.
  lightning_media_update_8006();

  // Grant the creator content role permission to use the rich_text format and
  // the media browser.
  if (\Drupal::moduleHandler()
    ->moduleExists('lightning_roles')) {
    lightning_media_modules_installed([
      'lightning_roles',
    ]);
  }

  // Add the media.embedded view mode to the media_browser embed button. It
  // cannot be part of the original embed button config entity because the view
  // mode is itself installed at the same time as the button, as part of this
  // module's default configuration -- which means that it might not exist when
  // the button is installed, resulting in a scary PluginNotFoundException.
  lightning_media_update_8013();
}

/**
 * Alerts users of Libraries API dependencies.
 *
 * A future version of Lightning Media will remove Libraries API, so
 * users must add that dependency to composer.json manually.
 *
 * @todo Remove this function when Libraries API is no longer shipped with Lightning Media.
 */
function lightning_media_requirements() {
  $requirements = [];
  $libraries_dependencies = [];
  $enabled_modules = \Drupal::service('extension.list.module')
    ->getAllInstalledInfo();
  foreach ($enabled_modules as $module => $info) {
    if (isset($info['dependencies']) && array_intersect($info['dependencies'], [
      'libraries:libraries',
      'libraries',
    ])) {
      $libraries_dependencies[$module] = $info['name'];
    }
  }
  if ($libraries_dependencies) {
    $requirements['lightning_libraries'] = [
      'title' => t('Libraries API dependencies'),
      'value' => t('These modules require Libraries API: %module_list. Lightning Media 4.0 will <strong>not</strong> include Libraries API as a dependency, so you must add that dependency to your composer.json manually. For example: <code>composer require drupal/libraries</code>.', [
        '%module_list' => Element::oxford($libraries_dependencies),
      ]),
      'severity' => REQUIREMENT_WARNING,
    ];
  }
  return $requirements;
}

/**
 * Removed in Lightning 8.x-1.0-rc6.
 *
 * Formerly updated the media_library view, installs Services module, and
 * created the lightning_media service endpoint.
 */
function lightning_media_update_8001() {
}

/**
 * Activates Lightning Media sub-features.
 */
function lightning_media_update_8002() {
  \Drupal::service('module_installer')
    ->install([
    'features',
    'lightning_media_image',
    'lightning_media_instagram',
    'lightning_media_twitter',
    'lightning_media_video',
  ]);
}

/**
 * Removed in Lightning 8.x-2.06.
 *
 * Formerly created the media_creator and media_manager roles.
 */
function lightning_media_update_8003() {
}

/**
 * Removed in Lightning 8.x-1.0-rc6.
 *
 * Formerly granted the content-related roles access to the rich_text input
 * format.
 */
function lightning_media_update_8004() {
}

/**
 * Installs the media browser and its embed button.
 */
function lightning_media_update_8005() {
  \Drupal::service('module_installer')
    ->install([
    'entity_browser',
  ]);
  $config = Config::forModule('lightning_media');
  $config
    ->getEntity('entity_form_mode', 'media.media_browser')
    ->save();
  $config
    ->getEntity('entity_browser', 'media_browser')
    ->save();
  $config
    ->getEntity('embed_button', 'media_browser')
    ->save();
}

/**
 * Sets the icon for the media browser's embed button.
 */
function lightning_media_update_8006() {
  $source = __DIR__ . '/images/star.png';
  $destination = 'public://star.png';

  // In Drupal 8.7.0 and later, we need to use FileSystemInterface::copy() to
  // avoid deprecated code. But in previous versions of Drupal, we need to use
  // file_unmanaged_copy(), which we need to invoke in an obscure way so that
  // PHPStan doesn't get mad at us for calling a deprecated function.
  if (version_compare(Drupal::VERSION, '8.7.0', '>=')) {
    try {
      $destination = Drupal::service('file_system')
        ->copy($source, $destination);
    } catch (FileException $e) {
      $destination = FALSE;
    }
  }
  else {
    $destination = call_user_func('file_unmanaged_copy', $source, $destination);
  }
  if ($destination) {
    $file = File::create([
      'uri' => $destination,
    ]);
    $file
      ->save();
    EmbedButton::load('media_browser')
      ->set('icon_uuid', $file
      ->uuid())
      ->save();
  }
  else {
    return t("Unable to copy @source to the public files directory.", [
      '@source' => $source,
    ]);
  }
}

/**
 * Deletes the media_library view.
 */
function lightning_media_update_8007() {
  $view = View::load('media_library');
  if ($view) {
    $view
      ->delete();
  }
}

/**
 * Removed in Lightning 8.x-2.21.
 *
 * Formerly created the media browser display of the media view.
 *
 * @see lightning_media_view_insert()
 */
function lightning_media_update_8008() {
}

/**
 * Changes the media_library CKEditor button to media_browser.
 */
function lightning_media_update_8009() {

  /** @var \Drupal\editor\EditorInterface $editor */
  $editor = Editor::load('rich_text');
  if ($editor) {
    $settings = $editor
      ->getSettings();
    foreach ($settings['toolbar']['rows'] as &$row) {
      foreach ($row as &$group) {
        $index = array_search('media_library', $group['items']);
        if ($index !== FALSE) {
          $group['items'][$index] = 'media_browser';
        }
      }
    }
    $editor
      ->setSettings($settings)
      ->save();
  }
}

/**
 * Installs document support for Lightning Media.
 */
function lightning_media_update_8010() {
  \Drupal::service('module_installer')
    ->install([
    'lightning_media_document',
  ]);
}

/**
 * Removed in Lightning 8.x-2.06.
 *
 * Formerly granted the creator content role access to the rich_text input
 * format and the media browser.
 */
function lightning_media_update_8011() {
}

/**
 * Adds the library filter to the media view's Entity Browser display.
 */
function lightning_media_update_8012() {

  /** @var \Drupal\entity_browser\EntityBrowserInterface $browser */
  $browser = EntityBrowser::load('media_browser');
  if (empty($browser)) {
    return;
  }

  /** @var \Drupal\entity_browser\WidgetInterface $widget */
  foreach ($browser
    ->getWidgets() as $widget) {
    if ($widget
      ->getPluginId() == 'view') {
      $configuration = $widget
        ->getConfiguration();
      if ($configuration['settings']['view'] == 'media') {

        /** @var \Drupal\views\ViewEntityInterface $view */
        $view = View::load('media');

        // Reference the display options directly, for readability.
        $display =& $view
          ->getDisplay($configuration['settings']['view_display'])['display_options'];

        // It's possible that the site owner took matters into their own hands
        // and configured the filter already, so only add it if it's not there.
        if (empty($display['filters']['field_media_in_library_value'])) {
          $display['filters']['field_media_in_library_value'] = unserialize('a:14:{s:2:"id";s:28:"field_media_in_library_value";s:5:"table";s:29:"media__field_media_in_library";s:5:"field";s:28:"field_media_in_library_value";s:12:"relationship";s:4:"none";s:10:"group_type";s:5:"group";s:11:"admin_label";s:0:"";s:8:"operator";s:1:"=";s:5:"value";b:1;s:5:"group";i:1;s:7:"exposed";b:0;s:6:"expose";a:10:{s:11:"operator_id";s:0:"";s:5:"label";s:0:"";s:11:"description";s:0:"";s:12:"use_operator";b:0;s:8:"operator";s:0:"";s:10:"identifier";s:0:"";s:8:"required";b:0;s:8:"remember";b:0;s:8:"multiple";b:0;s:14:"remember_roles";a:1:{s:13:"authenticated";s:13:"authenticated";}}s:10:"is_grouped";b:0;s:10:"group_info";a:10:{s:5:"label";s:0:"";s:11:"description";s:0:"";s:10:"identifier";s:0:"";s:8:"optional";b:1;s:6:"widget";s:6:"select";s:8:"multiple";b:0;s:8:"remember";b:0;s:13:"default_group";s:3:"All";s:22:"default_group_multiple";a:0:{}s:11:"group_items";a:0:{}}s:9:"plugin_id";s:7:"boolean";}');
          $view
            ->save();
        }
      }
    }
  }
}

/**
 * Adds the media.embedded view display to the media_browser embed button.
 */
function lightning_media_update_8013() {
  $button = EmbedButton::load('media_browser');
  if ($button) {

    // During installation, the media.embedded view mode may have just been
    // created as part of this module's default configuration. So we need to
    // clear Entity Embed's display plugin definition cache to ensure that it
    // picks up the new view mode's corresponding display plugin.
    \Drupal::service('plugin.manager.entity_embed.display')
      ->clearCachedDefinitions();
    $type_settings = $button
      ->getTypeSettings();
    $type_settings['display_plugins'][] = 'view_mode:media.embedded';
    $button
      ->set('type_settings', $type_settings);
    $button
      ->save();
  }
}

/**
 * Clears the entity type definition cache.
 */
function lightning_media_update_8014() {
  \Drupal::entityTypeManager()
    ->clearCachedDefinitions();
}

/**
 * Creates the thumbnail view mode for media items.
 */
function lightning_media_update_8015() {
  Config::forModule('lightning_media')
    ->getEntity('entity_view_mode', 'media.thumbnail')
    ->save();
}

/**
 * Creates the lightning_media.settings config object.
 */
function lightning_media_update_8016() {
  Config::forModule('lightning_media')
    ->get('lightning_media.settings')
    ->set('entity_embed.choose_display', TRUE)
    ->save();
}

/**
 * Changes all image_immutable field widgets to image_image.
 */
function lightning_media_update_8017() {
  \Drupal::service('plugin.manager.field.widget')
    ->clearCachedDefinitions();

  /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
  foreach (EntityFormDisplay::loadMultiple() as $form_display) {
    foreach ($form_display
      ->getComponents() as $key => $component) {
      if ($component['type'] == 'image_immutable') {
        $component['third_party_settings']['lightning_media'] = [
          'file_links' => FALSE,
          'remove_button' => FALSE,
        ];
        $component['type'] = 'image_image';
        $form_display
          ->setComponent($key, $component);
      }
    }
    $form_display
      ->save();
  }
}

/**
 * Updates the media browser's argument validation.
 */
function lightning_media_update_8018() {
  $browser = EntityBrowser::load('media_browser');
  $view = View::load('media');
  if (empty($browser) || empty($view)) {
    return;
  }
  $widgets = $browser
    ->get('widgets');
  foreach ($widgets as &$widget) {
    if ($widget['id'] == 'view' && $widget['settings']['view'] == $view
      ->id()) {
      $display =& $view
        ->getDisplay($widget['settings']['view_display']);
      $keys = [
        'display_options',
        'arguments',
        'bundle',
        'validate',
        'type',
      ];
      if (NestedArray::getValue($display, $keys) == 'entity:media_bundle') {
        NestedArray::setValue($display, $keys, 'entity:media_type');
      }
      $view
        ->save();
      break;
    }
  }
}

/**
 * Installs the core Media library module.
 */
function lightning_media_update_8019() {

  // Lightning used to provide a Media Library view mode in the past.
  // This is conflicting with the module's Media library view mode.
  $view_mode = EntityViewMode::load('media.media_library');
  if ($view_mode && !Drupal::moduleHandler()
    ->moduleExists('media_library')) {
    $label = $view_mode
      ->label();
    throw new UpdateException("Can't install Media library, because the media.media_library view mode ({$label}) already exists.");
  }
  Drupal::service('module_installer')
    ->install([
    'media_library',
  ]);
  foreach (MediaType::loadMultiple() as $media_type) {
    $bundle = $media_type
      ->id();
    if (EntityViewDisplay::load("media.{$bundle}.media_library")) {
      continue;
    }

    // If the Media library view mode doesn't already exist create one
    // containing only the thumbnail field.
    $display = EntityViewDisplay::create([
      'targetEntityType' => 'media',
      'bundle' => $bundle,
      'mode' => 'media_library',
      'status' => TRUE,
    ]);
    $display
      ->set('content', []);
    $display
      ->setComponent('thumbnail', [
      'type' => 'image',
      'region' => 'content',
      'label' => 'hidden',
      'settings' => [
        'image_style' => 'thumbnail',
      ],
    ]);
    $display
      ->save();
  }
}

/**
 * Sets the default value of the entity_browser.override_widget config switch.
 */
function lightning_media_update_8020() {
  Drupal::configFactory()
    ->getEditable('lightning_media.settings')
    ->set('entity_browser.override_widget', TRUE)
    ->save();
}

/**
 * Sets the default value of the revision_ui config switch.
 */
function lightning_media_update_8021() {
  Drupal::configFactory()
    ->getEditable('lightning_media.settings')
    ->set('revision_ui', TRUE)
    ->save();
}

/**
 * Implements hook_update_dependencies().
 */
function lightning_media_update_dependencies() {
  $dependencies = [
    'lightning_media' => [
      8017 => [
        'media_entity' => 8201,
      ],
      8018 => [
        'media_entity' => 8201,
      ],
    ],
    'media_entity' => [
      8201 => [
        'system' => 8402,
      ],
    ],
  ];
  if (\Drupal::moduleHandler()
    ->moduleExists('lightning_api')) {
    $dependencies['media_entity'][8201]['lightning_api'] = 8002;
    $dependencies['lightning_media'][8017]['lightning_api'] = 8002;
  }
  return $dependencies;
}

Functions

Namesort descending Description
lightning_media_install Implements hook_install().
lightning_media_requirements Alerts users of Libraries API dependencies.
lightning_media_update_8001 Removed in Lightning 8.x-1.0-rc6.
lightning_media_update_8002 Activates Lightning Media sub-features.
lightning_media_update_8003 Removed in Lightning 8.x-2.06.
lightning_media_update_8004 Removed in Lightning 8.x-1.0-rc6.
lightning_media_update_8005 Installs the media browser and its embed button.
lightning_media_update_8006 Sets the icon for the media browser's embed button.
lightning_media_update_8007 Deletes the media_library view.
lightning_media_update_8008 Removed in Lightning 8.x-2.21.
lightning_media_update_8009 Changes the media_library CKEditor button to media_browser.
lightning_media_update_8010 Installs document support for Lightning Media.
lightning_media_update_8011 Removed in Lightning 8.x-2.06.
lightning_media_update_8012 Adds the library filter to the media view's Entity Browser display.
lightning_media_update_8013 Adds the media.embedded view display to the media_browser embed button.
lightning_media_update_8014 Clears the entity type definition cache.
lightning_media_update_8015 Creates the thumbnail view mode for media items.
lightning_media_update_8016 Creates the lightning_media.settings config object.
lightning_media_update_8017 Changes all image_immutable field widgets to image_image.
lightning_media_update_8018 Updates the media browser's argument validation.
lightning_media_update_8019 Installs the core Media library module.
lightning_media_update_8020 Sets the default value of the entity_browser.override_widget config switch.
lightning_media_update_8021 Sets the default value of the revision_ui config switch.
lightning_media_update_dependencies Implements hook_update_dependencies().