Yaffs site version 1.1
[yaffs-website] / vendor / drush / drush / commands / core / cache.drush.inc
1 <?php
2
3 use Drush\Log\LogLevel;
4 use Drupal\Core\DrupalKernel;
5 use Drupal\Core\Site\Settings;
6 use Symfony\Component\HttpFoundation\Request;
7
8 /**
9  * Implementation of hook_drush_help().
10  */
11 function cache_drush_help($section) {
12   switch ($section) {
13     case 'meta:cache:title':
14       return dt('Cache commands');
15     case 'meta:cache:summary':
16       return dt('Interact with Drupal\'s cache API.');
17   }
18 }
19
20 /**
21  * Implementation of hook_drush_command().
22  */
23 function cache_drush_command() {
24   $items = array();
25
26   // We specify command callbacks here because the defaults would collide with
27   // the drush cache api functions.
28   $items['cache-get'] = array(
29     'description' => 'Fetch a cached object and display it.',
30     'examples' => array(
31       'drush cache-get schema' => 'Display the data for the cache id "schema" from the "cache" bin.',
32       'drush cache-get update_available_releases update' => 'Display the data for the cache id "update_available_releases" from the "update" bin.',
33     ),
34     'arguments' => array(
35       'cid' => 'The id of the object to fetch.',
36       'bin' => 'Optional. The cache bin to fetch from.',
37     ),
38     'required-arguments' => 1,
39     'callback' => 'drush_cache_command_get',
40     'outputformat' => array(
41       'default' => 'print-r',
42       'pipe-format' => 'var_export',
43       'output-data-type' => TRUE,
44     ),
45     'aliases' => array('cg'),
46   );
47   $items['cache-clear'] = array(
48     'bootstrap' => DRUSH_BOOTSTRAP_MAX,
49     'description' => 'Clear a specific cache, or all drupal caches.',
50     'arguments' => array(
51       'type' => 'The particular cache to clear. Omit this argument to choose from available caches.',
52     ),
53     'callback' => 'drush_cache_command_clear',
54     'aliases' => array('cc'),
55   );
56   $items['cache-set'] = array(
57     'description' => 'Cache an object expressed in JSON or var_export() format.',
58     'arguments' => array(
59       'cid' => 'The id of the object to set.',
60       'data' => 'The object to set in the cache. Use \'-\' to read the object from STDIN.',
61       'bin' => 'Optional. The cache bin to store the object in.',
62       'expire' => 'Optional. CACHE_PERMANENT, CACHE_TEMPORARY, or a Unix timestamp.',
63       'tags' => 'An array of cache tags.',
64     ),
65     'required-arguments' => 2,
66     'options' => array(
67       // Note that this is not an outputformat option.
68       'format' => 'Format to parse the object. Use "string" for string (default), and "json" for JSON.',
69       'cache-get' => 'If the object is the result a previous fetch from the cache, only store the value in the "data" property of the object in the cache.',
70     ),
71     'callback' => 'drush_cache_command_set',
72     'aliases' => array('cs'),
73   );
74   $items['cache-rebuild'] = array(
75     'description' => 'Rebuild a Drupal 8 site and clear all its caches.',
76     'options' => array(),
77     'arguments' => array(),
78     // Bootstrap to DRUSH_BOOTSTAP_DRUPAL_SITE to pick the correct site.
79     // Further bootstrap is done by the rebuild script.
80     'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_SITE,
81     'core' => array('8+'),
82     'aliases' => array('cr', 'rebuild'),
83   );
84
85   return $items;
86 }
87
88 /**
89  * Command argument complete callback.
90  *
91  * @return
92  *   Array of clear types.
93  */
94 function cache_cache_clear_complete() {
95   // Bootstrap as far as possible so that Views and others can list their caches.
96   drush_bootstrap_max();
97   return array('values' => array_keys(drush_cache_clear_types(TRUE)));
98 }
99
100 function drush_cache_clear_pre_validate($type = NULL) {
101   $types = drush_cache_clear_types(drush_has_boostrapped(DRUSH_BOOTSTRAP_DRUPAL_FULL));
102   // Check if the provided type ($type) is a valid cache type.
103   if ($type && !array_key_exists($type, $types)) {
104     if ($type === 'all' && drush_drupal_major_version() >= 8) {
105       return drush_set_error(dt('`cache-clear all` is deprecated for Drupal 8 and later. Please use the `cache-rebuild` command instead.'));
106     }
107     // If we haven't done a full bootstrap, provide a more
108     // specific message with instructions to the user on
109     // bootstrapping a Drupal site for more options.
110     if (!drush_has_boostrapped(DRUSH_BOOTSTRAP_DRUPAL_FULL)) {
111       $all_types = drush_cache_clear_types(TRUE);
112       if (array_key_exists($type, $all_types)) {
113         return drush_set_error(dt("'!type' cache requires a working Drupal site to operate on. Use the --root and --uri options, or a site @alias, or cd to a directory containing a Drupal settings.php file.", array('!type' => $type)));
114       }
115       else {
116         return drush_set_error(dt("'!type' cache is not a valid cache type. There may be more cache types available if you select a working Drupal site.", array('!type' => $type)));
117       }
118     }
119     return drush_set_error(dt("'!type' cache is not a valid cache type.", array('!type' => $type)));
120   }
121 }
122
123 /**
124  * Command callback for drush cache-clear.
125  */
126 function drush_cache_command_clear($type = NULL) {
127   if (!drush_get_option('cache-clear', TRUE)) {
128     drush_log(dt("Skipping cache-clear operation due to --cache-clear=0 option."), LogLevel::OK);
129     return TRUE;
130   }
131   $types = drush_cache_clear_types(drush_has_boostrapped(DRUSH_BOOTSTRAP_DRUPAL_FULL));
132
133   if (!isset($type)) {
134     // Don't offer 'all' unless Drush has bootstrapped the Drupal site
135     if (!drush_has_boostrapped(DRUSH_BOOTSTRAP_DRUPAL_FULL)) {
136       unset($types['all']);
137     }
138     $type = drush_choice($types, 'Enter a number to choose which cache to clear.', '!key');
139     if (empty($type)) {
140       return drush_user_abort();
141     }
142   }
143   // Do it.
144   drush_op($types[$type]);
145   if ($type == 'all' && !drush_has_boostrapped(DRUSH_BOOTSTRAP_DRUPAL_FULL)) {
146     drush_log(dt("No Drupal site found, only 'drush' cache was cleared."), LogLevel::WARNING);
147   }
148   else {
149     drush_log(dt("'!name' cache was cleared.", array('!name' => $type)), LogLevel::SUCCESS);
150   }
151 }
152
153 /**
154  * Print an object returned from the cache.
155  *
156  * @param $cid
157  *   The cache ID of the object to fetch.
158  * @param $bin
159  *   A specific bin to fetch from. If not specified, the default bin is used.
160  */
161 function drush_cache_command_get($cid = NULL, $bin = NULL) {
162   drush_include_engine('drupal', 'cache');
163   $result = drush_op('_drush_cache_command_get', $cid, $bin);
164
165   if (empty($result)) {
166     return drush_set_error('DRUSH_CACHE_OBJECT_NOT_FOUND', dt('The !cid object in the !bin bin was not found.', array('!cid' => $cid, '!bin' => $bin ? $bin : _drush_cache_bin_default())));
167   }
168   return $result;
169 }
170
171 /**
172  * Set an object in the cache.
173  *
174  * @param $cid
175  *   The cache ID of the object to fetch.
176  * @param $data
177  *   The data to save to the cache, or '-' to read from STDIN.
178  * @param $bin
179  *   A specific bin to fetch from. If not specified, the default bin is used.
180  * @param $expire
181  *   The expiry timestamp for the cached object.
182  * @param $tags
183  *   Cache tags for the cached object.
184  */
185 function drush_cache_command_set($cid = NULL, $data = '', $bin = NULL, $expire = NULL, $tags = array()) {
186   // In addition to prepare, this also validates. Can't easily be in own validate callback as
187   // reading once from STDIN empties it.
188   $data = drush_cache_set_prepare_data($data);
189   if ($data === FALSE && drush_get_error()) {
190     // An error was logged above.
191     return;
192   }
193
194   drush_include_engine('drupal', 'cache');
195   return drush_op('_drush_cache_command_set', $cid, $data, $bin, $expire, $tags);
196 }
197
198 function drush_cache_set_prepare_data($data) {
199   if ($data == '-') {
200     $data = file_get_contents("php://stdin");
201   }
202
203   // Now, we parse the object.
204   switch (drush_get_option('format', 'string')) {
205     case 'json':
206       $data = drush_json_decode($data);
207       break;
208   }
209
210   if (drush_get_option('cache-get')) {
211     // $data might be an object.
212     if (is_object($data) && $data->data) {
213       $data = $data->data;
214     }
215     // But $data returned from `drush cache-get --format=json` will be an array.
216     elseif (is_array($data) && isset($data['data'])) {
217       $data = $data['data'];
218     }
219     else {
220       // If $data is neither object nor array and cache-get was specified, then
221       // there is a problem.
222       return drush_set_error('CACHE_INVALID_FORMAT', dt("'cache-get' was specified as an option, but the data is neither an object or an array."));
223     }
224   }
225
226   return $data;
227 }
228
229 /**
230  * All types of caches available for clearing. Contrib commands can alter in their own.
231  */
232 function drush_cache_clear_types($include_bootstrapped_types = FALSE) {
233   drush_include_engine('drupal', 'cache');
234   $types = _drush_cache_clear_types($include_bootstrapped_types);
235
236   // Include the appropriate environment engine, so callbacks can use core
237   // version specific cache clearing functions directly.
238   drush_include_engine('drupal', 'environment');
239
240   // Command files may customize $types as desired.
241   drush_command_invoke_all_ref('drush_cache_clear', $types, $include_bootstrapped_types);
242
243   return $types;
244 }
245
246 /**
247  * Clear caches internal to drush core.
248  */
249 function drush_cache_clear_drush() {
250   drush_cache_clear_all(NULL, 'default'); // commandfiles, etc.
251   drush_cache_clear_all(NULL, 'complete'); // completion
252   // Release XML. We don't clear tarballs since those never change.
253   $matches = drush_scan_directory(drush_directory_cache('download'), "/^https---updates.drupal.org-release-history/", array('.', '..'));
254   array_map('unlink', array_keys($matches));
255 }
256
257 /**
258  * Rebuild a Drupal 8 site.
259  *
260  * This is a transpose of core/rebuild.php. Additionally
261  * it also clears drush cache and drupal render cache.
262  */
263 function drush_cache_rebuild() {
264   if (!drush_get_option('cache-clear', TRUE)) {
265     drush_log(dt("Skipping cache-clear operation due to --cache-clear=0 option."), LogLevel::OK);
266     return TRUE;
267   }
268   chdir(DRUPAL_ROOT);
269
270   // Clear the APC cache to ensure APC class loader is reset.
271   if (function_exists('apc_fetch')) {
272     apc_clear_cache('user');
273   }
274   // Clear user cache for all major platforms.
275   $user_caches = [
276     'apcu_clear_cache',
277     'wincache_ucache_clear',
278     'xcache_clear_cache',
279   ];
280   foreach (array_filter($user_caches, 'is_callable') as $cache) {
281     call_user_func($cache);
282   }
283
284   $autoloader = drush_drupal_load_autoloader(DRUPAL_ROOT);
285   require_once DRUSH_DRUPAL_CORE . '/includes/utility.inc';
286
287   $request = Request::createFromGlobals();
288   // Ensure that the HTTP method is set, which does not happen with Request::createFromGlobals().
289   $request->setMethod('GET');
290   // Manually resemble early bootstrap of DrupalKernel::boot().
291   require_once DRUSH_DRUPAL_CORE . '/includes/bootstrap.inc';
292   DrupalKernel::bootEnvironment();
293   // Avoid 'Only variables should be passed by reference'
294   $root  = DRUPAL_ROOT;
295   $site_path = DrupalKernel::findSitePath($request);
296   Settings::initialize($root, $site_path, $autoloader);
297
298   // Use our error handler since _drupal_log_error() depends on an unavailable theme system (ugh).
299   set_error_handler('drush_error_handler');
300
301   // drupal_rebuild() calls drupal_flush_all_caches() itself, so we don't do it manually.
302   drupal_rebuild($autoloader, $request);
303   drush_log(dt('Cache rebuild complete.'), LogLevel::OK);
304
305   // As this command replaces `drush cache-clear all` for Drupal 8 users, clear
306   // the Drush cache as well, for consistency with that behavior.
307   drush_cache_clear_drush();
308 }
309