Pull merge.
[yaffs-website] / web / modules / contrib / simple_sitemap / src / Batch.php
1 <?php
2
3 namespace Drupal\simple_sitemap;
4
5 use Drupal\Core\StringTranslation\StringTranslationTrait;
6 use Drupal\Core\Cache\Cache;
7
8 /**
9  * Class Batch
10  * @package Drupal\simple_sitemap\Batch
11  *
12  * The services of this class are not injected, as this class looses its state
13  * on every method call because of how the batch APi works.
14  */
15 class Batch {
16
17   use StringTranslationTrait;
18
19   /**
20    * @var array
21    */
22   protected $batch;
23
24   /**
25    * @var array
26    */
27   protected $batchSettings;
28
29   const BATCH_TITLE = 'Generating XML sitemap';
30   const BATCH_INIT_MESSAGE = 'Initializing batch...';
31   const BATCH_ERROR_MESSAGE = 'An error has occurred. This may result in an incomplete XML sitemap.';
32   const BATCH_PROGRESS_MESSAGE = 'Processing @current out of @total link types.';
33   const REGENERATION_FINISHED_MESSAGE = 'The <a href="@url" target="_blank">XML sitemap</a> has been regenerated.';
34   const REGENERATION_FINISHED_ERROR_MESSAGE = 'The sitemap generation finished with an error.';
35
36   /**
37    * Batch constructor.
38    */
39   public function __construct() {
40     $this->batch = [
41       'title' => $this->t(self::BATCH_TITLE),
42       'init_message' => $this->t(self::BATCH_INIT_MESSAGE),
43       'error_message' => $this->t(self::BATCH_ERROR_MESSAGE),
44       'progress_message' => $this->t(self::BATCH_PROGRESS_MESSAGE),
45       'operations' => [],
46       'finished' => [__CLASS__, 'finishGeneration'],
47     ];
48   }
49
50   /**
51    * @param array $batch_settings
52    */
53   public function setBatchSettings(array $batch_settings) {
54     $this->batchSettings = $batch_settings;
55   }
56
57   /**
58    * Starts the batch process depending on where it was requested from.
59    */
60   public function start() {
61     switch ($this->batchSettings['from']) {
62
63       case 'form':
64         // Start batch process.
65         batch_set($this->batch);
66         return TRUE;
67
68       case 'drush':
69         // Start drush batch process.
70         batch_set($this->batch);
71
72         // See https://www.drupal.org/node/638712
73         $this->batch =& batch_get();
74         $this->batch['progressive'] = FALSE;
75
76         drush_log($this->t(self::BATCH_INIT_MESSAGE), 'status');
77         drush_backend_batch_process();
78         return TRUE;
79
80       case 'backend':
81         // Start backend batch process.
82         batch_set($this->batch);
83
84         // See https://www.drupal.org/node/638712
85         $this->batch =& batch_get();
86         $this->batch['progressive'] = FALSE;
87
88         // todo: Does not take advantage of batch API and eventually runs out of memory on very large sites. Use queue API instead?
89         batch_process();
90         return TRUE;
91
92       case 'nobatch':
93         // Call each batch operation the way the Drupal batch API would do, but
94         // within one process (so in fact not using batch API here, just
95         // mimicking it to avoid code duplication).
96         $context = [];
97         foreach ($this->batch['operations'] as $i => $operation) {
98           $operation[1][] = &$context;
99           call_user_func_array($operation[0], $operation[1]);
100         }
101         $this->finishGeneration(TRUE, !empty($context['results']) ? $context['results'] : [], []);
102         return TRUE;
103     }
104     return FALSE;
105   }
106
107   /**
108    * Adds an operation to the batch.
109    *
110    * @param $plugin_id
111    * @param array|null $data_sets
112    */
113   public function addOperation($plugin_id, $data_sets = NULL) {
114     $this->batch['operations'][] = [
115       __CLASS__ . '::generate', [$plugin_id, $data_sets, $this->batchSettings],
116     ];
117   }
118
119   /**
120    * Batch callback function which generates URLs.
121    *
122    * @param $plugin_id
123    * @param array|null $data_sets
124    * @param array $batch_settings
125    * @param $context
126    *
127    * @see https://api.drupal.org/api/drupal/core!includes!form.inc/group/batch/8
128    */
129   public static function generate($plugin_id, $data_sets, array $batch_settings, &$context) {
130     \Drupal::service('plugin.manager.simple_sitemap.url_generator')
131       ->createInstance($plugin_id)
132       ->setContext($context)
133       ->setBatchSettings($batch_settings)
134       ->generate($data_sets);
135   }
136
137   /**
138    * Callback function called by the batch API when all operations are finished.
139    *
140    * @param $success
141    * @param $results
142    * @param $operations
143    *
144    * @see https://api.drupal.org/api/drupal/core!includes!form.inc/group/batch/8
145    */
146   public static function finishGeneration($success, $results, $operations) {
147     if ($success) {
148       $remove_sitemap = empty($results['chunk_count']);
149       if (!empty($results['generate']) || $remove_sitemap) {
150         \Drupal::service('simple_sitemap.sitemap_generator')
151           ->setSettings(['excluded_languages' => \Drupal::service('simple_sitemap.generator')->getSetting('excluded_languages', [])])
152           ->generateSitemap(!empty($results['generate']) ? $results['generate'] : [], $remove_sitemap);
153       }
154       Cache::invalidateTags(['simple_sitemap']);
155       \Drupal::service('simple_sitemap.logger')->m(self::REGENERATION_FINISHED_MESSAGE,
156         ['@url' => $GLOBALS['base_url'] . '/sitemap.xml'])
157 //        ['@url' => $this->sitemapGenerator->getCustomBaseUrl() . '/sitemap.xml']) //todo: Use actual base URL for message.
158         ->display('status')
159         ->log('info');
160     }
161     else {
162       \Drupal::service('simple_sitemap.logger')->m(self::REGENERATION_FINISHED_ERROR_MESSAGE)
163         ->display('error', 'administer sitemap settings')
164         ->log('error');
165     }
166   }
167
168 }