This repository has been archived on 2025-01-19. You can view files and clone it, but cannot push or open issues or pull requests.
drupalcampbristol/web/modules/contrib/webform/drush/webform.drush.inc

574 lines
21 KiB
PHP
Raw Normal View History

2017-03-16 15:29:07 +00:00
<?php
/**
* @file
* Webform module drush commands.
*/
use Drupal\Core\Serialization\Yaml;
use Drupal\webform\Controller\WebformResultsExportController;
use Drupal\webform\Entity\Webform;
use Drupal\webform\Form\WebformResultsClearForm;
use Drupal\webform\Form\WebformSubmissionsPurgeForm;
use Drupal\webform\Utility\WebformYaml;
use Psr\Log\LogLevel;
/**
* Implements hook_drush_command().
*/
function webform_drush_command() {
$items = [];
/* Submissions */
$items['webform-export'] = [
'description' => 'Exports webform submissions to a file.',
'core' => ['8+'],
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_SITE,
'arguments' => [
'webform' => 'The webform ID you want to export (required unless --entity-type and --entity-id are specified)',
],
'options' => [
// Delimited export options.
'delimiter' => 'Delimiter between columns (defaults to site-wide setting). This option may need to be wrapped in quotes. i.e. --delimiter="\t".',
'multiple_delimiter' => 'Delimiter between an element with multiple values (defaults to site-wide setting).',
// Document and managed file export options.
'file-name' => 'File name used to export submission and uploaded filed. You may use tokens.',
// Tabular export options.
'header-keys' => 'Set to "label" (default) or "key"',
'options-item-format' => 'Set to "label" (default) or "key". Set to "key" to print select list values by their keys instead of labels.',
'options-format' => 'Set to "separate" (default) or "compact" to determine how select list values are exported.',
'entity-reference-format' => 'Set to "link" (default) or "id" to determine how entity references are exported.',
'excluded-columns' => 'Comma-separated list of component IDs or webform keys to exclude.',
// Download options.
'entity-type' => 'The entity type to which this submission was submitted from.',
'entity-id' => 'The ID of the entity of which this webform submission was submitted from.',
'range-type' => 'Range of submissions to export: "all", "latest", "serial", "sid", or "date".',
'range-latest' => 'Integer specifying the latest X submissions will be downloaded. Used if "range-type" is "latest" or no other range options are provided.',
'range-start' => 'The submission ID or start date at which to start exporting.',
'range-end' => 'The submission ID or end date at which to end exporting.',
'state' => 'Submission state to be included: "completed", "draft" or "all" (default).',
'sticky' => 'Flagged/starred submission status.',
'files' => 'Download files: "1" or "0" (default). If set to 1, the exported CSV file and any submission file uploads will be download in a gzipped tar file.',
// Output options.
'destination' => 'The full path and filename in which the CSV or archive should be stored. If omitted the CSV file or archive will be outputted to the commandline.',
],
'aliases' => ['wfx'],
];
$items['webform-purge'] = [
'description' => "Purge webform submissions from the databases",
'core' => ['8+'],
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_SITE,
'arguments' => [
'webform_id' => "A webform machine name. If not provided, user may choose from a list of names.",
],
'options' => [
'all' => 'Flush all submissions',
'entity-type' => 'The entity type for webform submissions to be purged',
'entity-id' => 'The ID of the entity for webform submissions to be purged',
],
'examples' => [
'drush webform-purge' => 'Pick a webform and then purge its submissions.',
'drush webform-purge contact' => "Delete 'Contact' webform submissions.",
'drush webform-purge --all' => 'Purge all webform submissions.',
],
'aliases' => ['wfp'],
];
/* Tidy */
$items['webform-tidy'] = [
'description' => "Tidy export webform configuration files",
'core' => ['8+'],
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT,
'options' => [
'dependencies' => 'Add module dependencies to installed webform and options configuration entities.',
],
'arguments' => [
'module' => "The module that needs its YAML configuration files (config/install) tidied. (Defaults to webform)",
],
'examples' => [
'drush webform-tidy webform' => "Tidies YAML configuration files in 'webform/config' for the Webform module",
],
'aliases' => ['wft'],
];
/* Libraries */
$items['webform-libraries-status'] = [
'description' => 'Displays the status of third party libraries required by the Webform module.',
'core' => ['8+'],
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT,
'examples' => [
'webform-libraries-status' => 'Displays the status of third party libraries required by the Webform module.',
],
'aliases' => ['wfls'],
];
$items['webform-libraries-download'] = [
'description' => 'Download third party libraries required by the Webform module.',
'core' => ['8+'],
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT,
'examples' => [
'webform-libraries-download' => 'Download third party libraries required by the Webform module.',
],
'aliases' => ['wfld'],
];
$items['webform-libraries-remove'] = [
'description' => 'Removes all downloaded third party libraries required by the Webform module.',
'core' => ['8+'],
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT,
'examples' => [
'webform-libraries-remove' => 'Removes all downloaded third party libraries required by the Webform module.',
],
'aliases' => ['wflr'],
];
/* Devel Generate */
$items['webform-generate'] = [
'callback' => 'drush_devel_generate',
'callback arguments' => [
'plugin_id' => 'webform_submission',
],
'description' => 'Create submissions in specified webform.',
'arguments' => [
'webform_id' => 'Webform id into which new submissions will be inserted.',
'num' => 'Number of submissions to insert. Defaults to 50.',
],
'options' => [
'kill' => 'Delete all submissions in specified webform before generating.',
'feedback' => 'An integer representing interval for insertion rate logging. Defaults to 1000',
'entity-type' => 'The entity type to which this submission was submitted from.',
'entity-id' => 'The ID of the entity of which this webform submission was submitted from.',
],
'aliases' => ['wfg'],
];
/* Repair */
$items['webform-repair'] = [
'description' => 'Makes sure all Webform admin settings and webforms are up-to-date.',
'core' => ['8+'],
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT,
'examples' => [
'webform-repair' => 'Repairs admin settings and webforms are up-to-date.',
],
'aliases' => ['wfr'],
];
return $items;
}
/**
* Implements hook_drush_help().
*/
function webform_drush_help($section) {
switch ($section) {
case 'drush:webform-export':
return dt('This command will export webform submissions to a file.');
case 'drush:webform-purge':
return dt('This command will purge webform submissions.');
case 'drush:webform-libraries-status':
return dt('This command displays the status of third party libraries required by the Webform module.');
case 'drush:webform-libraries-download':
return dt('This command downloads third party libraries required by the Webform module.');
case 'drush:webform-libraries-remove':
return dt('This command removes all downloaded third party libraries required by the Webform module.');
case 'drush:webform-repair':
return dt('Makes sure all Webform admin settings and webforms are up-to-date. Only use this command if you are having problems with your existing Webform configuration.');
case 'drush:webform-tidy':
return dt('This command tidies exported YAML configuration files.') . "\n\n" .
dt('Changes include...') . PHP_EOL .
dt('- Preserving newlines using pipe (|).') . PHP_EOL .
dt('- Removing returns after array dashes (-).');
case 'drush:webform-generate':
return dt('This command will create submissions in specified webform.');
case 'meta:webform:title':
return dt('Webform commands');
case 'meta:webform:summary':
return dt('Enables the creation of webforms and questionnaires.');
}
}
/******************************************************************************/
// Export
/******************************************************************************/
/**
* Implements drush_hook_COMMAND_validate().
*/
function drush_webform_export_validate($webform_id = NULL) {
return _drush_webform_validate($webform_id);
}
/**
* Implements drush_hook_COMMAND().
*/
function drush_webform_export($webform_id = NULL) {
if (!$webform_id) {
$webforms = array_keys(Webform::loadMultiple());
$choices = array_combine($webforms, $webforms);
$webform_id = drush_choice($choices, dt("Choose a webform to export submissions from."));
if ($webform_id === FALSE) {
return drush_user_abort();
}
}
$webform = Webform::load($webform_id);
// @todd Determine if we should get source entity from options entity type
// and id.
$source_entity = NULL;
/** @var \Drupal\webform\WebformSubmissionExporterInterface $submission_exporter */
$submission_exporter = \Drupal::service('webform_submission.exporter');
$submission_exporter->setWebform($webform);
$submission_exporter->setSourceEntity($source_entity);
// Get command options as export options.
$export_options = drush_redispatch_get_options();
// Convert dashes to underscores.
foreach ($export_options as $key => $value) {
unset($export_options[$key]);
$export_options[str_replace('-', '_', $key)] = $value;
}
$export_options += $submission_exporter->getDefaultExportOptions();
$submission_exporter->setExporter($export_options);
WebformResultsExportController::batchSet($webform, $source_entity, $export_options);
drush_backend_batch_process();
$file_path = ($submission_exporter->isArchive()) ? $submission_exporter->getArchiveFilePath() : $submission_exporter->getExportFilePath();
if (isset($export_options['destination'])) {
drush_print(dt('Created @destination', ['@destination' => $export_options['destination']]));
file_unmanaged_copy($file_path, $export_options['destination'], FILE_EXISTS_REPLACE);
}
else {
drush_print(file_get_contents($file_path));
}
@unlink($file_path);
return NULL;
}
/******************************************************************************/
// Purge
/******************************************************************************/
/**
* Implements drush_hook_COMMAND_validate().
*/
function drush_webform_purge_validate($webform_id = NULL) {
// If webform id is set to 'all' or not included skip validation.
if (drush_get_option('all') || $webform_id == NULL) {
return;
}
return _drush_webform_validate($webform_id);
}
/**
* Implements drush_hook_COMMAND().
*/
function drush_webform_purge($webform_id = NULL) {
if (drush_get_option('all')) {
$webform_id = 'all';
}
if (!$webform_id) {
$webforms = array_keys(Webform::loadMultiple());
$choices = array_combine($webforms, $webforms);
$choices = array_merge(['all' => 'all'], $choices);
$webform_id = drush_choice($choices, dt("Choose a webform to purge submissions from."));
if ($webform_id === FALSE) {
return drush_user_abort();
}
}
// Set the webform.
$webform = ($webform_id == 'all') ? NULL : Webform::load($webform_id);
/** @var \Drupal\webform\WebformSubmissionStorageInterface $submission_storage */
$submission_storage = \Drupal::entityTypeManager()->getStorage('webform_submission');
/** @var \Drupal\webform\WebformRequestInterface $request_handler */
$request_handler = \Drupal::service('webform.request');
// Make sure there are submissions that need to be deleted.
if (!$submission_storage->getTotal($webform)) {
return drush_set_error(dt('There are no submissions that need to be deleted.'));
}
if (!$webform) {
$submission_total = \Drupal::entityQuery('webform_submission')->count()->execute();
$form_total = \Drupal::entityQuery('webform')->count()->execute();
$t_args = [
'@submission_total' => $submission_total,
'@submissions' => \Drupal::translation()->formatPlural($submission_total, t('submission'), t('submissions')),
'@form_total' => $form_total,
'@forms' => \Drupal::translation()->formatPlural($form_total, t('webform'), t('webforms')),
];
if (!drush_confirm(dt('Are you sure you want to delete @submission_total @submissions in @form_total @forms?', $t_args))) {
return drush_user_abort();
}
$form = new WebformResultsClearForm($submission_storage, $request_handler);
$form->batchSet();
drush_backend_batch_process();
}
else {
// Set source entity.
$entity_type = drush_get_option('entity-type');
$entity_id = drush_get_option('entity-id');
$source_entity = ($entity_type && $entity_id) ? \Drupal::entityTypeManager()->getStorage($entity_type)->load($entity_id) : NULL;
$t_args = [
'@title' => ($source_entity) ? $source_entity->label() : $webform->label(),
];
if (!drush_confirm(dt("Are you sure you want to delete all submissions from '@title' webform?", $t_args))) {
return drush_user_abort();
}
$form = new WebformSubmissionsPurgeForm($submission_storage, $request_handler);
$form->batchSet($webform, $source_entity);
drush_backend_batch_process();
}
}
/******************************************************************************/
// Tidy
/******************************************************************************/
/**
* Implements drush_hook_COMMAND_validate().
*/
function drush_webform_tidy_validate($module = 'webform') {
if (!file_exists(drupal_get_path('module', $module) . '/config')) {
$t_args = [
'@module' => $module,
'@directory' => drupal_get_path('module', $module) . '/config',
];
return drush_set_error(dt("@module does not contain a '@module/config' directory (@directory).", $t_args));
}
}
/**
* Implements drush_hook_COMMAND().
*/
function drush_webform_tidy($module = 'webform') {
$dependencies = drush_get_option('dependencies');
$file_directory_path = drupal_get_path('module', $module) . '/config';
$files = file_scan_directory($file_directory_path, '/.*\.yml$/');
drush_print(dt('Reviewing @count YAML configuration files for the @module.module.', ['@count' => count($files), '@module' => $module]));
$total = 0;
foreach ($files as $file) {
$original_yaml = file_get_contents($file->uri);
$tidied_yaml = $original_yaml;
// Add module dependency to exporter webform and webform options config entities.
if ($dependencies && preg_match('/^(webform\.webform\.|webform\.webform_options\.)/', $file->filename)) {
try {
$data = Yaml::decode($tidied_yaml);
if (empty($data['dependencies']['enforced']['module']) || !in_array($module, $data['dependencies']['enforced']['module'])) {
drush_print(dt('Adding module dependency to @file...', ['@file' => $file->filename]));
$data['dependencies']['enforced']['module'][] = $module;
$tidied_yaml = Yaml::encode($data);
}
}
catch (\Exception $exception) {
$message = 'Error parsing: ' . $file->filename . PHP_EOL . $exception->getMessage();
if (strlen($message) > 255) {
$message = substr($message, 0, 255) . '...';
}
drush_log($message, LogLevel::ERROR);
drush_print($message);
}
}
// Tidy and add new line to the end of the tidied file.
$tidied_yaml = WebformYaml::tidy($tidied_yaml) . PHP_EOL;
if ($tidied_yaml != $original_yaml) {
drush_print(dt('Tidying @file...', ['@file' => $file->filename]));
file_put_contents($file->uri, $tidied_yaml);
$total++;
}
}
if ($total) {
drush_print(dt('@total YAML file(s) tidied.', ['@total' => $total]));
}
else {
drush_print(dt('No YAML files needed to be tidied.'));
}
}
/******************************************************************************/
// Devel Generate.
/******************************************************************************/
/**
* Implements drush_hook_COMMAND_validate().
*/
function drush_webform_generate_validate() {
// Array of "Callback arguments" and "command line args".
$params = func_get_args();
$params[0] = 'webform_submission';
_drush_plugin_validate($params);
}
/******************************************************************************/
// Libraries
/******************************************************************************/
/**
* Implements drush_hook_COMMAND().
*/
function drush_webform_libraries_status() {
module_load_include('install', 'webform');
/** @var \Drupal\webform\WebformLibrariesManagerInterface $libraries_manager */
$libraries_manager = \Drupal::service('webform.libraries_manager');
$requirements = $libraries_manager->requirements();
foreach ($requirements as $requirement) {
$library = $requirement['library'];
drush_print($library['title'] . ' (' . $library['name'] . ') ' . $requirement['value']);
// drush_print();
drush_print(strip_tags($requirement['description']));
drush_print();
}
}
/**
* Implements drush_hook_COMMAND().
*/
function drush_webform_libraries_remove($status = TRUE) {
if ($status) {
drush_print(dt('Beginning to remove libraries...'));
}
$removed = FALSE;
/** @var \Drupal\webform\WebformLibrariesManagerInterface $libraries_manager */
$libraries_manager = \Drupal::service('webform.libraries_manager');
$libraries = $libraries_manager->getLibraries();
foreach ($libraries as $library_name => $library) {
$library_path = '/' . $library['destination'] . '/' . $library['directory_name'];
$library_exists = (file_exists(DRUPAL_ROOT . $library_path)) ? TRUE : FALSE;
if ($library_exists) {
$t_args = [
'@name' => $library_name,
'@path' => $library_path,
];
if ($status) {
drush_print(dt('@name removed from @path...', $t_args));
drush_delete_dir(DRUPAL_ROOT . $library_path, TRUE);
}
$removed = TRUE;
}
}
if ($status) {
drupal_flush_all_caches();
}
return $removed;
}
/**
* Implements drush_hook_COMMAND().
*/
function drush_webform_libraries_download() {
// Remove all existing libraries.
if (drush_webform_libraries_remove(FALSE)) {
drush_print(dt('Removing existing libraries...'));
}
// Download libraries using drush.
$commandline_args = [
DRUPAL_ROOT . '/' . drupal_get_path('module', 'webform') . '/webform.libraries.make.yml',
DRUPAL_ROOT,
];
$commandline_options = ['no-core' => 'no-core'];
drush_invoke_process('@self', 'make', $commandline_args, $commandline_options);
drupal_flush_all_caches();
}
/******************************************************************************/
// Repair.
/******************************************************************************/
/**
* Implements drush_hook_COMMAND().
*/
function drush_webform_repair() {
if (!drush_confirm(dt("Are you sure you want repair the Webform module's admin settings and webforms?"))) {
return drush_user_abort();
}
module_load_include('install', 'webform');
drush_print('Repairing admin settings...');
_webform_update_admin_settings();
drush_print('Repairing webform settings...');
_webform_update_form_settings();
}
/******************************************************************************/
// Helper functions.
/******************************************************************************/
/**
* Validate webform_id argument and source entity-type and entity-id options.
*/
function _drush_webform_validate($webform_id = NULL) {
if (empty($webform_id)) {
return drush_set_error(dt('Webform id required'));
}
if (!empty($webform_id) && !Webform::load($webform_id)) {
return drush_set_error(dt('Webform @id not recognized.', ['@id' => $webform_id]));
}
$entity_type = drush_get_option('entity-type');
$entity_id = drush_get_option('entity-id');
if ($entity_type || $entity_id) {
if (empty($entity_type)) {
return drush_set_error(dt('Entity type is required when entity id is specified.'));
}
if (empty($entity_id)) {
return drush_set_error(dt('Entity id is required when entity type is specified.'));
}
$dt_args = [
'@webform_id' => $webform_id,
'@entity_type' => $entity_type,
'@entity_id' => $entity_id,
];
$source_entity = \Drupal::entityTypeManager()->getStorage($entity_type)->load($entity_id);
if (!$source_entity) {
return drush_set_error(dt('Unable to load @entity_type:@entity_id', $dt_args));
}
$dt_args['@title'] = $source_entity->label();
if (empty($source_entity->webform) || empty($source_entity->webform->target_id)) {
return drush_set_error(dt("'@title' (@entity_type:@entity_id) does not reference a webform.", $dt_args));
}
if ($source_entity->webform->target_id != $webform_id) {
return drush_set_error(dt("'@title' (@entity_type:@entity_id) does not have a '@webform_id' webform associated with it.", $dt_args));
}
}
return NULL;
}