View source
<?php
namespace Drupal\devel_generate\Plugin\DevelGenerate;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Routing\UrlGeneratorInterface;
use Drupal\devel_generate\DevelGenerateBase;
use Drush\Utils\StringUtils;
use Symfony\Component\DependencyInjection\ContainerInterface;
class MediaDevelGenerate extends DevelGenerateBase implements ContainerFactoryPluginInterface {
protected $mediaStorage;
protected $mediaTypeStorage;
protected $userStorage;
protected $languageManager;
protected $urlGenerator;
protected $dateFormatter;
protected $time;
protected $drushBatch;
public function __construct(array $configuration, $plugin_id, array $plugin_definition, EntityTypeManagerInterface $entity_type_manager, LanguageManagerInterface $language_manager, UrlGeneratorInterface $url_generator, DateFormatterInterface $date_formatter, TimeInterface $time) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->mediaStorage = $entity_type_manager
->getStorage('media');
$this->mediaTypeStorage = $entity_type_manager
->getStorage('media_type');
$this->userStorage = $entity_type_manager
->getStorage('user');
$this->languageManager = $language_manager;
$this->urlGenerator = $url_generator;
$this->dateFormatter = $date_formatter;
$this->time = $time;
}
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('language_manager'), $container
->get('url_generator'), $container
->get('date.formatter'), $container
->get('datetime.time'));
}
public function settingsForm(array $form, FormStateInterface $form_state) {
$types = $this->mediaTypeStorage
->loadMultiple();
if (empty($types)) {
$create_url = $this->urlGenerator
->generateFromRoute('entity.media_type.add_form');
$this
->setMessage($this
->t('You do not have any media types that can be generated. <a href=":url">Go create a new media type</a>', [
':url' => $create_url,
]), MessengerInterface::TYPE_ERROR);
return [];
}
$options = [];
foreach ($types as $type) {
$options[$type
->id()] = [
'type' => [
'#markup' => $type
->label(),
],
];
}
$form['media_types'] = [
'#type' => 'tableselect',
'#header' => [
'type' => $this
->t('Media type'),
],
'#options' => $options,
];
$form['kill'] = [
'#type' => 'checkbox',
'#title' => $this
->t('<strong>Delete all media</strong> in these types before generating new media.'),
'#default_value' => $this
->getSetting('kill'),
];
$form['num'] = [
'#type' => 'number',
'#title' => $this
->t('How many media items would you like to generate?'),
'#default_value' => $this
->getSetting('num'),
'#required' => TRUE,
'#min' => 0,
];
$options = [
1 => $this
->t('Now'),
];
foreach ([
3600,
86400,
604800,
2592000,
31536000,
] as $interval) {
$options[$interval] = $this->dateFormatter
->formatInterval($interval, 1) . ' ' . $this
->t('ago');
}
$form['time_range'] = [
'#type' => 'select',
'#title' => $this
->t('How far back in time should the media be dated?'),
'#description' => $this
->t('Media creation dates will be distributed randomly from the current time, back to the selected time.'),
'#options' => $options,
'#default_value' => 604800,
];
$form['name_length'] = [
'#type' => 'number',
'#title' => $this
->t('Maximum number of words in names'),
'#default_value' => $this
->getSetting('name_length'),
'#required' => TRUE,
'#min' => 1,
'#max' => 255,
];
$options = [];
$languages = $this->languageManager
->getLanguages(LanguageInterface::STATE_ALL);
foreach ($languages as $langcode => $language) {
$options[$langcode] = $language
->getName();
}
$form['add_language'] = [
'#type' => 'select',
'#title' => $this
->t('Set language on media'),
'#multiple' => TRUE,
'#description' => $this
->t('Requires locale.module'),
'#options' => $options,
'#default_value' => [
$this->languageManager
->getDefaultLanguage()
->getId(),
],
];
$form['#redirect'] = FALSE;
return $form;
}
public function settingsFormValidate(array $form, FormStateInterface $form_state) {
$media_types = array_filter($form_state
->getValue('media_types'));
if (!$media_types) {
$form_state
->setErrorByName('media_types', $this
->t('Please select at least one media type'));
}
$form_state
->setValue('media_types', array_combine($media_types, $media_types));
}
protected function generateElements(array $values) {
if ($this
->isBatch($values['num'])) {
$this
->generateBatchMedia($values);
}
else {
$this
->generateMedia($values);
}
}
protected function generateMedia(array $values) {
if (!empty($values['kill']) && $values['media_types']) {
$this
->mediaKill($values);
}
if (!empty($values['media_types'])) {
$this
->preGenerate($values);
$start = time();
for ($i = 1; $i <= $values['num']; $i++) {
$this
->createMediaItem($values);
if (isset($values['feedback']) && $i % $values['feedback'] == 0) {
$now = time();
$this
->messenger()
->addStatus(dt('Completed !feedback media items (!rate media/min)', [
'!feedback' => $values['feedback'],
'!rate' => $values['feedback'] * 60 / ($now - $start),
]));
$start = $now;
}
}
}
$this
->setMessage($this
->formatPlural($values['num'], '1 media item created.', 'Finished creating @count media items.'));
}
protected function generateBatchMedia(array $values) {
$operations = [];
$operations[] = [
'devel_generate_operation',
[
$this,
'batchPreGenerate',
$values,
],
];
if ($values['kill']) {
$operations[] = [
'devel_generate_operation',
[
$this,
'batchMediaKill',
$values,
],
];
}
for ($num = 0; $num < $values['num']; $num++) {
$operations[] = [
'devel_generate_operation',
[
$this,
'batchCreateMediaItem',
$values,
],
];
}
$batch = [
'title' => $this
->t('Generating media items'),
'operations' => $operations,
'finished' => 'devel_generate_batch_finished',
'file' => drupal_get_path('module', 'devel_generate') . '/devel_generate.batch.inc',
];
batch_set($batch);
if ($this->drushBatch) {
drush_backend_batch_process();
}
}
public function batchPreGenerate(array $vars, iterable &$context) {
$context['results'] = $vars;
$context['results']['num'] = 0;
$this
->preGenerate($context['results']);
}
public function batchCreateMediaItem(array $vars, &$context) {
if ($this->drushBatch) {
$this
->createMediaItem($vars);
}
else {
$this
->createMediaItem($context['results']);
}
$context['results']['num']++;
}
public function batchMediaKill($vars, &$context) {
if ($this->drushBatch) {
$this
->mediaKill($vars);
}
else {
$this
->mediaKill($context['results']);
}
}
public function validateDrushParams(array $args, array $options = []) {
$add_language = $options['languages'];
if (!empty($add_language)) {
$add_language = explode(',', str_replace(' ', '', $add_language));
$values['values']['add_language'] = array_intersect($add_language, array_keys($this->languageManager
->getLanguages(LanguageInterface::STATE_ALL)));
}
$values['kill'] = $options['kill'];
$values['feedback'] = $options['feedback'];
$values['name_length'] = 6;
$values['num'] = array_shift($args);
$all_media_types = array_values($this->mediaTypeStorage
->getQuery()
->execute());
$requested_media_types = StringUtils::csvToArray($options['media-types'] ?: $all_media_types);
if (empty($requested_media_types)) {
throw new \Exception(dt('No media types available'));
}
if ($invalid_media_types = array_diff($requested_media_types, $all_media_types)) {
throw new \Exception("Requested media types don't exists: " . implode(', ', $invalid_media_types));
}
$values['media_types'] = array_combine($requested_media_types, $requested_media_types);
if ($this
->isBatch($values['num'])) {
$this->drushBatch = TRUE;
$this
->preGenerate($values);
}
return $values;
}
protected function mediaKill(array $values) {
$mids = $this->mediaStorage
->getQuery()
->condition('bundle', $values['media_types'], 'IN')
->execute();
if (!empty($mids)) {
$media = $this->mediaStorage
->loadMultiple($mids);
$this->mediaStorage
->delete($media);
$this
->setMessage($this
->t('Deleted %count media items.', [
'%count' => count($mids),
]));
}
}
protected function preGenerate(array &$results) {
$users = array_values($this->userStorage
->getQuery()
->range(0, 50)
->execute());
$users = array_merge($users, [
'0',
]);
$results['users'] = $users;
}
protected function createMediaItem(array &$results) {
if (!isset($results['time_range'])) {
$results['time_range'] = 0;
}
$media_type = array_rand($results['media_types']);
$uid = $results['users'][array_rand($results['users'])];
$media = $this->mediaStorage
->create([
'bundle' => $media_type,
'name' => $this
->getRandom()
->sentences(mt_rand(1, $results['name_length']), TRUE),
'uid' => $uid,
'revision' => mt_rand(0, 1),
'status' => TRUE,
'created' => $this->time
->getRequestTime() - mt_rand(0, $results['time_range']),
'langcode' => $this
->getLangcode($results),
]);
$media->devel_generate = $results;
$this
->populateFields($media);
$media
->save();
}
protected function getLangcode(array $results) {
if (isset($results['add_language'])) {
$langcodes = $results['add_language'];
$langcode = $langcodes[array_rand($langcodes)];
}
else {
$langcode = $this->languageManager
->getDefaultLanguage()
->getId();
}
return $langcode;
}
protected function isBatch($media_items_count) {
return $media_items_count >= 50;
}
}