node_export.drush.inc 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. <?php
  2. /**
  3. * @file
  4. * Drush support for node_export.
  5. */
  6. /**
  7. * Implements hook_drush_command().
  8. */
  9. function node_export_drush_command() {
  10. $items = array();
  11. $items['node-export-export'] = array(
  12. 'callback' => 'drupal_node_export_callback_export',
  13. 'description' => "Export nodes using Node export.",
  14. 'arguments' => array(
  15. 'nids' => "A list of space-separated node IDs to export.",
  16. ),
  17. 'options' => array(
  18. 'file' => "The filename of the output file. If supplied, the node code will be exported to that file, otherwise it will export to stdout.",
  19. 'format' => "If supplied, node code will be output using a particular export format, if available. (e.g. serialize)",
  20. 'status' => "Filter for 'status'; A boolean value (0 or 1) indicating whether the node is published (visible to non-administrators).",
  21. 'promote' => "Filter for 'promote'; A boolean value (0 or 1) indicating whether the node should be displayed on the front page.",
  22. 'sticky' => "Filter for 'sticky'; A boolean value (0 or 1) indicating whether the node should be displayed at the top of lists in which it appears.",
  23. 'translate' => "Filter for 'translate'; A boolean value (0 or 1) indicating whether the node translation needs to be updated.",
  24. 'language' => "Filter for 'language'; The language code (e.g. de or en-US) of this node.",
  25. 'type' => "Filter for 'type'; The machine-readable name (e.g. story or page) of the type of this node.",
  26. 'sql' => "Filter by SQL (EXPERIMENTAL); An SQL query string that returns nids (e.g. \"SELECT nid FROM nodes WHERE nid < 10\").",
  27. 'code' => "Filter by PHP code (EXPERIMENTAL); PHP code that prints or returns, an array or CSV string of nids (e.g. \"custom_get_my_nids();\"). Don't include PHP tags.",
  28. ),
  29. 'examples' => array(
  30. 'drush node-export-export 45 46 47 --file=filename' =>
  31. "export nodes with node IDs 45, 46, and 47 to the file with the supplied filename.",
  32. 'drush node-export-export --type=story,page --file=filename' =>
  33. "export nodes of type story and page to the file with the supplied filename.",
  34. ),
  35. );
  36. $items['node-export-import'] = array(
  37. 'callback' => 'drush_node_export_callback_import',
  38. 'description' => "Import nodes previously exported with Node export.",
  39. 'options' => array(
  40. 'uid' => "User ID of user to save nodes as. If not given will use the user with an ID of 1. You may specify 0 for the Anonymous user.",
  41. 'file' => "The filename of the input file. If supplied, the node code will be imported from that file, otherwise it will import to stdin.",
  42. ),
  43. 'examples' => array(
  44. 'drush node-export-import --file=filename' =>
  45. 'Import nodes from the file with the given filename.',
  46. 'drush node-export-import --uid=2 --file=filename' =>
  47. "Import nodes from the file with the given filename. The author of the nodes will be set to the user that has the user ID of 2.",
  48. ),
  49. );
  50. // Add aliases for usability.
  51. node_export_drush_command_add_alias($items, 'node-export-export', 'node-export');
  52. node_export_drush_command_add_alias($items, 'node-export-export', 'ne-export');
  53. node_export_drush_command_add_alias($items, 'node-export-import', 'ne-import');
  54. return $items;
  55. }
  56. /**
  57. * A function to help alias commands as other commands.
  58. */
  59. function node_export_drush_command_add_alias(&$items, $command, $alias) {
  60. // Create a property on the command for adding aliases, if not there.
  61. if (!isset($items[$command]['node_export command aliases'])) {
  62. $items[$command]['node_export command aliases'] = array();
  63. }
  64. // Record the alias into that property.
  65. $items[$command]['node_export command aliases'][] = $alias;
  66. // Create the alias as a new command.
  67. $items[$alias] = $items[$command];
  68. // Indicate what this new command is an alias for.
  69. $items[$alias]['node_export alias for'] = $command;
  70. }
  71. /**
  72. * Implements hook_drush_help().
  73. *
  74. * This function is called whenever a drush user calls
  75. * 'drush help <name-of-your-command>'
  76. *
  77. * @param
  78. * A string with the help section (prepend with 'drush:')
  79. *
  80. * @return
  81. * A string with the help text for your command.
  82. */
  83. function node_export_drush_help($section) {
  84. // This is to prevent duplication of information from hook_drush_command().
  85. $commands = node_export_drush_command();
  86. foreach ($commands as $command => $command_info) {
  87. if ($section == 'drush:' . $command) {
  88. $out = $command_info['description'];
  89. if (isset($command_info['node_export alias for'])) {
  90. $output .= "\nThis command is an alias for ";
  91. $output .= $command_info['node_export alias for'] . ".";
  92. }
  93. if (isset($command_info['node_export command aliases'])) {
  94. if (count($command_info['node_export command aliases']) == 1) {
  95. $output .= "\nThis command can be called by it's alias; ";
  96. $output .= $command_info['node_export command aliases'] . ".";
  97. }
  98. else {
  99. $last_alias = array_pop($command_info['node_export command aliases']);
  100. $output .= "\nThis command can be called by it's aliases; ";
  101. $output .= implode(", ", $command_info['node_export command aliases']);
  102. $output .= ", or " . $last_alias . ".";
  103. }
  104. }
  105. $out .= "\n\nArguments:";
  106. if (isset($command_info['arguments'])) {
  107. foreach ($command_info['arguments'] as $k => $v) {
  108. $out .= "\n " . $k . " : " . $v;
  109. }
  110. }
  111. $out .= "\n\nOptions:";
  112. if (isset($command_info['options'])) {
  113. foreach ($command_info['options'] as $k => $v) {
  114. $out .= "\n " . $k . " : " . $v;
  115. }
  116. }
  117. $out .= "\n\nExamples:";
  118. if (isset($command_info['examples'])) {
  119. foreach ($command_info['examples'] as $k => $v) {
  120. $out .= "\n \'" . $k . "\' : " . $v;
  121. }
  122. }
  123. return dt($out);
  124. }
  125. }
  126. }
  127. /**
  128. * Drush command callback.
  129. *
  130. * export nodes.
  131. */
  132. function drupal_node_export_callback_export() {
  133. // Set up an array of nid_filters.
  134. $nid_filters = array();
  135. // The base nids.
  136. $args = array_filter(func_get_args(), 'is_numeric');
  137. if ($args) {
  138. $nid_filters['base'] = $args;
  139. }
  140. // Filter for values in the node table (except for nids).
  141. $filters = array(
  142. 'status',
  143. 'promote',
  144. 'sticky',
  145. 'translate',
  146. 'language',
  147. 'type',
  148. );
  149. $query = db_select('node', 'n')->fields('n', array('nid'));
  150. $execute = FALSE;
  151. foreach ($filters as $filter) {
  152. $filter_option = drush_get_option($filter);
  153. if ($filter_option) {
  154. $query->condition($filter, explode(',', $filter_option), 'IN');
  155. // Only execute if conditions are set.
  156. $execute = TRUE;
  157. }
  158. }
  159. if ($execute) {
  160. $result = $query->execute();
  161. foreach ($result as $row) {
  162. $nid_filters['filters'][] = $row->nid;
  163. }
  164. }
  165. // Handle SQL option.
  166. $sql = drush_get_option('sql');
  167. if ($sql) {
  168. $result = db_query($sql);
  169. foreach ($result as $row) {
  170. $nid_filters['sql'][] = $row->nid;
  171. }
  172. }
  173. // Handle PHP option.
  174. $code = drush_get_option('code');
  175. if ($code) {
  176. ob_start();
  177. print eval("?><?php " . $code . " ?>");
  178. $result = ob_get_contents();
  179. ob_end_clean();
  180. if (is_array($result)) {
  181. $nid_filters['code'] = $result;
  182. }
  183. else {
  184. $nid_filters['code'] = explode(
  185. ",",
  186. str_replace(array("\n", "\r", "\t", " "), '', $result)
  187. );
  188. }
  189. }
  190. if (count($nid_filters) > 1) {
  191. // Compute the intersect of all $nid_filters if there are more than one.
  192. $nids = call_user_func_array('array_intersect', $nid_filters);
  193. }
  194. elseif (count($nid_filters) == 1) {
  195. // Use the only filter if there is only one.
  196. $nids = reset($nid_filters);
  197. }
  198. else {
  199. // Is there are no filters at all, do a query to get all nids.
  200. $result = db_select('node', 'n')->fields('n', array('nid'))->execute();
  201. $nids = array();
  202. foreach ($result as $row) {
  203. $nids[] = $row->nid;
  204. }
  205. }
  206. // Handle format option.
  207. $format = drush_get_option('format');
  208. if (empty($nids)) {
  209. drush_set_error('DRUSH_NOT_COMPLETED', "No nodes found.");
  210. }
  211. $result = node_export($nids, $format, 'dt');
  212. if ($result['success']) {
  213. $filename = drush_get_option('file');
  214. if ($filename) {
  215. // Output data to file. Note this only takes a flat filename for the current directory.
  216. // If file exists, ask for whether to overwrite.
  217. if (file_exists($filename)) {
  218. if (!drush_confirm(dt("File $filename exists. Do you really want to overwrite?"))) {
  219. return;
  220. }
  221. }
  222. // Write the file.
  223. file_put_contents($filename, $result['output']);
  224. }
  225. else {
  226. // stdout.
  227. drush_print_r($result['output']);
  228. }
  229. }
  230. else {
  231. // We have received an error message.
  232. drush_set_error('DRUSH_NOT_COMPLETED', strip_tags(implode("\n", $result['output'])));
  233. }
  234. }
  235. /**
  236. * Drush command callback.
  237. *
  238. * Import nodes from data.
  239. */
  240. function drush_node_export_callback_import() {
  241. // Switch to site maintenance account or the specified user so imported nodes are not anonymous.
  242. $uid = drush_get_option('uid');
  243. // Test on NULL so uid may be given as 0.
  244. if (is_null($uid)) {
  245. $uid = 1;
  246. }
  247. // User 0 is already loaded.
  248. if ($uid != 0) {
  249. global $user;
  250. $user = user_load($uid);
  251. }
  252. $filename = drush_get_option('file');
  253. if ($filename) {
  254. $node_code = file_get_contents($filename, "r");
  255. }
  256. else {
  257. $node_code = file_get_contents("php://stdin", "r");
  258. }
  259. if (!empty($node_code)) {
  260. $result = node_export_import($node_code, 'dt');
  261. if (!$result['success']) {
  262. // We have received an error message.
  263. drush_set_error('DRUSH_NOT_COMPLETED', strip_tags(implode("\n", $result['output'])));
  264. }
  265. else {
  266. drush_print(strip_tags(implode("\n", $result['output'])));
  267. }
  268. }
  269. }