context.inc

  1. 8.0.x includes/context.inc
  2. 6.x includes/context.inc
  3. 7.x includes/context.inc
  4. 3.x includes/context.inc
  5. 4.x includes/context.inc
  6. 5.x includes/context.inc
  7. master includes/context.inc

The Drush context API implementation.

This API acts as a storage mechanism for all options, arguments and configuration settings that are loaded into drush.

This API also acts as an IPC mechanism between the different drush commands, and provides protection from accidentally overriding settings that are needed by other parts of the system.

It also avoids the necessity to pass references through the command chain and allows the scripts to keep track of whether any settings have changed since the previous execution.

This API defines several contexts that are used by default.

Argument contexts : These contexts are used by Drush to store information on the command. They have their own access functions in the forms of drush_set_arguments(), drush_get_arguments(), drush_set_command(), drush_get_command().

command : The drush command being executed. arguments : Any additional arguments that were specified.

Setting contexts : These contexts store options that have been passed to the drush.php script, either through the use of any of the config files, directly from the command line through --option='value' or through a JSON encoded string passed through the STDIN pipe.

These contexts are accessible through the drush_get_option() and drush_set_option() functions. See drush_context_names() for a description of all of the contexts.

Drush commands may also choose to save settings for a specific context to the matching configuration file through the drush_save_config() function.

Functions

Namesort descending Description
drush_context_names Return a list of the valid drush context names.
drush_get_arguments Get the arguments passed to the drush.php script.
drush_get_command Return the command being executed.
drush_get_context Return a specific context, or the whole context cache
drush_get_context_options Get all of the values for an option in every context.
drush_get_merged_options Retrieves a collapsed list of all options
drush_get_option Get the value for an option.
drush_get_option_list Get the value for an option and return it as a list. If the option in question is passed on the command line, its value should be a comma-separated list (e.g. --flag=1,2,3). If the option was set in a drushrc.php file, then its value may be either…
drush_get_option_override Get the value for an option, but first checks the provided option overrides.
drush_load_config Load drushrc files (if available) from several possible locations.
drush_load_config_file
drush_save_config Save the settings in a specific context to the applicable configuration file This is useful is you want certain settings to be available automatically the next time a command is executed.
drush_set_arguments Set the arguments passed to the drush.php script.
drush_set_command Set the command being executed.
drush_set_config_options
drush_set_config_special_contexts There are certain options such as 'site-aliases' and 'command-specific' that must be merged together if defined in multiple drush configuration files. If we did not do this merge, then the last configuration file that defined any…
drush_set_context Set a specific context.
drush_set_default A small helper function to set the value in the default context
drush_set_option Set an option in one of the option contexts.
drush_unset_option Remove a setting from a specific context.
_drush_config_file Return a list of possible drushrc file locations.
_drush_get_option Helper function to recurse through possible option names

File

