content_packager-8.x-1.x-dev/src/Form/CreatePackage.php
src/Form/CreatePackage.php
<?php
namespace Drupal\content_packager\Form;
use Drupal\Component\Plugin\Exception\PluginException;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\content_packager\Plugin\SourcePluginManager;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\File\FileSystem;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides the content package generation form.
*
* @package Drupal\content_packager\Form
*/
class CreatePackage extends FormBase {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
private $entityTypeManager;
/**
* The file system service.
*
* @var \Drupal\Core\File\FileSystemInterface
*/
private $fileSystem;
/**
* The source plugin manager.
*
* @var \Drupal\content_packager\Plugin\SourcePluginManager
*/
protected $pluginManager;
/**
* The source plugin definitions.
*
* @var array
*/
protected $sourceTypes = [];
/**
* Constructs a \Drupal\content_packager\Form\CreatePackage object.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The factory for configuration objects.
* @param \Drupal\content_packager\Plugin\SourcePluginManager $plugin_manager
* The Content Packager source plugin manager.
* @param \Drupal\Core\Entity\EntityTypeManager $typeManager
* The Entity Type manager.
* @param \Drupal\Core\File\FileSystem $fileSystem
* The file system helpers.
*/
public function __construct(ConfigFactoryInterface $config_factory, SourcePluginManager $plugin_manager, EntityTypeManager $typeManager, FileSystem $fileSystem) {
$this->setConfigFactory($config_factory);
$this->pluginManager = $plugin_manager;
$this->entityTypeManager = $typeManager;
$this->fileSystem = $fileSystem;
foreach ($this->pluginManager->getDefinitions() as $id => $definition) {
$this->sourceTypes[$id] = $this->t('@title', ['@title' => $definition['title']])->render();
}
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('config.factory'),
$container->get('plugin.manager.content_packager.source'),
$container->get('entity_type.manager'),
$container->get('file_system')
);
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'content_packager_create_package';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form = [];
$config = $this->config('content_packager.settings');
$package_uri = content_packager_package_uri();
$form['#package_uri'] = $package_uri;
$zip_name = $config->get('zip_name');
$this->buildExistingPackageInfo($package_uri, $zip_name, $form);
$form['make_package'] = [
'#type' => 'details',
'#title' => $this->t('Make a content package'),
'#open' => empty($form['existing_file']),
];
$export_source_options = $this->sourceTypes;
$source_keys = array_keys($export_source_options);
$selected_source = $form_state->getValue('export_source', reset($source_keys));
$form['make_package']['export_source'] = [
'#type' => 'select',
'#title' => 'Source of Export',
'#options' => $export_source_options,
'#default_value' => $selected_source,
'#ajax' => [
'callback' => [$this, 'sourceSelectChanged'],
'event' => 'change',
'wrapper' => 'source-wrapper',
],
];
$form['make_package']['source_ajax'] = [
'#type' => 'container',
'#attributes' => [
'id' => ['source-wrapper'],
],
];
$plugins = $this->pluginManager->getDefinitions();
$selected_plugin = $plugins[$selected_source];
if (isset($selected_plugin['forms']) && isset($selected_plugin['forms']['package'])) {
$id = $selected_plugin['id'];
try {
$pluginInstance = $this->pluginManager->createInstance($id);
$form['make_package']['source_ajax'][$id] = $pluginInstance->getPackageForm([], $form_state);
}
catch (PluginException $e) {
$this->getLogger('content_packager')
->warning('Content Packager Plugin error: Failed to instantiate @plugin_id package form.', ['@plugin_id' => $id]);
}
}
$form['make_package']['destination'] = [
'#markup' => "<p>Package destination: $package_uri</p>",
];
$form['actions']['#type'] = 'actions';
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Copy Files'),
'#button_type' => 'primary',
];
$form['actions']['zip'] = [
'#type' => 'submit',
'#value' => $this->t('Zip Package'),
'#submit' => ['::zip'],
];
return $form;
}
/**
* Ajax callback.
*/
public function sourceSelectChanged(array $form, FormStateInterface $form_state) {
return $form['make_package']['source_ajax'];
}
/**
* Builds notice if a package is already present.
*/
private function buildExistingPackageInfo($package_uri, $zip_name, &$form) {
$full_package_uri = $package_uri . DIRECTORY_SEPARATOR . $zip_name;
if (!file_exists($full_package_uri)) {
return;
}
$url = file_create_url($full_package_uri);
$form['existing_file'] = [
'#type' => 'details',
'#title' => $this->t('Current Package'),
'#prefix' => $this->t('A package already exists and <a href=":package_link">can be downloaded</a> at any time.',
[':package_link' => $url]),
'#open' => TRUE,
];
$form['existing_file']['file'] = [
'#type' => 'item',
'#title' => 'File',
'#markup' => $this->t('<a href=":package_uri">%display_uri</a>',
[
':package_uri' => $url,
'%display_uri' => $full_package_uri,
]),
];
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
$source = $form_state->getValue('export_source');
try {
$pluginDef = $this->pluginManager->getDefinition($source);
if (isset($pluginDef['forms']) && isset($pluginDef['forms']['package'])) {
$pluginInstance = $this->pluginManager->createInstance($pluginDef['id']);
$pluginInstance->validatePackageForm($form, $form_state);
}
}
catch (PluginNotFoundException $e) {
$form_state->setErrorByName('make_package', $this->t('Failed to find plugin for @source during package creation.', ['@source' => $source]));
}
catch (PluginException $e) {
$form_state->setErrorByName('make_package', $this->t('Failed to instantiate plugin for @source during package creation.', ['@source' => $source]));
}
parent::validateForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$logger = $this->getLogger('content_packager');
// Make sure our directory is actually there!
$package_uri = content_packager_package_uri();
if (!file_exists($package_uri)) {
$errors = content_packager_prepare_directory($package_uri);
if (!file_exists($package_uri) || $errors) {
$msg = $this->t('Directory for packaging is incorrectly configured or cannot be found.');
$this->messenger()->addError($msg);
return;
}
}
content_packager_clear_processed();
$operations[] = [
'Drupal\content_packager\BatchOperations::prepareDestination',
[$package_uri],
];
$source = $form_state->getValue('export_source');
try {
$pluginDef = $this->pluginManager->getDefinition($source);
if (isset($pluginDef['forms']) && isset($pluginDef['forms']['package'])) {
$pluginInstance = $this->pluginManager->createInstance($pluginDef['id']);
$plugin_ops = $pluginInstance->submitPackageForm($form, $form_state);
$operations = array_merge($operations, $plugin_ops);
}
}
catch (PluginNotFoundException $e) {
$logger->warning('Failed to find plugin for @source during package creation.', ['@source' => $source]);
}
catch (PluginException $e) {
$logger->warning('Failed to instantiate plugin for @source during package creation.', ['@source' => $source]);
}
$batch = [
'operations' => $operations,
'finished' => 'Drupal\content_packager\BatchOperations::packingFinished',
];
batch_set($batch);
}
/**
* Form submission handler for the 'zip package' action.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*/
public function zip(array &$form, FormStateInterface $form_state) {
// Make sure our directory is actually there!
$package_dir_uri = content_packager_package_uri();
$zip_name = $this->config('content_packager.settings')->get('zip_name');
$zip_path = $this->fileSystem->realpath($package_dir_uri . DIRECTORY_SEPARATOR . $zip_name);
$this->fileSystem->delete($zip_path);
$operations = [];
$add_to_batch = function ($uri) use ($zip_path, &$operations) {
$zip_pathinfo = pathinfo($zip_path);
$file_path = $this->fileSystem->realpath($uri);
$file_pathinfo = pathinfo($file_path);
$operations[] = [
'Drupal\content_packager\BatchOperations::zipFile',
[
$zip_pathinfo['basename'],
$zip_pathinfo['dirname'],
$file_pathinfo['basename'],
$file_pathinfo['dirname'],
],
];
};
$this->fileSystem->scanDirectory($package_dir_uri, '/.*/', [
'callback' => $add_to_batch,
]);
$batch = [
'operations' => $operations,
'finished' => 'Drupal\content_packager\BatchOperations::packingFinished',
];
batch_set($batch);
}
}
