Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / web / modules / contrib / media_entity / src / Plugin / DevelGenerate / MediaDevelGenerate.php
1 <?php
2
3 namespace Drupal\media_entity\Plugin\DevelGenerate;
4
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;
16
17 /**
18  * Provides a MediaDevelGenerate plugin.
19  *
20  * @DevelGenerate(
21  *   id = "media",
22  *   label = @Translation("media"),
23  *   description = @Translation("Generate a given number of media entities."),
24  *   url = "media",
25  *   permission = "administer devel_generate",
26  *   settings = {
27  *     "num" = 50,
28  *     "kill" = FALSE,
29  *     "name_length" = 4
30  *   }
31  * )
32  */
33 class MediaDevelGenerate extends DevelGenerateBase implements ContainerFactoryPluginInterface {
34
35   /**
36    * The media storage.
37    *
38    * @var \Drupal\media_entity\MediaStorageInterface
39    */
40   protected $mediaStorage;
41
42   /**
43    * The media bundle storage.
44    *
45    * @var \Drupal\Core\Entity\EntityStorageInterface
46    */
47   protected $mediaBundleStorage;
48
49   /**
50    * The user storage.
51    *
52    * @var \Drupal\Core\Entity\EntityStorageInterface
53    */
54   protected $userStorage;
55
56   /**
57    * The module handler.
58    *
59    * @var \Drupal\Core\Extension\ModuleHandlerInterface
60    */
61   protected $moduleHandler;
62
63   /**
64    * The language manager.
65    *
66    * @var \Drupal\Core\Language\LanguageManagerInterface
67    */
68   protected $languageManager;
69
70   /**
71    * The url generator service.
72    *
73    * @var \Drupal\Core\Routing\UrlGeneratorInterface
74    */
75   protected $urlGenerator;
76
77   /**
78    * The date formatter service.
79    *
80    * @var \Drupal\Core\Datetime\DateFormatter
81    */
82   protected $dateFormatter;
83
84   /**
85    * Database connection.
86    *
87    * @var Connection
88    */
89   protected $database;
90
91   /**
92    * Constructs MediaDevelGenerate class.
93    *
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
101    *   The media storage.
102    * @param \Drupal\Core\Entity\EntityStorageInterface $user_storage
103    *   The 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.
114    */
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);
117
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;
125   }
126
127   /**
128    * {@inheritdoc}
129    */
130   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
131     $entity_manager = $container->get('entity.manager');
132     return new static(
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')
141     );
142   }
143
144   /**
145    * {@inheritdoc}
146    */
147   public function settingsForm(array $form, FormStateInterface $form_state) {
148     $bundles = $this->mediaBundleStorage->loadMultiple();
149
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);
153       return [];
154     }
155
156     $options = [];
157     foreach ($bundles as $bundle) {
158       $options[$bundle->id()] = ['bundle' => ['#markup' => $bundle->label()]];
159     }
160
161     $form['media_bundles'] = [
162       '#type' => 'tableselect',
163       '#header' => ['bundle' => $this->t('Media bundle')],
164       '#options' => $options,
165     ];
166
167     $form['kill'] = [
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'),
171     ];
172     $form['num'] = [
173       '#type' => 'number',
174       '#title' => $this->t('How many media items would you like to generate?'),
175       '#default_value' => $this->getSetting('num'),
176       '#required' => TRUE,
177       '#min' => 0,
178     ];
179
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');
183     }
184     $form['time_range'] = [
185       '#type' => 'select',
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,
190     ];
191
192     $form['name_length'] = [
193       '#type' => 'number',
194       '#title' => $this->t('Maximum number of words in names'),
195       '#default_value' => $this->getSetting('name_length'),
196       '#required' => TRUE,
197       '#min' => 1,
198       '#max' => 255,
199     ];
200
201     $options = [];
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();
206     }
207
208     $form['add_language'] = [
209       '#type' => 'select',
210       '#title' => $this->t('Set language on media'),
211       '#multiple' => TRUE,
212       '#description' => $this->t('Requires locale.module'),
213       '#options' => $options,
214       '#default_value' => [
215         $this->languageManager->getDefaultLanguage()->getId(),
216       ],
217     ];
218
219     $form['#redirect'] = FALSE;
220
221     return $form;
222   }
223
224   /**
225    * {@inheritdoc}
226    */
227   protected function generateElements(array $values) {
228     if ($values['num'] <= 50) {
229       $this->generateMedia($values);
230     }
231     else {
232       $this->generateBatchMedia($values);
233     }
234   }
235
236   /**
237    * Method for creating media when number of elements is less than 50.
238    *
239    * @param array $values
240    *   Array of values submitted through a form.
241    */
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);
246     }
247
248     if (!empty($values['media_bundles'])) {
249       // Generate media.
250       $this->preGenerate($values);
251       $start = time();
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) {
255           $now = time();
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),
259           ]), 'ok');
260           $start = $now;
261         }
262       }
263     }
264     $this->setMessage($this->formatPlural($values['num'], '1 media created.', 'Finished creating @count media items.'));
265   }
266
267   /**
268    * Method for creating media when number of elements is greater than 50.
269    *
270    * @param array $values
271    *   The input values from the settings form.
272    */
273   private function generateBatchMedia($values) {
274     // Setup the batch operations and save the variables.
275     $operations[] = [
276       'devel_generate_operation',
277       [$this, 'batchPreGenerate', $values],
278     ];
279
280     // Add the kill operation.
281     if ($values['kill']) {
282       $operations[] = [
283         'devel_generate_operation',
284         [$this, 'batchMediaKill', $values],
285       ];
286     }
287
288     // Add the operations to create the media.
289     for ($num = 0; $num < $values['num']; $num++) {
290       $operations[] = [
291         'devel_generate_operation',
292         [$this, 'batchCreateMediaItem', $values],
293       ];
294     }
295
296     // Start the batch.
297     $batch = [
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',
302     ];
303     batch_set($batch);
304   }
305
306   /**
307    * Batch version of preGenerate().
308    *
309    * @param array $vars
310    *   The input values from the settings form.
311    * @param array $context
312    *   Batch job context.
313    */
314   public function batchPreGenerate($vars, &$context) {
315     $context['results'] = $vars;
316     $context['results']['num'] = 0;
317     $this->preGenerate($context['results']);
318   }
319
320   /**
321    * Batch version of createMediaItem().
322    *
323    * @param array $vars
324    *   The input values from the settings form.
325    * @param array $context
326    *   Batch job context.
327    */
328   public function batchCreateMediaItem($vars, &$context) {
329     $this->createMediaItem($context['results']);
330     $context['results']['num']++;
331   }
332
333   /**
334    * Batch version of mediaKill().
335    *
336    * @param array $vars
337    *   The input values from the settings form.
338    * @param array $context
339    *   Batch job context.
340    */
341   public function batchMediaKill($vars, &$context) {
342     $this->mediaKill($context['results']);
343   }
344
345   /**
346    * {@inheritdoc}
347    */
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)));
355     }
356
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', []));
361
362     if (empty($selected_bundles)) {
363       return drush_set_error('DEVEL_GENERATE_NO_MEDIA_BUNDLES', dt('No media bundles available'));
364     }
365
366     $values['media_bundles'] = array_combine($selected_bundles, $selected_bundles);
367
368     return $values;
369   }
370
371   /**
372    * Deletes all media of given media bundles.
373    *
374    * @param array $values
375    *   The input values from the settings form.
376    */
377   protected function mediaKill($values) {
378     $mids = $this->mediaStorage->getQuery()
379       ->condition('bundle', $values['media_bundles'], 'IN')
380       ->execute();
381
382     if (!empty($mids)) {
383       $media = $this->mediaStorage->loadMultiple($mids);
384       $this->mediaStorage->delete($media);
385       $this->setMessage($this->t('Deleted %count media items.', ['%count' => count($mids)]));
386     }
387   }
388
389   /**
390    * Code to be run before generating items.
391    *
392    * Returns the same array passed in as parameter, but with an array of uids
393    * for the key 'users'.
394    *
395    * @param array $results
396    *   The input values from the settings form.
397    */
398   protected function preGenerate(&$results) {
399     // Get user id.
400     $users = $this->userStorage->getQuery()
401       ->range(0, 50)
402       ->execute();
403     $users = array_merge($users, ['0']);
404     $results['users'] = $users;
405   }
406
407   /**
408    * Create one media item. Used by both batch and non-batch code branches.
409    *
410    * @param array $results
411    *   The input values from the settings form.
412    */
413   protected function createMediaItem(&$results) {
414     if (!isset($results['time_range'])) {
415       $results['time_range'] = 0;
416     }
417     $users = $results['users'];
418
419     $bundle = array_rand(array_filter($results['media_bundles']));
420     $uid = $users[array_rand($users)];
421
422     $media = $this->mediaStorage->create([
423       'bundle' => $bundle,
424       'name' => $this->getRandom()->sentences(mt_rand(1, $results['name_length']), TRUE),
425       'uid' => $uid,
426       'revision' => mt_rand(0, 1),
427       'status' => TRUE,
428       'created' => REQUEST_TIME - mt_rand(0, $results['time_range']),
429       'langcode' => $this->getLangcode($results),
430     ]);
431
432     // A flag to let hook implementations know that this is a generated item.
433     $media->devel_generate = $results;
434
435     // Populate all fields with sample values.
436     $this->populateFields($media);
437
438     $media->save();
439   }
440
441   /**
442    * Determine language based on $results.
443    *
444    * @param array $results
445    *   The input values from the settings form.
446    */
447   protected function getLangcode($results) {
448     if (isset($results['add_language'])) {
449       $langcodes = $results['add_language'];
450       $langcode = $langcodes[array_rand($langcodes)];
451     }
452     else {
453       $langcode = $this->languageManager->getDefaultLanguage()->getId();
454     }
455     return $langcode;
456   }
457
458 }