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_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. * options : Passed as --option=value to the command line.
  54. * stdin : Passed as a JSON encoded string through stdin.
  55. * alias : Defined in an alias record, and set in the
  56. * alias context whenever that alias is used.
  57. * specific : Defined in a command-specific option record, and
  58. * set in the command context whenever that command 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', 'options', 'stdin', 'alias', 'specific',
  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. * @return
  83. * An associative array containing possible config files to load
  84. * The keys are the 'context' of the files, the values are the file
  85. * system locations.
  86. */
  87. function _drush_config_file($context) {
  88. $configs = array();
  89. // Did the user explicitly specify a config file?
  90. if ($config = drush_get_option(array('c', 'config'))) {
  91. if (is_dir($config)) {
  92. $config = $config . '/drushrc.php';
  93. }
  94. $configs['custom'] = $config;
  95. }
  96. if ($site_path = drush_get_context('DRUSH_DRUPAL_SITE_ROOT')) {
  97. $configs['site'] = $site_path . "/drushrc.php";
  98. }
  99. if ($drupal_root = drush_get_context('DRUSH_DRUPAL_ROOT')) {
  100. $configs['drupal'] = $drupal_root . '/drushrc.php';
  101. }
  102. // in the user home directory
  103. if (!is_null(drush_server_home())) {
  104. $configs['user'] = drush_server_home() . '/.drushrc.php';
  105. }
  106. // in $HOME/.drush directory
  107. if (!is_null(drush_server_home())) {
  108. $configs['home.drush'] = drush_server_home() . '/.drush/drushrc.php';
  109. }
  110. // In the system wide configuration folder.
  111. $configs['system'] = drush_get_context('ETC_PREFIX', '') . '/etc/drush/drushrc.php';
  112. // in the drush installation folder
  113. $configs['drush'] = dirname(__FILE__) . '/../drushrc.php';
  114. return empty($configs[$context]) ? '' : $configs[$context];
  115. }
  116. /**
  117. * Load drushrc files (if available) from several possible locations.
  118. */
  119. function drush_load_config($context) {
  120. drush_load_config_file($context, _drush_config_file($context));
  121. }
  122. function drush_load_config_file($context, $config) {
  123. if (file_exists($config)) {
  124. $options = $aliases = $command_specific = $override = array();
  125. drush_log(dt('Loading drushrc "!config" into "!context" scope.', array('!config' => realpath($config), '!context' => $context)), 'bootstrap');
  126. $ret = @include_once($config);
  127. if ($ret === FALSE) {
  128. drush_log(dt('Cannot open drushrc "!config", ignoring.', array('!config' => realpath($config))), 'warning');
  129. return FALSE;
  130. }
  131. if (!empty($options) || !empty($aliases) || !empty($command_specific)) {
  132. $options = array_merge(drush_get_context($context), $options);
  133. $options['config-file'] = realpath($config);
  134. //$options['site-aliases'] = array_merge(isset($aliases) ? $aliases : array(), isset($options['site-aliases']) ? $options['site-aliases'] : array());
  135. unset($options['site-aliases']);
  136. $options['command-specific'] = array_merge(isset($command_specific) ? $command_specific : array(), isset($options['command-specific']) ? $options['command-specific'] : array());
  137. drush_set_config_options($context, $options, $override);
  138. }
  139. }
  140. }
  141. function drush_set_config_options($context, $options, $override = array()) {
  142. global $drush_conf_override;
  143. // Only reset $drush_conf_override if the array is not set, otherwise keep old values and append new values to it.
  144. if (!isset($drush_conf_override)) {
  145. $drush_conf_override = array();
  146. }
  147. // Copy 'config-file' into 'context-path', converting to an array to hold multiple values if necessary
  148. if (isset($options['config-file'])) {
  149. if (isset($options['context-path'])) {
  150. $options['context-path'] = array_merge(array($options['config-file']), is_array($options['context-path']) ? $options['context-path'] : array($options['context-path']));
  151. }
  152. else {
  153. $options['context-path'] = $options['config-file'];
  154. }
  155. }
  156. // Take out $aliases and $command_specific options
  157. drush_set_config_special_contexts($options);
  158. drush_set_context($context, $options);
  159. // Instruct core not to store queries since we are not outputting them.
  160. // This can be overridden by a command or a drushrc file if needed.
  161. if (!isset($drush_conf_override['dev_query'])) {
  162. $drush_conf_override['dev_query'] = FALSE;
  163. }
  164. /**
  165. * Allow the drushrc.php file to override $conf settings.
  166. * This is a separate variable because the $conf array gets
  167. * initialized to an empty array, in the drupal bootstrap process,
  168. * and changes in settings.php would wipe out the drushrc.php settings.
  169. */
  170. if (!empty($override)) {
  171. $drush_conf_override = array_merge($drush_conf_override, $override);
  172. }
  173. }
  174. /**
  175. * There are certain options such as 'site-aliases' and 'command-specific'
  176. * that must be merged together if defined in multiple drush configuration
  177. * files. If we did not do this merge, then the last configuration file
  178. * that defined any of these properties would overwrite all of the options
  179. * that came before in previously-loaded configuration files. We place
  180. * all of them into their own context so that this does not happen.
  181. */
  182. function drush_set_config_special_contexts(&$options) {
  183. if (isset($options)) {
  184. $has_command_specific = array_key_exists('command-specific', $options);
  185. // Change the keys of the site aliases from 'alias' to '@alias'
  186. if (array_key_exists('site-aliases', $options)) {
  187. $user_aliases = $options['site-aliases'];
  188. $options['site-aliases'] = array();
  189. foreach ($user_aliases as $alias_name => $alias_value) {
  190. if (substr($alias_name,0,1) != '@') {
  191. $alias_name = "@$alias_name";
  192. }
  193. $options['site-aliases'][$alias_name] = $alias_value;
  194. }
  195. }
  196. // Copy site aliases and command-specific options into their
  197. // appropriate caches.
  198. foreach (array('site-aliases', 'command-specific') as $option_name) {
  199. if ((isset($options)) && (array_key_exists($option_name, $options))) {
  200. $cache =& drush_get_context($option_name);
  201. $cache = array_merge($cache, $options[$option_name]);
  202. unset($options[$option_name]);
  203. }
  204. }
  205. // If command-specific options were set and if we already have
  206. // a command, then apply the command-specific options immediately.
  207. if ($has_command_specific) {
  208. drush_command_default_options();
  209. }
  210. }
  211. }
  212. /**
  213. * Set a specific context.
  214. *
  215. * @param context
  216. * Any of the default defined contexts.
  217. * @param value
  218. * The value to store in the context
  219. *
  220. * @return
  221. * An associative array of the settings specified in the request context.
  222. */
  223. function drush_set_context($context, $value) {
  224. $cache =& drush_get_context($context);
  225. $cache = $value;
  226. return $value;
  227. }
  228. /**
  229. * Return a specific context, or the whole context cache
  230. *
  231. * This function provides a storage mechanism for any information
  232. * the currently running process might need to communicate.
  233. *
  234. * This avoids the use of globals, and constants.
  235. *
  236. * Functions that operate on the context cache, can retrieve a reference
  237. * to the context cache using :
  238. * $cache = &drush_get_context($context);
  239. *
  240. * This is a private function, because it is meant as an internal
  241. * generalized API for writing static cache functions, not as a general
  242. * purpose function to be used inside commands.
  243. *
  244. * Code that modifies the reference directly might have unexpected consequences,
  245. * such as modifying the arguments after they have already been parsed and dispatched
  246. * to the callbacks.
  247. *
  248. * @param context
  249. * Optional. Any of the default defined contexts.
  250. *
  251. * @return
  252. * If context is not supplied, the entire context cache will be returned.
  253. * Otherwise only the requested context will be returned.
  254. * If the context does not exist yet, it will be initialized to an empty array.
  255. */
  256. function &drush_get_context($context = null, $default = null) {
  257. static $cache = array();
  258. if (!is_null($context)) {
  259. if (!isset($cache[$context])) {
  260. $default = !is_null($default) ? $default : array();
  261. $cache[$context] = $default;
  262. }
  263. return $cache[$context];
  264. }
  265. return $cache;
  266. }
  267. /**
  268. * Set the arguments passed to the drush.php script.
  269. *
  270. * This function will set the 'arguments' context of the current running script.
  271. *
  272. * When initially called by drush_parse_options, the entire list of arguments will
  273. * be populated, once the command is dispatched, this will be set to only the remaining
  274. * arguments to the command.
  275. *
  276. * @param arguments
  277. * Command line arguments, as an array.
  278. */
  279. function drush_set_arguments($arguments) {
  280. drush_set_context('arguments', $arguments);
  281. }
  282. /**
  283. * Get the arguments passed to the drush.php script.
  284. *
  285. * When drush_set_arguments is initially called by drush_parse_options,
  286. * the entire list of arguments will be populated.
  287. * Once the command has been dispatched, this will be return only the remaining
  288. * arguments to the command.
  289. */
  290. function drush_get_arguments() {
  291. return drush_get_context('arguments');
  292. }
  293. /**
  294. * Set the command being executed.
  295. *
  296. * Drush_dispatch will set the correct command based on it's
  297. * matching of the script arguments retrieved from drush_get_arguments
  298. * to the implemented commands specified by drush_get_commands.
  299. *
  300. * @param
  301. * A numerically indexed array of command components.
  302. */
  303. function drush_set_command($command) {
  304. drush_set_context('command', $command);
  305. }
  306. /**
  307. * Return the command being executed.
  308. *
  309. *
  310. */
  311. function drush_get_command() {
  312. return drush_get_context('command');
  313. }
  314. /**
  315. * Get the value for an option.
  316. *
  317. * If the first argument is an array, then it checks whether one of the options
  318. * exists and return the value of the first one found. Useful for allowing both
  319. * -h and --host-name
  320. *
  321. * @param option
  322. * The name of the option to get
  323. * @param default
  324. * Optional. The value to return if the option has not been set
  325. * @param context
  326. * Optional. The context to check for the option. If this is set, only this context will be searched.
  327. */
  328. function drush_get_option($option, $default = NULL, $context = NULL) {
  329. $value = null;
  330. if ($context) {
  331. // We have a definite context to check for the presence of an option.
  332. $value = _drush_get_option($option, drush_get_context($context));
  333. }
  334. else {
  335. // We are not checking a specific context, so check them in a predefined order of precedence.
  336. $contexts = drush_context_names();
  337. foreach ($contexts as $context) {
  338. $value = _drush_get_option($option, drush_get_context($context));
  339. if ($value !== null) {
  340. return $value;
  341. }
  342. }
  343. }
  344. if ($value !== null) {
  345. return $value;
  346. }
  347. return $default;
  348. }
  349. /**
  350. * Get the value for an option, but first checks the provided option overrides.
  351. *
  352. * The feature of drush_get_option that allows a list of option names
  353. * to be passed in an array is NOT supported.
  354. *
  355. * @param option_overrides
  356. * An array to check for values before calling drush_get_option.
  357. * @param option
  358. * The name of the option to get.
  359. * @param default
  360. * Optional. The value to return if the option has not been set.
  361. * @param context
  362. * Optional. The context to check for the option. If this is set, only this context will be searched.
  363. *
  364. */
  365. function drush_get_option_override($option_overrides, $option, $value = NULL, $context = NULL) {
  366. if (array_key_exists($option, $option_overrides)) {
  367. return $option_overrides[$option];
  368. }
  369. else {
  370. return drush_get_option($option, $value, $context);
  371. }
  372. }
  373. /**
  374. * Get all of the values for an option in every context.
  375. *
  376. * @param option
  377. * The name of the option to get
  378. * @return
  379. * An array whose key is the context name and value is
  380. * the specific value for the option in that context.
  381. */
  382. function drush_get_context_options($option, $flatten = FALSE) {
  383. $result = array();
  384. $contexts = drush_context_names();
  385. foreach ($contexts as $context) {
  386. $value = _drush_get_option($option, drush_get_context($context));
  387. if ($value !== null) {
  388. if ($flatten && is_array($value)) {
  389. $result = array_merge($value, $result);
  390. }
  391. else {
  392. $result[$context] = $value;
  393. }
  394. }
  395. }
  396. return $result;
  397. }
  398. /**
  399. * Retrieves a collapsed list of all options
  400. */
  401. function drush_get_merged_options() {
  402. $contexts = drush_context_names();
  403. $cache = drush_get_context();
  404. $result = array();
  405. foreach (array_reverse($contexts) as $context) {
  406. if (array_key_exists($context, $cache)) {
  407. $result = array_merge($result, $cache[$context]);
  408. }
  409. }
  410. return $result;
  411. }
  412. /**
  413. * Helper function to recurse through possible option names
  414. */
  415. function _drush_get_option($option, $context) {
  416. if (is_array($option)) {
  417. foreach ($option as $current) {
  418. if (array_key_exists($current, $context)) {
  419. return $context[$current];
  420. }
  421. }
  422. }
  423. elseif (array_key_exists($option, $context)) {
  424. return $context[$option];
  425. }
  426. return null;
  427. }
  428. /**
  429. * Set an option in one of the option contexts.
  430. *
  431. * @param option
  432. * The option to set.
  433. * @param value
  434. * The value to set it to.
  435. * @param context
  436. * Optional. Which context to set it in.
  437. * @return
  438. * The value parameter. This allows for neater code such as
  439. * $myvalue = drush_set_option('http_host', $_SERVER['HTTP_HOST']);
  440. * Without having to constantly type out the value parameter.
  441. */
  442. function drush_set_option($option, $value, $context = 'process') {
  443. $cache =& drush_get_context($context);
  444. $cache[$option] = $value;
  445. return $value;
  446. }
  447. /**
  448. * A small helper function to set the value in the default context
  449. */
  450. function drush_set_default($option, $value) {
  451. return drush_set_option($option, $value, 'default');
  452. }
  453. /**
  454. * Remove a setting from a specific context.
  455. *
  456. * @param
  457. * Option to be unset
  458. * @param
  459. * Context in which to unset the value in.
  460. */
  461. function drush_unset_option($option, $context = NULL) {
  462. if ($context != NULL) {
  463. $cache =& drush_get_context($context);
  464. if (array_key_exists($option, $cache)) {
  465. unset($cache[$option]);
  466. }
  467. }
  468. else {
  469. $contexts = drush_context_names();
  470. foreach ($contexts as $context) {
  471. drush_unset_option($option, $context);
  472. }
  473. }
  474. }
  475. /**
  476. * Save the settings in a specific context to the applicable configuration file
  477. * This is useful is you want certain settings to be available automatically the next time a command is executed.
  478. *
  479. * @param $context
  480. * The context to save
  481. */
  482. function drush_save_config($context) {
  483. $filename = _drush_config_file($context);
  484. if ($filename) {
  485. $cache = drush_get_context($context);
  486. $fp = fopen($filename, "w+");
  487. if (!$fp) {
  488. return drush_set_error('DRUSH_PERM_ERROR', dt('Drushrc (!filename) could not be written', array('!filename' => $filename)));
  489. }
  490. else {
  491. fwrite($fp, "<?php\n");
  492. $timestamp = mktime();
  493. foreach ($cache as $key => $value) {
  494. $line = "\n\$options['$key'] = ". var_export($value, TRUE) .';';
  495. fwrite($fp, $line);
  496. }
  497. fwrite($fp, "\n");
  498. fclose($fp);
  499. drush_log(dt('Drushrc file (!filename) was written successfully', array('!filename' => $filename)));
  500. return true;
  501. }
  502. }
  503. return false;
  504. }