panopoly_media-8.x-2.x-dev/panopoly_media.module

panopoly_media.module
<?php

/**
 * @file
 * Hook implementations for Panopoly Media.
 */

use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Entity\EntityListBuilder;
use Drupal\Core\Form\FormStateInterface;
use Drupal\file\Entity\File;
use Drupal\media\IFrameMarkup;
use Drupal\panopoly_media\FileAccessControlHandler;
use Drupal\panopoly_media\Form\FileDeleteForm;
use Drupal\panopoly_media\Plugin\Field\FieldWidget\ImageWidget;
use Drupal\panopoly_media\Routing\FileRouteProvider;

/**
 * Implements hook_theme().
 */
function panopoly_media_theme() {
  return [
    'media__image' => [
      'base hook' => 'media',
    ],
    'media__file' => [
      'base hook' => 'media',
    ],
    'media__video' => [
      'base hook' => 'media',
    ],
  ];
}

/**
 * Implements hook_block_alter().
 */
function panopoly_media_block_alter(&$definitions) {
  $custom_blocks = [
    'inline_block:panopoly_media_video',
  ];
  foreach ($custom_blocks as $custom_block) {
    if (isset($definitions[$custom_block])) {
      $definitions[$custom_block]['category'] = t('Custom');
    }
  }
}

/**
 * Implements hook_block_view_alter().
 */
function panopoly_media_block_view_alter(array &$build, BlockPluginInterface $block) {
  if ($block->getBaseId() === 'page_title_block') {
    $current_route_name = \Drupal::routeMatch()->getRouteName();

    $entity_browsers = [
      'panopoly_media_field_media_browser',
      'panopoly_media_field_video_browser',
      'panopoly_media_wysiwyg_media_browser',
    ];
    foreach ($entity_browsers as $entity_browser) {
      if ($current_route_name === "entity_browser.{$entity_browser}") {
        $build['#access'] = FALSE;
        break;
      }
    }
  }
}

/**
 * Implements hook_theme_registry_alter().
 */
