class YamlFormSubmissionDevelGenerate in YAML Form 8
Provides a YamlFormSubmissionDevelGenerate plugin.
Plugin annotation
@DevelGenerate(
id = "yamlform_submission",
label = @Translation("Form submissions"),
description = @Translation("Generate a given number of form submissions. Optionally delete current submissions."),
url = "yamlform",
permission = "administer yamlform",
settings = {
"num" = 50,
"kill" = FALSE,
"entity-type" = NULL,
"entity-id" = NULL,
}
)
Hierarchy
- class \Drupal\yamlform\Plugin\DevelGenerate\YamlFormSubmissionDevelGenerate extends \Drupal\devel_generate\DevelGenerateBase implements ContainerFactoryPluginInterface
Expanded class hierarchy of YamlFormSubmissionDevelGenerate
File
- src/
Plugin/ DevelGenerate/ YamlFormSubmissionDevelGenerate.php, line 31
Namespace
Drupal\yamlform\Plugin\DevelGenerateView source
class YamlFormSubmissionDevelGenerate extends DevelGenerateBase implements ContainerFactoryPluginInterface {
/**
* Track in form submission are being generated.
*
* @var bool
*/
protected static $generatingSubmissions = FALSE;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The form storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $yamlformStorage;
/**
* The form submission storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $yamlformSubmissionStorage;
/**
* Form submission generation service.
*
* @var \Drupal\yamlform\YamlFormSubmissionGenerateInterface
*/
protected $yamlformSubmissionGenerate;
/**
* Constructs a new YamlFormSubmissionDevelGenerate object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\yamlform\YamlFormSubmissionGenerateInterface $yamlform_submission_generate
* The form submission generator.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, YamlFormSubmissionGenerateInterface $yamlform_submission_generate) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->entityTypeManager = $entity_type_manager;
$this->yamlformSubmissionGenerate = $yamlform_submission_generate;
$this->yamlformStorage = $entity_type_manager
->getStorage('yamlform');
$this->yamlformSubmissionStorage = $entity_type_manager
->getStorage('yamlform_submission');
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('entity_type.manager'), $container
->get('yamlform_submission.generate'));
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
drupal_set_message($this
->t('Please note that no emails will be sent while generating form submissions.'), 'warning');
$options = [];
foreach ($this->yamlformStorage
->loadMultiple() as $yamlform) {
$options[$yamlform
->id()] = $yamlform
->label();
}
$form['yamlform_ids'] = [
'#type' => 'checkboxes',
'#title' => $this
->t('Form'),
'#description' => $this
->t('Restrict submissions to these forms.'),
'#required' => TRUE,
'#options' => $options,
];
$form['num'] = [
'#type' => 'number',
'#title' => $this
->t('Number of submissions?'),
'#min' => 1,
'#required' => TRUE,
'#default_value' => $this
->getSetting('num'),
];
$form['kill'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Delete existing submissions in specified form before generating new submissions.'),
'#default_value' => $this
->getSetting('kill'),
];
$entity_types = \Drupal::service('entity_type.repository')
->getEntityTypeLabels(TRUE);
$form['submitted'] = [
'#type' => 'item',
'#title' => $this
->t('Submitted to'),
'#field_prefix' => '<div class="container-inline">',
'#field_suffix' => '</div>',
];
$form['submitted']['entity-type'] = [
'#type' => 'select',
'#title' => $this
->t('Entity type'),
'#title_display' => 'Invisible',
'#options' => [
'' => '',
] + $entity_types,
'#default_value' => $this
->getSetting('entity-type'),
];
$form['submitted']['entity-id'] = [
'#type' => 'number',
'#title' => $this
->t('Entity id'),
'#title_display' => 'Invisible',
'#default_value' => $this
->getSetting('entity-id'),
'#min' => 1,
'#size' => 10,
'#states' => [
'invisible' => [
':input[name="entity-type"]' => [
'value' => '',
],
],
],
];
$form['#validate'] = [
[
$this,
'validateForm',
],
];
return $form;
}
/**
* Custom validation handler.
*/
public function validateForm(array $form, FormStateInterface $form_state) {
$yamlform_ids = array_filter($form_state
->getValue('yamlform_ids'));
// Let default form validation handle requiring form ids.
if (empty($yamlform_ids)) {
return;
}
$entity_type = $form_state
->getValue('entity-type');
$entity_id = $form_state
->getValue('entity-id');
if ($entity_type || $entity_id) {
if ($error = $this
->validateEntity($yamlform_ids, $entity_type, $entity_id)) {
$form_state
->setErrorByName('entity_type', $error);
}
}
}
/**
* {@inheritdoc}
*/
public function generateElements(array $values) {
$this
->generateSubmissions($values);
}
/**
* Generates submissions for a list of given forms.
*
* @param array $values
* The element values from the settings form.
*/
protected function generateSubmissions(array $values) {
self::$generatingSubmissions = TRUE;
if ($values['kill']) {
$this
->deleteYamlFormSubmissions($values['yamlform_ids'], $values['entity-type'], $values['entity-id']);
$this
->setMessage($this
->t('Deleted existing submissions.'));
}
if (!empty($values['yamlform_ids'])) {
$this
->initializeGenerate($values);
$start = time();
for ($i = 1; $i <= $values['num']; $i++) {
$this
->generateSubmission($values);
if (function_exists('drush_log') && $i % drush_get_option('feedback', 1000) == 0) {
$now = time();
drush_log(dt('Completed @feedback submissions (@rate submissions/min)', [
'@feedback' => drush_get_option('feedback', 1000),
'@rate' => drush_get_option('feedback', 1000) * 60 / ($now - $start),
]), 'ok');
$start = $now;
}
}
}
$this
->setMessage($this
->formatPlural($values['num'], '1 submissions created.', 'Finished creating @count submissions'));
self::$generatingSubmissions = FALSE;
}
/**
* Deletes all submissions of given forms.
*
* @param array $yamlform_ids
* Array of form ids.
* @param string|null $entity_type
* A form source entity type.
* @param int|null $entity_id
* A form source entity id.
*/
protected function deleteYamlFormSubmissions(array $yamlform_ids, $entity_type = NULL, $entity_id = NULL) {
$yamlforms = $this->yamlformStorage
->loadMultiple($yamlform_ids);
$entity = $entity_type && $entity_id ? $this->entityTypeManager
->getStorage($entity_type)
->load($entity_id) : NULL;
foreach ($yamlforms as $yamlform) {
$this->yamlformSubmissionStorage
->deleteAll($yamlform, $entity);
}
}
/**
* Add 'users' that contains a list of uids.
*
* @param array $values
* The element values from the settings form.
*/
protected function initializeGenerate(array &$values) {
// Set user id.
$users = $this
->getUsers();
$users = array_merge($users, [
'0',
]);
$values['users'] = $users;
// Set created min and max.
$values['created_min'] = strtotime('-1 month');
$values['created_max'] = time();
}
/**
* Create one node. Used by both batch and non-batch code branches.
*/
protected function generateSubmission(&$results) {
$yamlform_id = array_rand(array_filter($results['yamlform_ids']));
/** @var \Drupal\yamlform\YamlFormInterface $yamlform */
$yamlform = $this->yamlformStorage
->load($yamlform_id);
$users = $results['users'];
$uid = $users[array_rand($users)];
$entity_type = $results['entity-type'] ?: '';
$entity_id = $results['entity-id'] ?: '';
$timestamp = rand($results['created_min'], $results['created_max']);
$this->yamlformSubmissionStorage
->create([
'yamlform_id' => $yamlform_id,
'entity_type' => $entity_type,
'entity_id' => $entity_id,
'uid' => $uid,
'remote_addr' => mt_rand(0, 255) . '.' . mt_rand(0, 255) . '.' . mt_rand(0, 255) . '.' . mt_rand(0, 255),
'uri' => preg_replace('#^' . base_path() . '#', '/', $yamlform
->toUrl()
->toString()),
'data' => Yaml::encode($this->yamlformSubmissionGenerate
->getData($yamlform)),
'created' => $timestamp,
'changed' => $timestamp,
])
->save();
}
/**
* {@inheritdoc}
*/
public function validateDrushParams($args) {
$yamlform_id = array_shift($args);
$yamlform_ids = [
$yamlform_id => $yamlform_id,
];
$values = [
'yamlform_ids' => $yamlform_ids,
'num' => array_shift($args) ?: 50,
'kill' => drush_get_option('kill') ?: FALSE,
];
if (empty($yamlform_id)) {
return drush_set_error('DEVEL_GENERATE_INVALID_INPUT', dt('Form id required'));
}
if (!$this->yamlformStorage
->load($yamlform_id)) {
return drush_set_error('DEVEL_GENERATE_INVALID_INPUT', dt('Invalid form name: @name', [
'@name' => $yamlform_id,
]));
}
if ($this
->isNumber($values['num']) == FALSE) {
return drush_set_error('DEVEL_GENERATE_INVALID_INPUT', dt('Invalid number of submissions: @num', [
'@num' => $values['num'],
]));
}
$entity_type = drush_get_option('entity-type');
$entity_id = drush_get_option('entity-id');
if ($entity_type || $entity_id) {
if ($error = $this
->validateEntity($yamlform_ids, $entity_type, $entity_id)) {
return drush_set_error('DEVEL_GENERATE_INVALID_INPUT', $error);
}
else {
$values['entity-type'] = $entity_type;
$values['entity-id'] = $entity_id;
}
}
return $values;
}
/**
* Retrieve 50 uids from the database.
*
* @return array
* An array of uids.
*/
protected function getUsers() {
$users = [];
$result = db_query_range("SELECT uid FROM {users}", 0, 50);
foreach ($result as $record) {
$users[] = $record->uid;
}
return $users;
}
/**
* Track if form submissions are being generated.
*
* Used to block emails from being sent while using devel generate.
*
* @return bool
* TRUE if form submissions are being generated.
*/
public static function isGeneratingSubmissions() {
return self::$generatingSubmissions;
}
/**
* Validate form source entity type and id.
*
* @param array $yamlform_ids
* An array form ids.
* @param string $entity_type
* An entity type.
* @param int $entity_id
* An entity id.
*
* @return string
* An error message or NULL if there are no validation errors.
*/
protected function validateEntity(array $yamlform_ids, $entity_type, $entity_id) {
$t = function_exists('dt') ? 'dt' : 't';
if (!$entity_type) {
return $t('Entity type is required');
}
if (!$entity_id) {
return $t('Entity id is required');
}
$dt_args = [
'@entity_type' => $entity_type,
'@entity_id' => $entity_id,
];
$source_entity = $this->entityTypeManager
->getStorage($entity_type)
->load($entity_id);
if (!$source_entity) {
return $t('Unable to load @entity_type:@entity_id', $dt_args);
}
$dt_args['@title'] = $source_entity
->label();
if (!method_exists($source_entity, 'hasField') || !$source_entity
->hasField('yamlform')) {
return $t("'@title' (@entity_type:@entity_id) does not have a 'yamlform' field.", $dt_args);
}
if (count($yamlform_ids) > 1) {
return $t("'@title' (@entity_type:@entity_id) can only be associated with a single form.", $dt_args);
}
$dt_args['@yamlform_ids'] = YamlFormArrayHelper::toString($yamlform_ids, $t('or'));
if (!in_array($source_entity->yamlform->target_id, $yamlform_ids)) {
return $t("'@title' (@entity_type:@entity_id) does not have a '@yamlform_ids' yamlform associated with it.", $dt_args);
}
return NULL;
}
}