Yaffs site version 1.1
[yaffs-website] / vendor / drush / drush / commands / core / outputformat.drush.inc
1 <?php
2
3 /**
4  * @file
5  *   Core drush output formats.
6  */
7
8 /**
9  * @return drush_outputformat The selected output format engine
10  */
11 function drush_get_outputformat() {
12   return drush_get_engine('outputformat');
13 }
14
15 /**
16  * Dynamically switch to a new output format.  Does NOT override
17  * user-selected output format.
18  */
19 function drush_set_default_outputformat($format, $metadata = array()) {
20   $command = drush_get_command();
21   $command['engines']['outputformat']['default'] = $format;
22   $outputformat = drush_load_command_engine($command, 'outputformat', $metadata);
23 }
24
25 /**
26  * Given a command name or a command record, return the
27  * command formatter that is used to process that command's output.
28  */
29 function drush_get_command_format_metadata($command, $metadata = array()) {
30   $commands = drush_get_commands();
31   if (!is_array($command) && array_key_exists($command, $commands)) {
32     $command = $commands[$command];
33   }
34   return drush_get_command_engine_config($command, 'outputformat', $metadata);
35 }
36
37 /**
38  * Implementation of hook_drush_engine_type_info().
39  */
40 function outputformat_drush_engine_type_info() {
41   $info = array();
42   $info['outputformat'] = array(
43     'description' => 'Output formatting options selection and use.',
44     'topic' => 'docs-output-formats',
45     'topic-file' => 'docs/output-formats.md',
46     'combine-help' => TRUE,
47     'option' => 'format',
48     'options' => array(
49       'format' => array(
50         'description' => 'Select output format.',
51         'example-value' => 'json',
52       ),
53       'fields' => array(
54         'description' => 'Fields to output.',
55         'example-value' => 'field1,field2',
56         'value' => 'required',
57         'list' => TRUE,
58       ),
59       'list-separator' => array(
60         'description' => 'Specify how elements in a list should be separated. In lists of lists, this applies to the elements in the inner lists.',
61         'hidden' => TRUE,
62       ),
63       'line-separator' => array(
64         'description' => 'In nested lists of lists, specify how the outer lists ("lines") should be separated.',
65         'hidden' => TRUE,
66       ),
67       'field-labels' => array(
68         'description' => 'Add field labels before first line of data. Default is on; use --no-field-labels to disable.',
69         'default' => '1',
70         'key' => 'include-field-labels',
71       ),
72     ),
73     // Allow output formats to declare their
74     // "output data type" instead of their
75     // "required engine capability" for readability.
76     'config-aliases' => array(
77       'output-data-type' => 'require-engine-capability',
78     ),
79   );
80   return $info;
81 }
82
83 /**
84  * Implements hook_drush_engine_ENGINE_TYPE().
85  *
86  * The output format types supported are represented by
87  * the 'engine-capabilities' of the output format engine.
88  * The different capabilities include:
89  *
90  * format-single:       A simple string.
91  *
92  * format-list:         An associative array where the key
93  *                      is usually the row label, and the value
94  *                      is a simple string.  Some list formatters
95  *                      render the label, and others (like
96  *                      "list" and "csv") throw it away.
97  *
98  * format-table:        An associative array, where the key
99  *                      is the row id, and the value is the
100  *                      column data.  The column data is also
101  *                      an associative array where the key
102  *                      is the column id and the value is the
103  *                      cell data.  The cell data should usually
104  *                      be a simple string; however, some
105  *                      formatters can recursively format their
106  *                      cell contents before rendering (e.g. if
107  *                      a cell contains a list of items in an array).
108  *
109  * These definitions align with the declared 'output-data-type'
110  * declared in command records.  @see drush_parse_command().
111  *
112  * Any output format that does not declare any engine capabilities
113  * is expected to be able to render any php data structure that is
114  * passed to it.
115  */
116 function outputformat_drush_engine_outputformat() {
117   $common_topic_example = array(
118     "a" => array("b" => 2, "c" => 3),
119     "d" => array("e" => 5, "f" => 6)
120   );
121
122   $engines = array();
123   $engines['table'] = array(
124     'description' => 'A formatted, word-wrapped table.',
125     'engine-capabilities' => array('format-table'),
126   );
127   $engines['key-value'] = array(
128     'description' => 'A formatted list of key-value pairs.',
129     'engine-capabilities' => array('format-single', 'format-list', 'format-table'),
130     'hidden' => TRUE,
131   );
132   $engines['key-value-list'] = array(
133     'implemented-by' => 'list',
134     'list-item-type' => 'key-value',
135     'description' => 'A list of formatted lists of key-value pairs.',
136     'list-field-selection-control' => 1,
137     'engine-capabilities' => array('format-table'),
138     'hidden' => TRUE,
139   );
140   $engines['json'] = array(
141     'machine-parsable' => TRUE,
142     'description' => 'Javascript Object Notation.',
143     'topic-example' => $common_topic_example,
144   );
145   $engines['string'] = array(
146     'machine-parsable' => TRUE,
147     'description' => 'A simple string.',
148     'engine-capabilities' => array('format-single'),
149   );
150   $engines['message'] = array(
151     'machine-parsable' => FALSE, // depends on the label....
152     'hidden' => TRUE,
153   );
154   $engines['print-r'] = array(
155     'machine-parsable' => TRUE,
156     'description' => 'Output via php print_r function.',
157     'verbose-only' => TRUE,
158     'topic-example' => $common_topic_example,
159   );
160   $engines['var_export'] = array(
161     'machine-parsable' => TRUE,
162     'description' => 'An array in executable php format.',
163     'topic-example' => $common_topic_example,
164   );
165   $engines['yaml'] = array(
166     'machine-parsable' => TRUE,
167     'description' => 'Yaml output format.',
168     'topic-example' => $common_topic_example,
169   );
170   $engines['php'] = array(
171     'machine-parsable' => TRUE,
172     'description' => 'A serialized php string.',
173     'verbose-only' => TRUE,
174     'topic-example' => $common_topic_example,
175   );
176   $engines['config'] = array(
177     'machine-parsable' => TRUE,
178     'implemented-by' => 'list',
179     'list-item-type' => 'var_export',
180     'description' => "A configuration file in executable php format. The variable name is \"config\", and the variable keys are taken from the output data array's keys.",
181     'metadata' => array(
182       'variable-name' => 'config',
183     ),
184     'list-field-selection-control' => -1,
185     'engine-capabilities' => array('format-list','format-table'),
186     'verbose-only' => TRUE,
187   );
188   $engines['list'] = array(
189     'machine-parsable' => TRUE,
190     'list-item-type' => 'string',
191     'description' => 'A simple list of values.',
192     // When a table is printed as a list, only the array keys of the rows will print.
193     'engine-capabilities' => array('format-list', 'format-table'),
194     'topic-example' => array('a', 'b', 'c'),
195   );
196   $engines['nested-csv'] = array(
197     'machine-parsable' => TRUE,
198     'implemented-by' => 'list',
199     'list-separator' => ',',
200     'list-item-type' => 'csv-or-string',
201     'hidden' => TRUE,
202   );
203   $engines['csv-or-string'] = array(
204     'machine-parsable' => TRUE,
205     'hidden' => TRUE,
206   );
207   $engines['csv'] = array(
208     'machine-parsable' => TRUE,
209     'implemented-by' => 'list',
210     'list-item-type' => 'nested-csv',
211     'labeled-list' => TRUE,
212     'description' => 'A list of values, one per row, each of which is a comma-separated list of values.',
213     'engine-capabilities' => array('format-table'),
214     'topic-example' => array(array('a', 12, 'a@one.com'),array('b', 17, 'b@two.com')),
215   );
216   $engines['variables'] = array(
217     'machine-parsable' => TRUE,
218     'description' => 'A list of php variable assignments.',
219     'engine-capabilities' => array('format-table'),
220     'verbose-only' => TRUE,
221     'list-field-selection-control' => -1,
222     'topic-example' => $common_topic_example,
223   );
224   $engines['labeled-export'] = array(
225     'machine-parsable' => TRUE,
226     'description' => 'A list of php exports, labeled with a name.',
227     'engine-capabilities' => array('format-table'),
228     'verbose-only' => TRUE,
229     'implemented-by' => 'list',
230     'list-item-type' => 'var_export',
231     'metadata' => array(
232       'label-template' => '!label: !value',
233     ),
234     'list-field-selection-control' => -1,
235     'topic-example' => $common_topic_example,
236   );
237   $engines['html'] = array(
238     'machine-parsable' => FALSE,
239     'description' => 'An HTML representation',
240     'engine-capabilities' => array('format-table'),
241   );
242   return $engines;
243 }
244
245 /**
246  * Implements hook_drush_command_alter
247  */
248 function outputformat_drush_command_alter(&$command) {
249   // In --pipe mode, change the default format to the default pipe format, or
250   // to json, if no default pipe format is given.
251   if (drush_get_context('DRUSH_PIPE') && (isset($command['engines']['outputformat']))) {
252     $default_format = isset($command['engines']['outputformat']['pipe-format']) ? $command['engines']['outputformat']['pipe-format'] : 'json';
253     $command['engines']['outputformat']['default'] = $default_format;
254   }
255 }
256
257 /**
258  * Implements hook_drush_help_alter().
259  */
260 function outputformat_drush_help_alter(&$command) {
261   if (isset($command['engines']['outputformat'])) {
262     $outputformat = $command['engines']['outputformat'];
263     // If the command defines specific field labels,
264     // then modify the help for --fields to include
265     // specific information about the available fields.
266     if (isset($outputformat['field-labels'])) {
267       $all_fields = array();
268       $all_fields_description = array();
269       foreach ($outputformat['field-labels'] as $field => $human_readable) {
270         $all_fields[] = $field;
271         if ((strtolower($field) != strtolower($human_readable)) && !array_key_exists(strtolower($human_readable), $outputformat['field-labels'])) {
272           $all_fields_description[] = $field . dt(" (or '!other')", array('!other' => strtolower($human_readable)));
273         }
274         else {
275           $all_fields_description[] = $field;
276         }
277       }
278       $field_defaults = isset($outputformat['fields-default']) ? $outputformat['fields-default'] : $all_fields;
279       $command['options']['fields']['example-value'] = implode(', ', $field_defaults);
280       $command['options']['fields']['description'] .= ' '. dt('All available fields are: !fields.', array('!fields' => implode(', ', $all_fields_description)));
281       if (isset($outputformat['fields-default'])) {
282         $command['options']['full']['description'] = dt("Show the full output, with all fields included.");
283       }
284     }
285     else {
286       // If the command does not define specific field labels,
287       // then hide the help for --fields unless the command
288       // uses output format engines that format tables.
289       if (isset($outputformat['require-engine-capability']) && is_array($outputformat['require-engine-capability'])) {
290         if (!in_array('format-table', $outputformat['require-engine-capability'])) {
291           unset($command['options']['fields']);
292           unset($command['options']['field-labels']);
293         }
294       }
295       // If the command does define output formats, but does not
296       // define fields, then just hide the help for the --fields option.
297       else {
298         $command['options']['fields']['hidden'] = TRUE;
299         $command['options']['field-labels']['hidden'] = TRUE;
300       }
301     }
302
303     // If the command defines a default pipe format, then
304     // add '--pipe   Equivalent to --format=<pipe-default>'.
305     if (isset($outputformat['pipe-format'])) {
306       if (isset($command['options']['pipe'])) {
307         $command['options']['pipe'] .= ' ';
308       }
309       else {
310         $command['options']['pipe'] = '';
311       }
312       if (isset($outputformat['pipe-metadata']['message-template'])) {
313         $command['options']['pipe'] .= dt('Displays output in the form "!message"', array('!message' => $outputformat['pipe-metadata']['message-template']));
314       }
315       else {
316         $command['options']['pipe'] .= dt("Equivalent to --format=!default.", array('!default' => $outputformat['pipe-format']));
317       }
318     }
319   }
320 }
321
322 /**
323  * Implements hook_drush_engine_topic_additional_text().
324  */
325 function outputformat_drush_engine_topic_additional_text($engine, $instance, $config) {
326   $result = array();
327
328   // If the output format engine has a 'topic-example' in
329   // its configuration, then format the provided array using
330   // the output formatter, and insert the result of the
331   // transform into the topic text.
332   if ($engine == 'outputformat') {
333     if (array_key_exists('topic-example', $config)) {
334       $code = $config['topic-example'];
335       $formatted = drush_format($code, array(), $instance);
336       $result[] = dt("Code:\n\nreturn !code;\n\nOutput with --format=!instance:\n\n!formatted", array('!code' => var_export($code, TRUE), '!instance' => $instance, '!formatted' => $formatted));
337     }
338   }
339
340   return $result;
341 }
342
343 /**
344  * Interface for output format engines.
345  */
346 class drush_outputformat {
347   function __construct($config) {
348     $config += array(
349       'column-widths' => array(),
350       'field-mappings' => array(),
351       'engine-info' => array(),
352     );
353     $config['engine-info'] += array(
354       'machine-parsable' => FALSE,
355       'metadata' => array(),
356     );
357     $config += $config['engine-info']['metadata'];
358     $this->engine_config = $config;
359   }
360   function format_error($message) {
361     return drush_set_error('DRUSH_FORMAT_ERROR', dt("The output data could not be processed by the selected format '!type'.  !message", array('!type' => $this->engine, '!message' => $message)));
362   }
363   function formatter_type() {
364     return $this->engine;
365   }
366   function is_list() {
367     return FALSE;
368   }
369   function formatter_is_simple_list() {
370     if (!isset($this->sub_engine)) {
371       return false;
372     }
373     return ($this->formatter_type() == 'list') && ($this->sub_engine->supports_single_only());
374   }
375   function data_type($metadata) {
376     if (isset($metadata['metameta']['require-engine-capability']) && is_array($metadata['metameta']['require-engine-capability'])) {
377       return  $metadata['metameta']['require-engine-capability'][0];
378     }
379     if (isset($metadata['require-engine-capability']) && is_array($metadata['require-engine-capability'])) {
380       return  $metadata['require-engine-capability'][0];
381     }
382     return 'unspecified';
383   }
384   function supported_data_types($metadata = NULL) {
385     if ($metadata == NULL) {
386       $metadata = $this->engine_config;
387     }
388     if (isset($metadata['metameta']['engine-info']['engine-capabilities'])) {
389       return  $metadata['metameta']['engine-info']['engine-capabilities'];
390     }
391     if (isset($metadata['engine-info']['engine-capabilities'])) {
392       return  $metadata['engine-info']['engine-capabilities'];
393     }
394     return array();
395   }
396   function supports_single_only($metadata = NULL) {
397     $supported = $this->supported_data_types($metadata);
398     return (count($supported) == 1) && ($supported[0] == 'format-single');
399   }
400   function get_info($key) {
401     if (array_key_exists($key, $this->engine_config)) {
402       return $this->engine_config[$key];
403     }
404     elseif (isset($this->sub_engine)) {
405       return $this->sub_engine->get_info($key);
406     }
407     return FALSE;
408   }
409   /**
410    * Perform pre-processing and then format() the $input.
411    */
412   function process($input, $metadata = array()) {
413     $metadata = array_merge_recursive($metadata, $this->engine_config);
414     if (isset($metadata['private-fields']) && is_array($input)) {
415       if (!drush_get_option('show-passwords', FALSE)) {
416         if (!is_array($metadata['private-fields'])) {
417           $metadata['private-fields'] = array($metadata['private-fields']);
418         }
419         foreach ($metadata['private-fields'] as $private) {
420           drush_unset_recursive($input, $private);
421         }
422       }
423     }
424     if (isset($metadata[$this->engine . '-metadata'])) {
425       $engine_specific_metadata = $metadata[$this->engine . '-metadata'];
426       unset($metadata[$this->engine . '-metadata']);
427       $metadata = array_merge($metadata, $engine_specific_metadata);
428     }
429     if ((drush_get_context('DRUSH_PIPE')) && (isset($metadata['pipe-metadata']))) {
430       $pipe_specific_metadata = $metadata['pipe-metadata'];
431       unset($metadata['pipe-metadata']);
432       $metadata = array_merge($metadata, $pipe_specific_metadata);
433     }
434     $machine_parsable = $this->engine_config['engine-info']['machine-parsable'];
435     $formatter_type = $machine_parsable ? 'parsable' : 'formatted';
436     if ((!$machine_parsable) && is_bool($input)) {
437       $input = $input ? 'TRUE' : 'FALSE';
438     }
439
440     // Run $input through any filters that are specified for this formatter.
441     if (isset($metadata[$formatter_type . '-filter'])) {
442       $filters = $metadata[$formatter_type . '-filter'];
443       if (!is_array($filters)) {
444         $filters = array($filters);
445       }
446       foreach ($filters as $filter) {
447         if (function_exists($filter)) {
448           $input = $filter($input, $metadata);
449         }
450       }
451     }
452     if (isset($metadata['field-labels'])) {
453       foreach (drush_hide_output_fields() as $hidden_field) {
454         unset($metadata['field-labels'][$hidden_field]);
455       }
456     }
457     return $this->format($input, $metadata);
458   }
459   function format($input, $metadata) {
460     return $input;
461   }
462 }
463
464 /**
465  * Specify that certain fields should not appear in the resulting output.
466  */
467 function drush_hide_output_fields($fields_to_hide = array()) {
468   $already_hidden = drush_get_context('DRUSH_HIDDEN_OUTPUT_FIELDS');
469   if (!is_array($fields_to_hide)) {
470     $fields_to_hide = array($fields_to_hide);
471   }
472   $result = array_merge($already_hidden, $fields_to_hide);
473   drush_set_context('DRUSH_HIDDEN_OUTPUT_FIELDS', $result);
474   return $result;
475 }