config_devel.drush.inc 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. <?php
  2. /**
  3. * @file
  4. * Configuration development module drush integration.
  5. */
  6. use Drupal\Core\Config\InstallStorage;
  7. /**
  8. * Implements hook_drush_command().
  9. */
  10. function config_devel_drush_command() {
  11. $items = array();
  12. $description = '';
  13. $description .= "List which configuration settings you want to export in the\n";
  14. $description .= "module's info file by listing them under 'config_devel', as shown below:\n";
  15. $description .= "\n";
  16. $description .= "config_devel:\n";
  17. $description .= " install:\n";
  18. $description .= " - entity.view_display.node.article.default\n";
  19. $description .= " - entity.view_display.node.article.teaser\n";
  20. $description .= " - field.instance.node.article.body\n";
  21. $description .= " optional:\n";
  22. $description .= " - field.instance.node.article.tags\n";
  23. $items['config-devel-export'] = array(
  24. 'description' => "Write back configuration to module's config directory.\n" . $description,
  25. 'arguments' => array(
  26. 'module' => 'Module machine name.',
  27. ),
  28. 'options' => array(
  29. ),
  30. 'required-arguments' => TRUE,
  31. 'examples' => array(
  32. 'drush config-devel-export MODULE_NAME' => 'Write back configuration to the specified module, based on .info file.',
  33. ),
  34. 'aliases' => array('cde', 'cd-em'),
  35. );
  36. $items['config-devel-import'] = array(
  37. 'description' => "Import configuration from module's config directory to active storage.\n" . $description,
  38. 'arguments' => array(
  39. 'module' => 'Module machine name.',
  40. ),
  41. 'options' => array(
  42. ),
  43. 'required-arguments' => TRUE,
  44. 'examples' => array(
  45. 'drush config-devel-import MODULE_NAME' => 'Import configuration from the specified module into the active storage, based on .info file.',
  46. ),
  47. 'aliases' => array('cdi', 'cd-im'),
  48. );
  49. $items['config-devel-import-one'] = array(
  50. 'description' => "Import a single configuration item from module's config directory to active storage.\n" . $description,
  51. 'arguments' => array(
  52. 'path' => 'Config file name.',
  53. ),
  54. 'options' => array(
  55. ),
  56. 'required-arguments' => TRUE,
  57. 'examples' => array(
  58. 'drush config-devel-import-one system.site.yml' => 'Import the contents of system.site.yml into the config object system.site.',
  59. 'drush config-devel-import-one system.site' => 'Import the standard input into the config object system.site. Helpful for scripting copying to remote',
  60. ),
  61. 'aliases' => array('cdi1', 'cd-i1'),
  62. );
  63. return $items;
  64. }
  65. /**
  66. * Drush command callback.
  67. */
  68. function drush_config_devel_export($extension) {
  69. // Determine the type of extension we're dealing with.
  70. $type = drush_config_devel_get_type($extension);
  71. if ($type) {
  72. // Get the config
  73. $config = drush_config_devel_get_config($type, $extension);
  74. // Process config
  75. if (isset($config['install'])) {
  76. drush_config_devel_process_config($config['install'], $type, $extension, InstallStorage::CONFIG_INSTALL_DIRECTORY);
  77. }
  78. // If we have any optional configuration, process that as well.
  79. if (isset($config['optional'])) {
  80. drush_config_devel_process_config($config['optional'], $type, $extension, InstallStorage::CONFIG_OPTIONAL_DIRECTORY);
  81. }
  82. }
  83. else {
  84. drush_set_error("Couldn't export configuration. The '$extension' extension is not enabled.");
  85. }
  86. }
  87. /**
  88. * Drush command callback.
  89. */
  90. function drush_config_devel_import($extension) {
  91. // Determine the type of extension we're dealing with.
  92. $type = drush_config_devel_get_type($extension);
  93. if ($type) {
  94. // Get the config
  95. $config = drush_config_devel_get_config($type, $extension);
  96. // Import config
  97. if (isset($config['install'])) {
  98. drush_config_devel_import_config($config['install'], $type, $extension, InstallStorage::CONFIG_INSTALL_DIRECTORY);
  99. }
  100. // Import optional config
  101. if (isset($config['optional'])) {
  102. drush_config_devel_import_config($config['optional'], $type, $extension, InstallStorage::CONFIG_OPTIONAL_DIRECTORY);
  103. }
  104. }
  105. else {
  106. drush_set_error("Couldn't import configuration. The '$extension' extension is not enabled.");
  107. }
  108. }
  109. /**
  110. * Drush command callback.
  111. */
  112. function drush_config_devel_import_one($path) {
  113. $contents = '';
  114. if (!file_exists($path)) {
  115. if (substr($path, -4) != '.yml') {
  116. $contents = file_get_contents('php://stdin');
  117. }
  118. elseif (!empty($_SERVER['PWD'])) {
  119. $path = $_SERVER['PWD'] . '/' . trim($path, '/');
  120. }
  121. }
  122. if ($contents || file_exists($path)) {
  123. \Drupal::service('config_devel.auto_import_subscriber')->importOne($path, '', $contents);
  124. }
  125. else {
  126. drush_log("file '$path' not found", 'error');
  127. exit;
  128. }
  129. }
  130. /**
  131. * Exports a list of configuration entities.
  132. *
  133. * @param array $config_list
  134. * An array of configuration entities.
  135. * @param string $type
  136. * The type of extension we're exporting, one of module or theme.
  137. * @param string $extension
  138. * The module, theme or install profile we're exporting.
  139. * @param string $directory
  140. * The directory we're exporting to.
  141. *
  142. * @return bool
  143. * TRUE when the configuration was successfully exported. FALSE otherwise.
  144. */
  145. function drush_config_devel_process_config($config_list, $type, $extension, $directory) {
  146. $config_path = drupal_get_path($type, $extension) . "/$directory";
  147. // Ensure the directory always exists.
  148. if (!file_exists($config_path) && !\Drupal::service('file_system')->mkdir($config_path, NULL, TRUE)) {
  149. drush_set_error('CONFIG_DEVEL_DIRECTORY_NOT_CREATED', sprintf('The %s directory could not be created', $config_path));
  150. return FALSE;
  151. }
  152. foreach ($config_list as $name) {
  153. $config = \Drupal::config($name);
  154. $file_names = array($config_path . '/' . $name . '.yml');
  155. \Drupal::service('config_devel.writeback_subscriber')->writeBackConfig($config, $file_names);
  156. }
  157. return TRUE;
  158. }
  159. /**
  160. * Imports a list of configuration entities
  161. *
  162. * @param array $config_list
  163. * An array of configuration entities.
  164. * @param string $type
  165. * The type of extension we're exporting, one of module or theme.
  166. * @param string $extension
  167. * The module, theme or install profile we're exporting.
  168. * @param string $directory
  169. * The directory we're exporting to.
  170. */
  171. function drush_config_devel_import_config($config_list, $type, $extension, $directory) {
  172. $config_path = drupal_get_path($type, $extension) . "/$directory";
  173. foreach ($config_list as $name) {
  174. $file_name = $config_path . '/' . $name . '.yml';
  175. drush_config_devel_import_one($file_name);
  176. }
  177. }
  178. /**
  179. * Gets the config.
  180. *
  181. * @param string $type
  182. * module, theme or profile
  183. * @param string $extension
  184. * extension name
  185. * @return array
  186. * An array containing install and optional config
  187. */
  188. function drush_config_devel_get_config($type, $extension) {
  189. $filename = drupal_get_path($type, $extension) . '/' . $extension .'.info.yml';
  190. $info = \Drupal::service('info_parser')->parse($filename);
  191. $config = array();
  192. if (isset($info['config_devel'])) {
  193. // Keep backwards compatibility for the old format. This has config names
  194. // listed directly beneath 'config_devel', rather than an intermediate level
  195. // for 'install' and 'optional'.
  196. // Detect the old format based on whether there's neither of these two keys.
  197. if (!isset($info['config_devel']['install']) && !isset($info['config_devel']['optional'])) {
  198. $info['config_devel']['install'] = $info['config_devel'];
  199. }
  200. $config['install'] = $info['config_devel']['install'];
  201. // If we have any optional configuration, fetch that as well.
  202. if (isset($info['config_devel']['optional'])) {
  203. $config['optional'] = $info['config_devel']['optional'];
  204. }
  205. }
  206. return $config;
  207. }
  208. /**
  209. * Gets the type for the given extension.
  210. *
  211. * @param string $extension
  212. * extension name
  213. * @return string
  214. * module, theme, profile, or FALSE if no valid extension provided.
  215. */
  216. function drush_config_devel_get_type($extension) {
  217. $type = NULL;
  218. if (\Drupal::moduleHandler()->moduleExists($extension)) {
  219. $type = 'module';
  220. }
  221. elseif (\Drupal::service('theme_handler')->themeExists($extension)) {
  222. $type = 'theme';
  223. }
  224. elseif (drupal_get_profile() === $extension) {
  225. $type = 'profile';
  226. }
  227. return $type;
  228. }