3 namespace Drupal\media_entity\Plugin\DevelGenerate;
5 use Drupal\Core\Datetime\DateFormatter;
6 use Drupal\Core\Entity\EntityStorageInterface;
7 use Drupal\Core\Extension\ModuleHandlerInterface;
8 use Drupal\Core\Form\FormStateInterface;
9 use Drupal\Core\Language\LanguageInterface;
10 use Drupal\Core\Language\LanguageManagerInterface;
11 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
12 use Drupal\Core\Routing\UrlGeneratorInterface;
13 use Drupal\devel_generate\DevelGenerateBase;
14 use Drupal\media_entity\MediaStorageInterface;
15 use Symfony\Component\DependencyInjection\ContainerInterface;
18 * Provides a MediaDevelGenerate plugin.
22 * label = @Translation("media"),
23 * description = @Translation("Generate a given number of media entities."),
25 * permission = "administer devel_generate",
33 class MediaDevelGenerate extends DevelGenerateBase implements ContainerFactoryPluginInterface {
38 * @var \Drupal\media_entity\MediaStorageInterface
40 protected $mediaStorage;
43 * The media bundle storage.
45 * @var \Drupal\Core\Entity\EntityStorageInterface
47 protected $mediaBundleStorage;
52 * @var \Drupal\Core\Entity\EntityStorageInterface
54 protected $userStorage;
59 * @var \Drupal\Core\Extension\ModuleHandlerInterface
61 protected $moduleHandler;
64 * The language manager.
66 * @var \Drupal\Core\Language\LanguageManagerInterface
68 protected $languageManager;
71 * The url generator service.
73 * @var \Drupal\Core\Routing\UrlGeneratorInterface
75 protected $urlGenerator;
78 * The date formatter service.
80 * @var \Drupal\Core\Datetime\DateFormatter
82 protected $dateFormatter;
85 * Database connection.
92 * Constructs MediaDevelGenerate class.
94 * @param array $configuration
95 * A configuration array containing information about the plugin instance.
96 * @param string $plugin_id
97 * The plugin ID for the plugin instance.
98 * @param array $plugin_definition
99 * The plugin definition.
100 * @param \Drupal\media_entity\MediaStorageInterface $media_storage
102 * @param \Drupal\Core\Entity\EntityStorageInterface $user_storage
104 * @param \Drupal\Core\Entity\EntityStorageInterface $media_bundle_storage
105 * The media bundle storage.
106 * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
107 * The module handler.
108 * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
109 * The language manager.
110 * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
111 * The url generator service.
112 * @param \Drupal\Core\Datetime\DateFormatter $date_formatter
113 * The date formatter service.
115 public function __construct(array $configuration, $plugin_id, array $plugin_definition, MediaStorageInterface $media_storage, EntityStorageInterface $user_storage, EntityStorageInterface $media_bundle_storage, ModuleHandlerInterface $module_handler, LanguageManagerInterface $language_manager, UrlGeneratorInterface $url_generator, DateFormatter $date_formatter) {
116 parent::__construct($configuration, $plugin_id, $plugin_definition);
118 $this->moduleHandler = $module_handler;
119 $this->mediaStorage = $media_storage;
120 $this->mediaBundleStorage = $media_bundle_storage;
121 $this->userStorage = $user_storage;
122 $this->languageManager = $language_manager;
123 $this->urlGenerator = $url_generator;
124 $this->dateFormatter = $date_formatter;
130 public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
131 $entity_manager = $container->get('entity.manager');
133 $configuration, $plugin_id, $plugin_definition,
134 $entity_manager->getStorage('media'),
135 $entity_manager->getStorage('user'),
136 $entity_manager->getStorage('media_bundle'),
137 $container->get('module_handler'),
138 $container->get('language_manager'),
139 $container->get('url_generator'),
140 $container->get('date.formatter')
147 public function settingsForm(array $form, FormStateInterface $form_state) {
148 $bundles = $this->mediaBundleStorage->loadMultiple();
150 if (empty($bundles)) {
151 $create_url = $this->urlGenerator->generateFromRoute('media.bundle_add');
152 $this->setMessage($this->t('You do not have any media bundles that can be generated. <a href="@create-bundle">Go create a new media bundle</a>', ['@create-bundle' => $create_url]), 'error', FALSE);
157 foreach ($bundles as $bundle) {
158 $options[$bundle->id()] = ['bundle' => ['#markup' => $bundle->label()]];
161 $form['media_bundles'] = [
162 '#type' => 'tableselect',
163 '#header' => ['bundle' => $this->t('Media bundle')],
164 '#options' => $options,
168 '#type' => 'checkbox',
169 '#title' => $this->t('<strong>Delete all media</strong> in these bundles before generating new media.'),
170 '#default_value' => $this->getSetting('kill'),
174 '#title' => $this->t('How many media items would you like to generate?'),
175 '#default_value' => $this->getSetting('num'),
180 $options = [1 => $this->t('Now')];
181 foreach ([3600, 86400, 604800, 2592000, 31536000] as $interval) {
182 $options[$interval] = $this->dateFormatter->formatInterval($interval, 1) . ' ' . $this->t('ago');
184 $form['time_range'] = [
186 '#title' => $this->t('How far back in time should the media be dated?'),
187 '#description' => $this->t('Media creation dates will be distributed randomly from the current time, back to the selected time.'),
188 '#options' => $options,
189 '#default_value' => 604800,
192 $form['name_length'] = [
194 '#title' => $this->t('Maximum number of words in names'),
195 '#default_value' => $this->getSetting('name_length'),
202 // We always need a language.
203 $languages = $this->languageManager->getLanguages(LanguageInterface::STATE_ALL);
204 foreach ($languages as $langcode => $language) {
205 $options[$langcode] = $language->getName();
208 $form['add_language'] = [
210 '#title' => $this->t('Set language on media'),
212 '#description' => $this->t('Requires locale.module'),
213 '#options' => $options,
214 '#default_value' => [
215 $this->languageManager->getDefaultLanguage()->getId(),
219 $form['#redirect'] = FALSE;
227 protected function generateElements(array $values) {
228 if ($values['num'] <= 50) {
229 $this->generateMedia($values);
232 $this->generateBatchMedia($values);
237 * Method for creating media when number of elements is less than 50.
239 * @param array $values
240 * Array of values submitted through a form.
242 private function generateMedia($values) {
243 $values['media_bundles'] = array_filter($values['media_bundles']);
244 if (!empty($values['kill']) && $values['media_bundles']) {
245 $this->mediaKill($values);
248 if (!empty($values['media_bundles'])) {
250 $this->preGenerate($values);
252 for ($i = 1; $i <= $values['num']; $i++) {
253 $this->createMediaItem($values);
254 if (function_exists('drush_log') && $i % drush_get_option('feedback', 1000) == 0) {
256 drush_log(dt('Completed !feedback media items (!rate media/min)', [
257 '!feedback' => drush_get_option('feedback', 1000),
258 '!rate' => (drush_get_option('feedback', 1000) * 60) / ($now - $start),
264 $this->setMessage($this->formatPlural($values['num'], '1 media created.', 'Finished creating @count media items.'));
268 * Method for creating media when number of elements is greater than 50.
270 * @param array $values
271 * The input values from the settings form.
273 private function generateBatchMedia($values) {
274 // Setup the batch operations and save the variables.
276 'devel_generate_operation',
277 [$this, 'batchPreGenerate', $values],
280 // Add the kill operation.
281 if ($values['kill']) {
283 'devel_generate_operation',
284 [$this, 'batchMediaKill', $values],
288 // Add the operations to create the media.
289 for ($num = 0; $num < $values['num']; $num++) {
291 'devel_generate_operation',
292 [$this, 'batchCreateMediaItem', $values],
298 'title' => $this->t('Generating media'),
299 'operations' => $operations,
300 'finished' => 'devel_generate_batch_finished',
301 'file' => drupal_get_path('module', 'devel_generate') . '/devel_generate.batch.inc',
307 * Batch version of preGenerate().
310 * The input values from the settings form.
311 * @param array $context
314 public function batchPreGenerate($vars, &$context) {
315 $context['results'] = $vars;
316 $context['results']['num'] = 0;
317 $this->preGenerate($context['results']);
321 * Batch version of createMediaItem().
324 * The input values from the settings form.
325 * @param array $context
328 public function batchCreateMediaItem($vars, &$context) {
329 $this->createMediaItem($context['results']);
330 $context['results']['num']++;
334 * Batch version of mediaKill().
337 * The input values from the settings form.
338 * @param array $context
341 public function batchMediaKill($vars, &$context) {
342 $this->mediaKill($context['results']);
348 public function validateDrushParams($args) {
349 $add_language = drush_get_option('languages');
350 if (!empty($add_language)) {
351 $add_language = explode(',', str_replace(' ', '', $add_language));
352 // Intersect with the enabled languages to make sure the language args
353 // passed are actually enabled.
354 $values['values']['add_language'] = array_intersect($add_language, array_keys($this->languageManager->getLanguages(LanguageInterface::STATE_ALL)));
357 $values['kill'] = drush_get_option('kill');
358 $values['name_length'] = drush_get_option('name_length', 6);
359 $values['num'] = array_shift($args);
360 $selected_bundles = _convert_csv_to_array(drush_get_option('bundles', []));
362 if (empty($selected_bundles)) {
363 return drush_set_error('DEVEL_GENERATE_NO_MEDIA_BUNDLES', dt('No media bundles available'));
366 $values['media_bundles'] = array_combine($selected_bundles, $selected_bundles);
372 * Deletes all media of given media bundles.
374 * @param array $values
375 * The input values from the settings form.
377 protected function mediaKill($values) {
378 $mids = $this->mediaStorage->getQuery()
379 ->condition('bundle', $values['media_bundles'], 'IN')
383 $media = $this->mediaStorage->loadMultiple($mids);
384 $this->mediaStorage->delete($media);
385 $this->setMessage($this->t('Deleted %count media items.', ['%count' => count($mids)]));
390 * Code to be run before generating items.
392 * Returns the same array passed in as parameter, but with an array of uids
393 * for the key 'users'.
395 * @param array $results
396 * The input values from the settings form.
398 protected function preGenerate(&$results) {
400 $users = $this->userStorage->getQuery()
403 $users = array_merge($users, ['0']);
404 $results['users'] = $users;
408 * Create one media item. Used by both batch and non-batch code branches.
410 * @param array $results
411 * The input values from the settings form.
413 protected function createMediaItem(&$results) {
414 if (!isset($results['time_range'])) {
415 $results['time_range'] = 0;
417 $users = $results['users'];
419 $bundle = array_rand(array_filter($results['media_bundles']));
420 $uid = $users[array_rand($users)];
422 $media = $this->mediaStorage->create([
424 'name' => $this->getRandom()->sentences(mt_rand(1, $results['name_length']), TRUE),
426 'revision' => mt_rand(0, 1),
428 'created' => REQUEST_TIME - mt_rand(0, $results['time_range']),
429 'langcode' => $this->getLangcode($results),
432 // A flag to let hook implementations know that this is a generated item.
433 $media->devel_generate = $results;
435 // Populate all fields with sample values.
436 $this->populateFields($media);
442 * Determine language based on $results.
444 * @param array $results
445 * The input values from the settings form.
447 protected function getLangcode($results) {
448 if (isset($results['add_language'])) {
449 $langcodes = $results['add_language'];
450 $langcode = $langcodes[array_rand($langcodes)];
453 $langcode = $this->languageManager->getDefaultLanguage()->getId();