content_packager-8.x-1.x-dev/src/PluginForm/RestSourcePackage.php
src/PluginForm/RestSourcePackage.php
<?php namespace Drupal\content_packager\PluginForm; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\DependencyInjection\DependencySerializationTrait; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\ConfigFormBaseTrait; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerTrait; use Drupal\Core\Plugin\PluginFormBase; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\Url; use Drupal\rest\Plugin\views\display\RestExport; use Drupal\views\Views; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Rest Export Plugin's "Package" form. * * @package Drupal\content_packager\PluginForm */ class RestSourcePackage extends PluginFormBase implements ContainerInjectionInterface { use ConfigFormBaseTrait; use StringTranslationTrait; use MessengerTrait; // Serialization during batch process due to the $this in #ajax callback. use DependencySerializationTrait; private $moduleHandler; /** * RestSourcePackage constructor. * * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * The config factory. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler. */ public function __construct(ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler) { $this->setConfigFactory($config_factory); $this->moduleHandler = $module_handler; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static($container ->get('config.factory'), $container->get('module_handler') ); } /** * Sets the config factory for this form. * * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * The config factory. * * @return $this */ public function setConfigFactory(ConfigFactoryInterface $config_factory) { $this->configFactory = $config_factory; return $this; } /** * {@inheritdoc} */ protected function getEditableConfigNames() { return []; } /** * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $available_views = content_packager_get_rest_export_views(); $view_options = []; foreach ($available_views as $display) { $view_options[$display[0]] = $display[0]; } if (empty($available_views)) { $suggestion = 'Configure a REST Export'; $t_args = []; if ($this->moduleHandler->moduleExists('views_ui') && \Drupal::currentUser()->hasPermission('administer views')) { $suggestion .= ' via the <a href=":views-ui">Views UI</a>.'; $t_args[':views-ui'] = Url::fromRoute('entity.view.collection')->toString(); } $markup = $this ->t("No available REST Exports found. You should $suggestion to use one as Package source.", $t_args); $form['selected_view'] = [ '#markup' => $markup, ]; return $form; } $selected_view = $form_state->getValue('selected_view', reset($view_options)); $displays = []; if ($selected_view) { $view = Views::getView($selected_view); $displays = $view->storage->get('display'); } $rest_displays = []; foreach ($displays as $display) { if ($display['display_plugin'] === 'rest_export') { $rest_displays[$display['id']] = $display['id']; } } $form['selected_view'] = [ '#type' => 'select', '#title' => $this->t('View to export'), '#default_value' => '', '#options' => $view_options, '#ajax' => [ 'callback' => [$this, 'viewSelectChanged'], 'event' => 'change', 'wrapper' => 'display-wrapper', ], ]; $form['display_ajax'] = [ '#type' => 'container', '#attributes' => [ 'id' => ['display-wrapper'], ], ]; $form['display_ajax']['selected_display'] = [ '#type' => 'select', '#title' => $this->t('View display'), '#default_value' => '', '#options' => $rest_displays, ]; return $form; } /** * Ajax callback. */ public function viewSelectChanged(array $form, FormStateInterface $form_state) { return $form['make_package']['source_ajax']['rest']['display_ajax']; } public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { $view_id = $form_state->getValue('selected_view'); $display_id = $form_state->getValue('selected_display'); if (empty($view_id)) { $msg = $this->t('View information is missing, and packaging cannot proceed.'); $form_state->setErrorByName('make_package][rest', $msg); $this->messenger()->addError($msg); return; } if (empty($display_id)) { $msg = $this->t('Could not find an appropriate REST Export display for the selected view to render!'); $form_state->setErrorByName('make_package][rest', $msg); return; } parent::validateConfigurationForm($form, $form_state); } /** * {@inheritdoc} */ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { $package_uri = $form['#package_uri']; $view_id = $form_state->getValue('selected_view'); $display_id = $form_state->getValue('selected_display'); $views_ops = $this->buildViewExportOperations($package_uri, $view_id, $display_id); if (!$views_ops) { return []; } return $views_ops; } /** * Helper that assembles the operations necessary for a Views package. */ private function buildViewExportOperations($dest_uri, $view_id, $display_id) { $view = Views::getView($view_id); if (!$view) { $msg = $this->t('Invalid view configuration: could not find view @view_id.', ['@view_id' => $view_id]); $this->messenger()->addError($msg); return FALSE; } $view->setDisplay($display_id); $has_access = $view->access($display_id); if (!$has_access) { $msg = $this->t('Could not render view; access deined.'); $this->messenger()->addError($msg); return FALSE; } $display = $view->getDisplay(); $content_filename = $display instanceof RestExport ? "{$display_id}.{$display->getContentType()}" : "{$display_id}.data"; $data_uri = $dest_uri . DIRECTORY_SEPARATOR . $content_filename; $operations[] = [ 'Drupal\content_packager\BatchOperations::renderAndSaveViewOutput', [$view_id, $display_id, $data_uri], ]; $image_styles = array_keys($this->config('content_packager.settings')->get('image_styles')); $field_blacklist = $this->config('content_packager.settings')->get('fields_ignored'); $options = [ 'image_styles' => $image_styles, 'field_blacklist' => $field_blacklist, 'data_path' => $data_uri, ]; // This function does a lot, so we aren't using the existing $view. $view_rows = $has_access ? views_get_view_result($view_id, $display_id) : []; foreach ($view_rows as $row) { $infos = []; /* @var \Drupal\Core\Entity\Entity $entity */ $entity = $row->_entity; $access = $entity->access('view'); if (!$access) { continue; } $infos[] = ['id' => $entity->id(), 'type' => $entity->getEntityTypeId()]; $operations[] = [ 'Drupal\content_packager\BatchOperations::copyEntityFiles', [ $infos, $dest_uri, $options, ], ]; } return $operations; } }