includes/context.inc
View source
  1. <?php
  2. /**
  3. * @file
  4. * The Drush context API implementation.
  5. *
  6. * This API acts as a storage mechanism for all options, arguments and
  7. * configuration settings that are loaded into drush.
  8. *
  9. * This API also acts as an IPC mechanism between the different drush commands,
  10. * and provides protection from accidentally overriding settings that are
  11. * needed by other parts of the system.
  12. *
  13. * It also avoids the necessity to pass references through the command chain
  14. * and allows the scripts to keep track of whether any settings have changed
  15. * since the previous execution.
  16. *
  17. * This API defines several contexts that are used by default.
  18. *
  19. * Argument contexts :
  20. * These contexts are used by Drush to store information on the command.
  21. * They have their own access functions in the forms of
  22. * drush_set_arguments(), drush_get_arguments(), drush_set_command(),
  23. * drush_get_command().
  24. *
  25. * command : The drush command being executed.
  26. * arguments : Any additional arguments that were specified.
  27. *
  28. * Setting contexts :
  29. * These contexts store options that have been passed to the drush.php
  30. * script, either through the use of any of the config files, directly from
  31. * the command line through --option='value' or through a JSON encoded string
  32. * passed through the STDIN pipe.
  33. *
  34. * These contexts are accessible through the drush_get_option() and
  35. * drush_set_option() functions. See drush_context_names() for a description
  36. * of all of the contexts.
  37. *
  38. * Drush commands may also choose to save settings for a specific context to
  39. * the matching configuration file through the drush_save_config() function.
  40. */
  41. /**
  42. * Return a list of the valid drush context names.
  43. *
  44. * These context names are carefully ordered from
  45. * highest to lowest priority.
  46. *
  47. * These contexts are evaluated in a certain order, and the highest priority value
  48. * is returned by default from drush_get_option. This allows scripts to check whether
  49. * an option was different before the current execution.
  50. *
  51. * Specified by the script itself :
  52. * process : Generated in the current process.
  53. * cli : Passed as --option=value to the command line.
  54. * stdin : Passed as a JSON encoded string through stdin.
  55. * specific : Defined in a command-specific option record, and
  56. * set in the command context whenever that command is used.
  57. * alias : Defined in an alias record, and set in the
  58. * alias context whenever that alias is used.
  59. *
  60. * Specified by config files :
  61. * custom : Loaded from the config file specified by --config or -c
  62. * site : Loaded from the drushrc.php file in the Drupal site directory.
  63. * drupal : Loaded from the drushrc.php file in the Drupal root directory.
  64. * user : Loaded from the drushrc.php file in the user's home directory.
  65. * home.drush Loaded from the drushrc.php file in the $HOME/.drush directory.
  66. * system : Loaded from the drushrc.php file in the system's $PREFIX/etc/drush directory.
  67. * drush : Loaded from the drushrc.php file in the same directory as drush.php.
  68. *
  69. * Specified by the script, but has the lowest priority :
  70. * default : The script might provide some sensible defaults during init.
  71. */
  72. function drush_context_names() {
  73. static $contexts = array(
  74. 'process', 'cli', 'stdin', 'specific', 'alias',
  75. 'custom', 'site', 'drupal', 'user', 'home.drush', 'system',
  76. 'drush', 'default');
  77. return $contexts;
  78. }
  79. /**
  80. * Return a list of possible drushrc file locations.
  81. *
  82. * @context
  83. * A valid drush context from drush_context_names().
  84. * @prefix
  85. * Optional. Specify a prefix to prepend to ".drushrc.php" when looking
  86. * for config files. Most likely used by contrib commands.
  87. * @return
  88. * An associative array containing possible config files to load
  89. * The keys are the 'context' of the files, the values are the file
  90. * system locations.
  91. */
  92. function _drush_config_file($context, $prefix = NULL, $version = '') {
  93. $configs = array();
  94. $base_name = 'drush' . $version . 'rc.php';
  95. $config_file = $prefix ? $prefix . '.' . $base_name : $base_name;
  96. // Did the user explicitly specify a config file?
  97. if ($config = drush_get_option(array('c', 'config'))) {
  98. if (is_dir($config)) {
  99. $config = $config . '/drushrc.php';
  100. }
  101. $configs['custom'] = $config;
  102. }
  103. if ($site_path = drush_get_context('DRUSH_DRUPAL_SITE_ROOT')) {
  104. $configs['site'] = $site_path . "/" . $config_file;
  105. }
  106. if ($drupal_root = drush_get_context('DRUSH_DRUPAL_ROOT')) {
  107. $configs['drupal'] = $drupal_root . '/' . $config_file;
  108. }
  109. // in the user home directory
  110. if (!is_null(drush_server_home())) {
  111. $configs['user'] = drush_server_home() . '/.' . $config_file;
  112. }
  113. // in $HOME/.drush directory
  114. if (!is_null(drush_server_home())) {
  115. $configs['home.drush'] = drush_server_home() . '/.drush/' . $config_file;
  116. }
  117. // In the system wide configuration folder.
  118. $configs['system'] = drush_get_context('ETC_PREFIX', '') . '/etc/drush/' . $config_file;
  119. // in the drush installation folder
  120. $configs['drush'] = dirname(__FILE__) . '/../' . $config_file;
  121. return empty($configs[$context]) ? '' : $configs[$context];
  122. }
  123. /**
  124. * Load drushrc files (if available) from several possible locations.
  125. */
  126. function drush_load_config($context) {
  127. drush_load_config_file($context, _drush_config_file($context));
  128. drush_load_config_file($context, _drush_config_file($context, '', DRUSH_MAJOR_VERSION));
  129. }
  130. function drush_load_config_file($context, $config) {
  131. if (file_exists($config)) {
  132. $options = $aliases = $command_specific = $override = array();
  133. drush_log(dt('Loading drushrc "!config" into "!context" scope.', array('!config' => realpath($config), '!context' => $context)), 'bootstrap');
  134. $ret = @include_once($config);
  135. if ($ret === FALSE) {
  136. drush_log(dt('Cannot open drushrc "!config", ignoring.', array('!config' => realpath($config))), 'warning');
  137. return FALSE;
  138. }
  139. if (!empty($options) || !empty($aliases) || !empty($command_specific) || !empty($override)) {
  140. $options = array_merge(drush_get_context($context), $options);
  141. $options['config-file'] = realpath($config);
  142. //$options['site-aliases'] = array_merge(isset($aliases) ? $aliases : array(), isset($options['site-aliases']) ? $options['site-aliases'] : array());
  143. unset($options['site-aliases']);
  144. $options['command-specific'] = array_merge(isset($command_specific) ? $command_specific : array(), isset($options['command-specific']) ? $options['command-specific'] : array());
  145. drush_set_config_options($context, $options, $override);
  146. }
  147. }
  148. }
  149. function drush_set_config_options($context, $options, $override = array()) {
  150. global $drush_conf_override;
  151. // Only reset $drush_conf_override if the array is not set, otherwise keep old values and append new values to it.
  152. if (!isset($drush_conf_override)) {
  153. $drush_conf_override = array();
  154. }
  155. // Copy 'config-file' into 'context-path', converting to an array to hold multiple values if necessary
  156. if (isset($options['config-file'])) {
  157. if (isset($options['context-path'])) {
  158. $options['context-path'] = array_merge(array($options['config-file']), is_array($options['context-path']) ? $options['context-path'] : array($options['context-path']));
  159. }
  160. else {
  161. $options['context-path'] = $options['config-file'];
  162. }
  163. }
  164. // Take out $aliases and $command_specific options
  165. drush_set_config_special_contexts($options);
  166. drush_set_context($context, $options);
  167. // Instruct core not to store queries since we are not outputting them.
  168. // Don't run poormanscron during drush request (D7+).
  169. $defaults = array(
  170. 'dev_query' => FALSE,
  171. 'cron_safe_threshold' => 0,
  172. );
  173. foreach ($defaults as $key => $value) {
  174. // This can be overridden by a command or a drushrc file if needed.
  175. if (!isset($drush_conf_override[$key])) {
  176. $drush_conf_override[$key] = $value;
  177. }
  178. }
  179. /**
  180. * Allow the drushrc.php file to override $conf settings.
  181. * This is a separate variable because the $conf array gets
  182. * initialized to an empty array, in the drupal bootstrap process,
  183. * and changes in settings.php would wipe out the drushrc.php settings.
  184. */
  185. if (!empty($override)) {
  186. $drush_conf_override = array_merge($drush_conf_override, $override);
  187. }
  188. }
  189. /**
  190. * There are certain options such as 'site-aliases' and 'command-specific'
  191. * that must be merged together if defined in multiple drush configuration
  192. * files. If we did not do this merge, then the last configuration file
  193. * that defined any of these properties would overwrite all of the options
  194. * that came before in previously-loaded configuration files. We place
  195. * all of them into their own context so that this does not happen.
  196. */
  197. function drush_set_config_special_contexts(&$options) {
  198. if (isset($options)) {
  199. $has_command_specific = array_key_exists('command-specific', $options);
  200. // Change the keys of the site aliases from 'alias' to '@alias'
  201. if (array_key_exists('site-aliases', $options)) {
  202. $user_aliases = $options['site-aliases'];
  203. $options['site-aliases'] = array();
  204. foreach ($user_aliases as $alias_name => $alias_value) {
  205. if (substr($alias_name,0,1) != '@') {
  206. $alias_name = "@$alias_name";
  207. }
  208. $options['site-aliases'][$alias_name] = $alias_value;
  209. }
  210. }
  211. // Copy site aliases and command-specific options into their
  212. // appropriate caches.
  213. $special_contexts = drush_get_special_keys();
  214. foreach ($special_contexts as $option_name) {
  215. if (isset($options[$option_name])) {
  216. $cache =& drush_get_context($option_name);
  217. $cache = array_merge($cache, $options[$option_name]);
  218. unset($options[$option_name]);
  219. }
  220. }
  221. // If command-specific options were set and if we already have
  222. // a command, then apply the command-specific options immediately.
  223. if ($has_command_specific) {
  224. drush_command_default_options();
  225. }
  226. }
  227. }
  228. /**
  229. * Set a specific context.
  230. *
  231. * @param context
  232. * Any of the default defined contexts.
  233. * @param value
  234. * The value to store in the context
  235. *
  236. * @return
  237. * An associative array of the settings specified in the request context.
  238. */
  239. function drush_set_context($context, $value) {
  240. $cache =& drush_get_context($context);
  241. $cache = $value;
  242. return $value;
  243. }
  244. /**
  245. * Return a specific context, or the whole context cache
  246. *
  247. * This function provides a storage mechanism for any information
  248. * the currently running process might need to communicate.
  249. *
  250. * This avoids the use of globals, and constants.
  251. *
  252. * Functions that operate on the context cache, can retrieve a reference
  253. * to the context cache using :
  254. * $cache = &drush_get_context($context);
  255. *
  256. * This is a private function, because it is meant as an internal
  257. * generalized API for writing static cache functions, not as a general
  258. * purpose function to be used inside commands.
  259. *
  260. * Code that modifies the reference directly might have unexpected consequences,
  261. * such as modifying the arguments after they have already been parsed and dispatched
  262. * to the callbacks.
  263. *
  264. * @param context
  265. * Optional. Any of the default defined contexts.
  266. *
  267. * @return
  268. * If context is not supplied, the entire context cache will be returned.
  269. * Otherwise only the requested context will be returned.
  270. * If the context does not exist yet, it will be initialized to an empty array.
  271. */
  272. function &drush_get_context($context = NULL, $default = NULL) {
  273. static $cache = array();
  274. if (!is_null($context)) {
  275. if (!isset($cache[$context])) {
  276. $default = !is_null($default) ? $default : array();
  277. $cache[$context] = $default;
  278. }
  279. return $cache[$context];
  280. }
  281. return $cache;
  282. }
  283. /**
  284. * Set the arguments passed to the drush.php script.
  285. *
  286. * This function will set the 'arguments' context of the current running script.
  287. *
  288. * When initially called by drush_parse_args, the entire list of arguments will
  289. * be populated. Once the command is dispatched, this will be set to only the remaining
  290. * arguments to the command (i.e. the command name is removed).
  291. *
  292. * @param arguments
  293. * Command line arguments, as an array.
  294. */
  295. function drush_set_arguments($arguments) {
  296. drush_set_context('arguments', $arguments);
  297. }
  298. /**
  299. * Get the arguments passed to the drush.php script.
  300. *
  301. * When drush_set_arguments is initially called by drush_parse_args,
  302. * the entire list of arguments will be populated.
  303. * Once the command has been dispatched, this will be return only the remaining
  304. * arguments to the command.
  305. */
  306. function drush_get_arguments() {
  307. return drush_get_context('arguments');
  308. }
  309. /**
  310. * Set the command being executed.
  311. *
  312. * Drush_dispatch will set the correct command based on it's
  313. * matching of the script arguments retrieved from drush_get_arguments
  314. * to the implemented commands specified by drush_get_commands.
  315. *
  316. * @param
  317. * A numerically indexed array of command components.
  318. */
  319. function drush_set_command($command) {
  320. drush_set_context('command', $command);
  321. }
  322. /**
  323. * Return the command being executed.
  324. *
  325. *
  326. */
  327. function drush_get_command() {
  328. return drush_get_context('command');
  329. }
  330. /**
  331. * Get the value for an option.
  332. *
  333. * If the first argument is an array, then it checks whether one of the options
  334. * exists and return the value of the first one found. Useful for allowing both
  335. * -h and --host-name
  336. *
  337. * @param option
  338. * The name of the option to get
  339. * @param default
  340. * Optional. The value to return if the option has not been set
  341. * @param context
  342. * Optional. The context to check for the option. If this is set, only this context will be searched.
  343. */
  344. function drush_get_option($option, $default = NULL, $context = NULL) {
  345. $value = NULL;
  346. if ($context) {
  347. // We have a definite context to check for the presence of an option.
  348. $value = _drush_get_option($option, drush_get_context($context));
  349. }
  350. else {
  351. // We are not checking a specific context, so check them in a predefined order of precedence.
  352. $contexts = drush_context_names();
  353. foreach ($contexts as $context) {
  354. $value = _drush_get_option($option, drush_get_context($context));
  355. if ($value !== NULL) {
  356. return $value;
  357. }
  358. }
  359. }
  360. if ($value !== NULL) {
  361. return $value;
  362. }
  363. return $default;
  364. }
  365. /**
  366. * Get the value for an option and return it as a list. If the
  367. * option in question is passed on the command line, its value should
  368. * be a comma-separated list (e.g. --flag=1,2,3). If the option
  369. * was set in a drushrc.php file, then its value may be either a
  370. * comma-separated list or an array of values (e.g. $option['flag'] = array('1', '2', '3')).
  371. *
  372. * @param option
  373. * The name of the option to get
  374. * @param default
  375. * Optional. The value to return if the option has not been set
  376. * @param context
  377. * Optional. The context to check for the option. If this is set, only this context will be searched.
  378. */
  379. function drush_get_option_list($option, $default = array(), $context = NULL) {
  380. $result = drush_get_option($option, $default, $context);
  381. if (!is_array($result)) {
  382. $result = explode(',', $result);
  383. }
  384. return $result;
  385. }
  386. /**
  387. * Get the value for an option, but first checks the provided option overrides.
  388. *
  389. * The feature of drush_get_option that allows a list of option names
  390. * to be passed in an array is NOT supported.
  391. *
  392. * @param option_overrides
  393. * An array to check for values before calling drush_get_option.
  394. * @param option
  395. * The name of the option to get.
  396. * @param default
  397. * Optional. The value to return if the option has not been set.
  398. * @param context
  399. * Optional. The context to check for the option. If this is set, only this context will be searched.
  400. *
  401. */
  402. function drush_get_option_override($option_overrides, $option, $value = NULL, $context = NULL) {
  403. if (array_key_exists($option, $option_overrides)) {
  404. return $option_overrides[$option];
  405. }
  406. else {
  407. return drush_get_option($option, $value, $context);
  408. }
  409. }
  410. /**
  411. * Get all of the values for an option in every context.
  412. *
  413. * @param option
  414. * The name of the option to get
  415. * @return
  416. * An array whose key is the context name and value is
  417. * the specific value for the option in that context.
  418. */
  419. function drush_get_context_options($option, $flatten = FALSE) {
  420. $result = array();
  421. $contexts = drush_context_names();
  422. foreach ($contexts as $context) {
  423. $value = _drush_get_option($option, drush_get_context($context));
  424. if ($value !== NULL) {
  425. if ($flatten && is_array($value)) {
  426. $result = array_merge($value, $result);
  427. }
  428. else {
  429. $result[$context] = $value;
  430. }
  431. }
  432. }
  433. return $result;
  434. }
  435. /**
  436. * Retrieves a collapsed list of all options
  437. */
  438. function drush_get_merged_options() {
  439. $contexts = drush_context_names();
  440. $cache = drush_get_context();
  441. $result = array();
  442. foreach (array_reverse($contexts) as $context) {
  443. if (array_key_exists($context, $cache)) {
  444. $result = array_merge($result, $cache[$context]);
  445. }
  446. }
  447. return $result;
  448. }
  449. /**
  450. * Helper function to recurse through possible option names
  451. */
  452. function _drush_get_option($option, $context) {
  453. if (is_array($option)) {
  454. foreach ($option as $current) {
  455. if (array_key_exists($current, $context)) {
  456. return $context[$current];
  457. }
  458. }
  459. }
  460. elseif (array_key_exists($option, $context)) {
  461. return $context[$option];
  462. }
  463. return NULL;
  464. }
  465. /**
  466. * Set an option in one of the option contexts.
  467. *
  468. * @param option
  469. * The option to set.
  470. * @param value
  471. * The value to set it to.
  472. * @param context
  473. * Optional. Which context to set it in.
  474. * @return
  475. * The value parameter. This allows for neater code such as
  476. * $myvalue = drush_set_option('http_host', $_SERVER['HTTP_HOST']);
  477. * Without having to constantly type out the value parameter.
  478. */
  479. function drush_set_option($option, $value, $context = 'process') {
  480. $cache =& drush_get_context($context);
  481. $cache[$option] = $value;
  482. return $value;
  483. }
  484. /**
  485. * A small helper function to set the value in the default context
  486. */
  487. function drush_set_default($option, $value) {
  488. return drush_set_option($option, $value, 'default');
  489. }
  490. /**
  491. * Remove a setting from a specific context.
  492. *
  493. * @param
  494. * Option to be unset
  495. * @param
  496. * Context in which to unset the value in.
  497. */
  498. function drush_unset_option($option, $context = NULL) {
  499. if ($context != NULL) {
  500. $cache =& drush_get_context($context);
  501. if (array_key_exists($option, $cache)) {
  502. unset($cache[$option]);
  503. }
  504. }
  505. else {
  506. $contexts = drush_context_names();
  507. foreach ($contexts as $context) {
  508. drush_unset_option($option, $context);
  509. }
  510. }
  511. }
  512. /**
  513. * Save the settings in a specific context to the applicable configuration file
  514. * This is useful is you want certain settings to be available automatically the next time a command is executed.
  515. *
  516. * @param $context
  517. * The context to save
  518. */
  519. function drush_save_config($context) {
  520. $filename = _drush_config_file($context);
  521. if ($filename) {
  522. $cache = drush_get_context($context);
  523. $fp = fopen($filename, "w+");
  524. if (!$fp) {
  525. return drush_set_error('DRUSH_PERM_ERROR', dt('Drushrc (!filename) could not be written', array('!filename' => $filename)));
  526. }
  527. else {
  528. fwrite($fp, "<?php\n");
  529. $timestamp = mktime();
  530. foreach ($cache as $key => $value) {
  531. $line = "\n\$options['$key'] = ". var_export($value, TRUE) .';';
  532. fwrite($fp, $line);
  533. }
  534. fwrite($fp, "\n");
  535. fclose($fp);
  536. drush_log(dt('Drushrc file (!filename) was written successfully', array('!filename' => $filename)));
  537. return TRUE;
  538. }
  539. }
  540. return FALSE;
  541. }