View source
<?php
namespace Drupal\yamlform\Plugin\DevelGenerate;
use Drupal\Core\Serialization\Yaml;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\devel_generate\DevelGenerateBase;
use Drupal\yamlform\Utility\YamlFormArrayHelper;
use Drupal\yamlform\YamlFormSubmissionGenerateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class YamlFormSubmissionDevelGenerate extends DevelGenerateBase implements ContainerFactoryPluginInterface {
protected static $generatingSubmissions = FALSE;
protected $entityTypeManager;
protected $yamlformStorage;
protected $yamlformSubmissionStorage;
protected $yamlformSubmissionGenerate;
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');
}
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'));
}
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;
}
public function validateForm(array $form, FormStateInterface $form_state) {
$yamlform_ids = array_filter($form_state
->getValue('yamlform_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);
}
}
}
public function generateElements(array $values) {
$this
->generateSubmissions($values);
}
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;
}
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);
}
}
protected function initializeGenerate(array &$values) {
$users = $this
->getUsers();
$users = array_merge($users, [
'0',
]);
$values['users'] = $users;
$values['created_min'] = strtotime('-1 month');
$values['created_max'] = time();
}
protected function generateSubmission(&$results) {
$yamlform_id = array_rand(array_filter($results['yamlform_ids']));
$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();
}
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;
}
protected function getUsers() {
$users = [];
$result = db_query_range("SELECT uid FROM {users}", 0, 50);
foreach ($result as $record) {
$users[] = $record->uid;
}
return $users;
}
public static function isGeneratingSubmissions() {
return self::$generatingSubmissions;
}
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;
}
}