trait WebformSubmissionDevelGenerateTrait in Webform 8.5
Same name and namespace in other branches
- 6.x src/Plugin/DevelGenerate/WebformSubmissionDevelGenerateTrait.php \Drupal\webform\Plugin\DevelGenerate\WebformSubmissionDevelGenerateTrait
Provides a WebformSubmissionDevelGenerate trait.
Hierarchy
- trait \Drupal\webform\Plugin\DevelGenerate\WebformSubmissionDevelGenerateTrait
See also
webform_devel_generate_info_alter()
File
- src/
Plugin/ DevelGenerate/ WebformSubmissionDevelGenerateTrait.php, line 22
Namespace
Drupal\webform\Plugin\DevelGenerateView source
trait WebformSubmissionDevelGenerateTrait {
/**
* Track in webform submission are being generated.
*
* @var bool
*/
protected static $generatingSubmissions = FALSE;
/**
* The current request.
*
* @var null|\Symfony\Component\HttpFoundation\Request
*/
protected $request;
/**
* The database object.
*
* @var object
*/
protected $database;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The webform storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $webformStorage;
/**
* The webform submission storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $webformSubmissionStorage;
/**
* The webform submission generation service.
*
* @var \Drupal\webform\WebformSubmissionGenerateInterface
*/
protected $webformSubmissionGenerate;
/**
* The webform entity reference manager.
*
* @var \Drupal\webform\WebformEntityReferenceManagerInterface
*/
protected $webformEntityReferenceManager;
/**
* The messenger.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected $messenger;
/**
* The time service.
*
* @var \Drupal\Component\Datetime\TimeInterface
*/
protected $time;
/**
* Constructs a WebformSubmissionDevelGenerate 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 \Symfony\Component\HttpFoundation\RequestStack $request_stack
* The request stack.
* @param \Drupal\Core\Database\Connection $database
* The database.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
* The messenger.
* @param \Drupal\webform\WebformSubmissionGenerateInterface $webform_submission_generate
* The webform submission generator.
* @param \Drupal\webform\WebformEntityReferenceManagerInterface $webform_entity_reference_manager
* The webform entity reference manager.
* @param \Drupal\Component\Datetime\TimeInterface $time
* The time service.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, RequestStack $request_stack, Connection $database, EntityTypeManagerInterface $entity_type_manager, MessengerInterface $messenger, WebformSubmissionGenerateInterface $webform_submission_generate, WebformEntityReferenceManagerInterface $webform_entity_reference_manager, TimeInterface $time) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->request = $request_stack
->getCurrentRequest();
$this->database = $database;
$this->entityTypeManager = $entity_type_manager;
$this->messenger = $messenger;
$this->webformSubmissionGenerate = $webform_submission_generate;
$this->webformEntityReferenceManager = $webform_entity_reference_manager;
$this->webformStorage = $entity_type_manager
->getStorage('webform');
$this->webformSubmissionStorage = $entity_type_manager
->getStorage('webform_submission');
$this->time = $time;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('request_stack'), $container
->get('database'), $container
->get('entity_type.manager'), $container
->get('messenger'), $container
->get('webform_submission.generate'), $container
->get('webform.entity_reference_manager'), $container
->get('datetime.time'));
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$form['message'] = [
'#type' => 'webform_message',
'#message_message' => $this
->t('Please note that no emails will be sent while generating webform submissions.'),
'#message_type' => 'warning',
];
$options = [];
foreach ($this->webformStorage
->loadMultiple() as $webform) {
$options[$webform
->id()] = $webform
->label();
}
$webform_id = $this->request
->get('webform_id');
$source_entity_type = $this->request
->get('entity_type');
$source_entity_id = $this->request
->get('entity_id');
$source_entity = $source_entity_type && $source_entity_id ? \Drupal::entityTypeManager()
->getStorage($source_entity_type)
->load($source_entity_id) : NULL;
if ($webform_id && isset($options[$webform_id])) {
$form['webform_ids'] = [
'#type' => 'value',
'#value' => [
$webform_id => $webform_id,
],
];
$form['webform'] = [
'#type' => 'item',
'#title' => $this
->t('Webform'),
'#markup' => $options[$webform_id],
];
}
else {
$form['webform_ids'] = [
'#type' => 'checkboxes',
'#title' => $this
->t('Webform'),
'#description' => $this
->t('Restrict submissions to these webforms.'),
'#required' => TRUE,
'#options' => $options,
];
}
if ($source_entity) {
$form['submitted'] = [
'#type' => 'item',
'#title' => $this
->t('Submitted to'),
'#markup' => $source_entity
->toLink()
->toString(),
];
$form['entity-type'] = [
'#type' => 'value',
'#value' => $source_entity_type,
];
$form['entity-id'] = [
'#type' => 'value',
'#value' => $source_entity_id,
];
}
elseif ($webform_id && isset($options[$webform_id])) {
$form['entity-type'] = [
'#type' => 'value',
'#value' => '',
];
$form['entity-id'] = [
'#type' => 'value',
'#value' => '',
];
}
else {
$entity_types = \Drupal::service('entity_type.repository')
->getEntityTypeLabels(TRUE);
$form['submitted'] = [
'#type' => 'item',
'#title' => $this
->t('Submitted to'),
];
$form['submitted']['container'] = [
'#prefix' => '<div class="container-inline">',
'#suffix' => '</div>',
];
$form['submitted']['container']['entity-type'] = [
'#type' => 'select',
'#title' => $this
->t('Entity type'),
'#title_display' => 'invisible',
'#empty_option' => $this
->t('- None -'),
'#options' => $entity_types,
'#default_value' => $this
->getSetting('entity-type'),
];
$form['submitted']['container']['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['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 webform before generating new submissions'),
'#default_value' => $this
->getSetting('kill'),
];
$form['#validate'] = [
[
$this,
'validateForm',
],
];
return $form;
}
/**
* Custom validation handler.
*/
public function validateForm(array $form, FormStateInterface $form_state) {
$webform_ids = array_filter($form_state
->getValue('webform_ids'));
// Let default webform validation handle requiring webform ids.
if (empty($webform_ids)) {
return;
}
$entity_type = $form_state
->getValue('entity-type');
$entity_id = $form_state
->getValue('entity-id');
if ($entity_type) {
if ($error = $this
->validateEntity($webform_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 webforms.
*
* @param array $values
* The element values from the settings webform.
*/
protected function generateSubmissions(array $values) {
static::$generatingSubmissions = TRUE;
if (!empty($values['kill'])) {
$this
->deleteWebformSubmissions($values['webform_ids'], $values['entity-type'], $values['entity-id']);
$this
->setMessage($this
->t('Deleted existing submissions.'));
}
if (!empty($values['webform_ids'])) {
$this
->initializeGenerate($values);
$start = $this->time
->getRequestTime();
for ($i = 1; $i <= $values['num']; $i++) {
$this
->generateSubmission($values);
$feedback = isset($values['feedback']) && is_int($values['feedback']) ? $values['feedback'] : 1000;
if ($i % $feedback === 0) {
$now = $this->time
->getRequestTime();
$dt_args = [
'@feedback' => $feedback,
'@rate' => $feedback * 60 / ($now - $start),
];
\Drupal::logger('webform')
->notice($this
->t('Completed @feedback submissions (@rate submissions/min)', $dt_args));
$start = $now;
}
}
}
$this
->setMessage($this
->formatPlural($values['num'], '1 submissions created.', 'Finished creating @count submissions'));
static::$generatingSubmissions = FALSE;
}
/**
* Deletes all submissions of given webforms.
*
* @param array $webform_ids
* Array of webform ids.
* @param string|null $entity_type
* A webform source entity type.
* @param int|null $entity_id
* A webform source entity id.
*/
protected function deleteWebformSubmissions(array $webform_ids, $entity_type = NULL, $entity_id = NULL) {
$webforms = $this->webformStorage
->loadMultiple($webform_ids);
$entity = $entity_type && $entity_id ? $this->entityTypeManager
->getStorage($entity_type)
->load($entity_id) : NULL;
foreach ($webforms as $webform) {
$this->webformSubmissionStorage
->deleteAll($webform, $entity);
}
}
/**
* Add 'users' that contains a list of uids.
*
* @param array $values
* The element values from the settings webform.
*/
protected function initializeGenerate(array &$values) {
// Set user id.$devel_generate_manager = \Drupal::service('plugin.manager.develgenerate')
$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'] = $this->time
->getRequestTime();
// Set entity type and id default value.
$values += [
'num' => 50,
'entity-type' => '',
'entity-id' => '',
];
}
/**
* Create one node. Used by both batch and non-batch code branches.
*/
protected function generateSubmission(&$results) {
$webform_id = array_rand(array_filter($results['webform_ids']));
/** @var \Drupal\webform\WebformInterface $webform */
$webform = $this->webformStorage
->load($webform_id);
$users = $results['users'];
$uid = $users[array_rand($users)];
$entity_type = $results['entity-type'];
$entity_id = $results['entity-id'];
// Get submission URL from source entity or webform.
$url = $webform
->toUrl();
if ($entity_type && $entity_id) {
$source_entity = \Drupal::entityTypeManager()
->getStorage($entity_type)
->load($entity_id);
if ($source_entity
->hasLinkTemplate('canonical')) {
$url = $source_entity
->toUrl();
}
}
$timestamp = rand($results['created_min'], $results['created_max']);
$this->webformSubmissionStorage
->create([
'webform_id' => $webform_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() . '#', '/', $url
->toString()),
'data' => Yaml::encode($this->webformSubmissionGenerate
->getData($webform)),
'created' => $timestamp,
'changed' => $timestamp,
])
->save();
}
/**
* {@inheritdoc}
*/
public function _validateDrushParams($args) {
$webform_id = array_shift($args);
$webform_ids = [
$webform_id => $webform_id,
];
$values = [
'webform_ids' => $webform_ids,
'num' => array_shift($args) ?: 50,
'kill' => empty($args['kill']) ? FALSE : TRUE,
];
if (empty($webform_id)) {
throw new \Exception(dt('Webform ida required'));
}
if (!$this
->getWebformStorage()
->load($webform_id)) {
throw new \Exception(dt('Invalid webform name: @name', [
'@name' => $webform_id,
]));
}
if ($this
->isNumber($values['num']) === FALSE) {
throw new \Exception(dt('Invalid number of submissions: @num', [
'@num' => $values['num'],
]));
}
$entity_type = $args['entity-type'];
$entity_id = $args['entity-id'];
if ($entity_type || $entity_id) {
if ($error = $this
->validateEntity($webform_ids, $entity_type, $entity_id)) {
throw new \Exception($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 = $this->database
->queryRange('SELECT uid FROM {users}', 0, 50);
foreach ($result as $record) {
$users[] = $record->uid;
}
return $users;
}
/**
* Track if webform submissions are being generated.
*
* Used to block emails from being sent while using devel generate.
*
* @return bool
* TRUE if webform submissions are being generated.
*/
public static function isGeneratingSubmissions() {
return static::$generatingSubmissions;
}
/**
* Validate webform source entity type and id.
*
* @param array $webform_ids
* An array webform 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 $webform_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();
$webform_field_name = $this->webformEntityReferenceManager
->getFieldName($source_entity);
if (!$webform_field_name) {
return $t("'@title' (@entity_type:@entity_id) does not have a 'webform' field.", $dt_args);
}
if (count($webform_ids) > 1) {
return $t("'@title' (@entity_type:@entity_id) can only be associated with a single webform.", $dt_args);
}
$dt_args['@webform_ids'] = WebformArrayHelper::toString($webform_ids, $t('or'));
if (!in_array($source_entity->webform->target_id, $webform_ids)) {
return $t("'@title' (@entity_type:@entity_id) does not have a '@webform_ids' webform associated with it.", $dt_args);
}
return NULL;
}
}