function panopoly_media_theme_registry_alter(&$theme_registry) {
  // If in Olivero, replace the HTML template for the entity browser modal.
  if (isset($theme_registry['block']['preprocess functions']) && in_array('olivero_preprocess_block', $theme_registry['block']['preprocess functions'])) {
    /** @var \Drupal\Core\Extension\ModuleExtensionList $moduleList */
    $moduleList = \Drupal::service('extension.list.module');

    // Ensure that we're using the module version of the template, and not
    // one overridden in a sub-theme.
    $entity_browser_iframe =& $theme_registry['html__entity_browser__modal'];
    if ($entity_browser_iframe['path'] === $moduleList->getPath('entity_browser') . '/templates') {
      $entity_browser_iframe['template'] = 'html--entity-browser--modal-olivero';
      $entity_browser_iframe['theme path'] = $moduleList->getpath('panopoly_media');
      $entity_browser_iframe['path'] = $entity_browser_iframe['theme path'] . '/templates';
    }
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Alters the display mode offerings of the embed entity module to be more
 * user friendly, and reflect what is available.
 */
function panopoly_media_form_entity_embed_dialog_alter(&$form, FormStateInterface $form_state) {
  if ($form_state->get('step') == 'embed') {
    /** @var \Drupal\Core\Entity\EntityInterface $entity */
    $entity = $form_state->get('entity');
    switch ($entity->bundle()) {
      case 'panopoly_media_image':
        $options =& $form['attributes']['data-entity-embed-display']['#options'];
        $rename_options = [
          'view_mode:media.embed_large' => t('Original size'),
          'view_mode:media.embed_medium' => t('Quarter size'),
          'view_mode:media.embed_small' => t('Thumbnail'),
          'entity_reference:media_thumbnail' => t('Custom'),
        ];
        foreach (array_keys($options) as $key) {
          if (isset($rename_options[$key])) {
            $options[$key] = $rename_options[$key];
          }
        }

        $embed_display_element =& $form['attributes']['data-entity-embed-display-settings'];
        if (array_key_exists('image_style', $embed_display_element)) {
          foreach ($embed_display_element['image_style']['#options'] as $key => $option) {
            // @todo Expose this as a setting in Panopoly settings.
            if (strpos($key, 'panopoly_') === FALSE) {
              unset($embed_display_element['image_style']['#options'][$key]);
            }
          }
        }
        break;

      // There are no custom displays for files or videos. Force to default
      // for now, until file (PDF preview) or video formatters (set size) added.
      case 'panopoly_media_video':
      case 'panopoly_media_file':
        $form['attributes']['data-entity-embed-display']['#default_value'] = 'view_mode:media.embed_large';
        $form['attributes']['data-entity-embed-display']['#access'] = FALSE;
    }
  }
}

/**
 * Implements hook_field_formatter_info_alter().
 */
function panopoly_media_field_formatter_info_alter(&$definitions) {
  if (isset($definitions['file_default']) && !in_array('image', $definitions['file_default']['field_types'])) {
    $definitions['file_default']['field_types'][] = 'image';
  }
}

/**
 * Implements hook_field_widget_info_alter().
 */
function panopoly_media_field_widget_info_alter(array &$info) {
  $info['image_image']['class'] = ImageWidget::class;
}

/**
 * Implements hook_inline_entity_form_entity_form_alter().
 */
function panopoly_media_inline_entity_form_entity_form_alter(&$entity_form, &$form_state) {
  // Only deal with media.
  if ($entity_form['#entity_type'] != 'media') {
    return;
  }

  $entity_form['revision_log_message']['#access'] = FALSE;
}

/**
 * Implements hook_field_widget_form_alter().
 */
function panopoly_media_field_widget_form_alter(&$element, FormStateInterface $form_state, $context) {
  $widgets = ['file_generic', 'image_image'];
  if (in_array($context['widget']->getPluginId(), $widgets)) {
    $element['#process'][] = 'panopoly_media_field_widget_process';
    $element['#element_validate'][] = 'panopoly_media_widget_duplicate_validate';
  }
}

/**
 * Process callback for file and image widgets to add duplicate acknowledgement.
 */
function panopoly_media_field_widget_process(&$element, FormStateInterface $form_state, $form) {
  $parents = $element['#parents'];
  $values = $form_state->getValue($parents);

  $files = File::loadMultiple($values['fids']);
  $duplicate = panopoly_media_duplicate_files($files, TRUE);
  $element['#panopoly_media_is_duplicate'] = $duplicate;

  if ($duplicate) {
    $element['panopoly_media_duplicate'] = [
      '#type' => 'checkbox',
      '#title' => t('Acknowledge duplicate upload'),
      '#default_value' => FALSE,
    ];
  }

  return $element;
}

/**
 * Determines if a file is or if set of files has a duplicate.
 *
 * @param \Drupal\file\FileInterface|\Drupal\file\FileInterface[] $files
 *   The file or files.
 * @param bool $new_only
 *   Optional. Indicates if only new files should be checked for duplicity.
 *
 * @return bool
 *   Indicates if there is a duplicate.
 */
function panopoly_media_duplicate_files($files, $new_only = FALSE) {
  // Soft dependency on filehash.
  if (!\Drupal::moduleHandler()->moduleExists('filehash')) {
    return FALSE;
  }

  // Normalize into an array.
  if (!is_array($files)) {
    $files = [$files];
  }

  // Check only newly-created files.
  if ($new_only) {
    $files = array_filter($files, function ($file) {
      /** @var \Drupal\file\FileInterface $file */
      return $file->isTemporary();
    });
  }

  // If no files, we've got nothing to do.
  if (empty($files)) {
    return FALSE;
  }

  // Gather file IDs.
  $fids = array_map(function ($file) {
    /** @var \Drupal\file\FileInterface $file */
    return $file->id();
  }, $files);

  // Check each used algorithm for duplicate.
  foreach (filehash_algos() as $algo) {
    $hashes = array_map(function ($file) use ($algo) {
      return $file->filehash[$algo];
    }, $files);
    if (!$hashes) {
      break;
    }

    // Query for duplicates.
    $query = \Drupal::database()->select('filehash');
    $query->addField('filehash', 'fid');
    $query->condition('fid', $fids, 'NOT IN');
    $query->condition($algo, $hashes, 'IN');
    $query->range(0, 1);
    if ($fid = $query->execute()->fetchField()) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
 * Validation handler for duplicate file uploads.
 */
function panopoly_media_widget_duplicate_validate(&$element, FormStateInterface &$form_state) {
  // Only validate on submit.
  $triggering_element = $form_state->getTriggeringElement();
  if (!empty($triggering_element['#submit']) && in_array('file_managed_file_submit', $triggering_element['#submit'])) {
    if (strpos($triggering_element['#name'], '_upload_button') === FALSE) {
      return;
    }
  }

  $parents = $element['#parents'];
  $values = $form_state->getValue($parents);

  // If there is a duplicate, verify "Acknowledge duplicate upload" box checked.
  if (!empty($element['#panopoly_media_is_duplicate']) && empty($values['panopoly_media_duplicate'])) {
    $form_state->setError($element, t('Duplicate file uploaded. Please check the media library for an existing file or check the "Acknowledge duplicate upload" box to continue with this upload.'));
  }
}

/**
 * Implements hook_entity_type_alter().
 */
function panopoly_media_entity_type_alter(array &$entity_types) {
  /** @var \Drupal\Core\Entity\EntityTypeInterface[] $entity_types */

  // Allows "operations" on file entities.
  if (!$entity_types['file']->hasHandlerClass('list_builder')) {
    $entity_types['file']->setListBuilderClass(EntityListBuilder::class);
  }

  // Provides a delete form.
  if (!$entity_types['file']->hasHandlerClass('form', 'delete')) {
    $handlers = $entity_types['file']->getHandlerClasses();
    $handlers['form']['delete'] = FileDeleteForm::class;
    $entity_types['file']->setHandlerClass('form', $handlers['form']);
  }

  // Provides a delete form link template.
  if (!$entity_types['file']->hasLinkTemplate('delete-form')) {
    $entity_types['file']->setLinkTemplate('delete-form', '/file/{file}/delete');
  }

  // Provides routes.
  if (!$entity_types['file']->hasHandlerClass('route_provider', 'html')) {
    $entity_types['file']->setHandlerClass('route_provider', ['html' => FileRouteProvider::class]);
  }

  // Set access handler.
  $entity_types['file']->setAccessClass(FileAccessControlHandler::class);
}

/**
 * Implements hook_views_data_alter().
 */
function panopoly_media_views_data_alter(&$data) {
  $data['file_managed']['panopoly_media_file_managed_bulk_form'] = [
    'title' => t('File operations bulk form'),
    'help' => t('Add a form element that lets you run operations on multiple files.'),
    'field' => [
      'id' => 'panopoly_media_file_managed_bulk_form',
    ],
  ];
}

/**
 * Implements hook_preprocess_HOOK().
 */
function panopoly_media_preprocess_media_oembed_iframe(&$variables) {
  $config = \Drupal::config('panopoly_media.settings');
  if ($config->get('youtube_nocookie')) {
    /** @var \Drupal\media\IFrameMarkup $media */
    $html = (string) $variables['media'];
    $html = str_replace('youtube.com', 'youtube-nocookie.com', $html);
    $variables['media'] = IFrameMarkup::create($html);
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function panopoly_media_form_media_settings_form_alter(&$form) {
  $config = \Drupal::config('panopoly_media.settings');

  $form['panopoly_media'] = [
    '#type' => 'fieldset',
    '#title' => t('Panopoly Media'),
  ];

  $form['panopoly_media']['panopoly_media_youtube_nocookie'] = [
    '#type' => 'checkbox',
    '#title' => t('YouTube no-cookie'),
    '#description' => t("Use YouTube's privacy-enhanced mode."),
    '#default_value' => $config->get('youtube_nocookie'),
  ];

  $form['actions']['#weight'] = 101;
  $form['#submit'][] = '_panopoly_media_media_settings_form_submit';
}

/**
 * Submit handler for media_settings_form.
 */
function _panopoly_media_media_settings_form_submit($form, FormStateInterface $form_state) {
  $config = \Drupal::configFactory()->getEditable('panopoly_media.settings');
  $config->set('youtube_nocookie', $form_state->getValue('panopoly_media_youtube_nocookie'));
  $config->save();
}

/**
 * Implements hook_form_FORM_ID_form_alter().
 */
function panopoly_media_form_views_exposed_form_alter(&$form, FormStateInterface $form_state) {
  /** @var \Drupal\views\Entity\View $view */
  $view = $form_state->get('view');
  if ($view->id() === 'panopoly_media_browser') {
    // Reduce size from 60 to 30, so it fits better.
    $form['tags']['#size'] = 30;
  }
}

/**
 * Implements hook_preprocess_views_view().
 */
function panopoly_media_preprocess_views_view(&$variables) {
  if ($variables['view']->id() === 'panopoly_media_browser') {
    $variables['view_array']['#attached']['library'][] = 'panopoly_media/panopoly_media_browser';
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc