Version 1
[yaffs-website] / vendor / consolidation / output-formatters / src / Options / FormatterOptions.php
1 <?php
2 namespace Consolidation\OutputFormatters\Options;
3
4 use Symfony\Component\Console\Input\InputInterface;
5 use Consolidation\OutputFormatters\Transformations\PropertyParser;
6 use Consolidation\OutputFormatters\StructuredData\Xml\XmlSchema;
7 use Consolidation\OutputFormatters\StructuredData\Xml\XmlSchemaInterface;
8
9 /**
10  * FormetterOptions holds information that affects the way a formatter
11  * renders its output.
12  *
13  * There are three places where a formatter might get options from:
14  *
15  * 1. Configuration associated with the command that produced the output.
16  *    This is passed in to FormatterManager::write() along with the data
17  *    to format.  It might originally come from annotations on the command,
18  *    or it might come from another source.  Examples include the field labels
19  *    for a table, or the default list of fields to display.
20  *
21  * 2. Options specified by the user, e.g. by commandline options.
22  *
23  * 3. Default values associated with the formatter itself.
24  *
25  * This class caches configuration from sources (1) and (2), and expects
26  * to be provided the defaults, (3), whenever a value is requested.
27  */
28 class FormatterOptions
29 {
30     /** var array */
31     protected $configurationData = [];
32     /** var array */
33     protected $options = [];
34     /** var InputInterface */
35     protected $input;
36
37     const FORMAT = 'format';
38     const DEFAULT_FORMAT = 'default-format';
39     const TABLE_STYLE = 'table-style';
40     const LIST_ORIENTATION = 'list-orientation';
41     const FIELDS = 'fields';
42     const FIELD = 'field';
43     const INCLUDE_FIELD_LABELS = 'include-field-labels';
44     const ROW_LABELS = 'row-labels';
45     const FIELD_LABELS = 'field-labels';
46     const DEFAULT_FIELDS = 'default-fields';
47     const DEFAULT_STRING_FIELD = 'default-string-field';
48     const DELIMITER = 'delimiter';
49     const LIST_DELIMITER = 'list-delimiter';
50     const TERMINAL_WIDTH = 'width';
51
52     /**
53      * Create a new FormatterOptions with the configuration data and the
54      * user-specified options for this request.
55      *
56      * @see FormatterOptions::setInput()
57      * @param array $configurationData
58      * @param array $options
59      */
60     public function __construct($configurationData = [], $options = [])
61     {
62         $this->configurationData = $configurationData;
63         $this->options = $options;
64     }
65
66     /**
67      * Create a new FormatterOptions object with new configuration data (provided),
68      * and the same options data as this instance.
69      *
70      * @param array $configurationData
71      * @return FormatterOptions
72      */
73     public function override($configurationData)
74     {
75         $override = new self();
76         $override
77             ->setConfigurationData($configurationData + $this->getConfigurationData())
78             ->setOptions($this->getOptions());
79         return $override;
80     }
81
82     public function setTableStyle($style)
83     {
84         return $this->setConfigurationValue(self::TABLE_STYLE, $style);
85     }
86
87     public function setDelimiter($delimiter)
88     {
89         return $this->setConfigurationValue(self::DELIMITER, $delimiter);
90     }
91
92     public function setListDelimiter($listDelimiter)
93     {
94         return $this->setConfigurationValue(self::LIST_DELIMITER, $listDelimiter);
95     }
96
97
98
99     public function setIncludeFieldLables($includFieldLables)
100     {
101         return $this->setConfigurationValue(self::INCLUDE_FIELD_LABELS, $includFieldLables);
102     }
103
104     public function setListOrientation($listOrientation)
105     {
106         return $this->setConfigurationValue(self::LIST_ORIENTATION, $listOrientation);
107     }
108
109     public function setRowLabels($rowLabels)
110     {
111         return $this->setConfigurationValue(self::ROW_LABELS, $rowLabels);
112     }
113
114     public function setDefaultFields($fields)
115     {
116         return $this->setConfigurationValue(self::DEFAULT_FIELDS, $fields);
117     }
118
119     public function setFieldLabels($fieldLabels)
120     {
121         return $this->setConfigurationValue(self::FIELD_LABELS, $fieldLabels);
122     }
123
124     public function setDefaultStringField($defaultStringField)
125     {
126         return $this->setConfigurationValue(self::DEFAULT_STRING_FIELD, $defaultStringField);
127     }
128
129     public function setWidth($width)
130     {
131         return $this->setConfigurationValue(self::TERMINAL_WIDTH, $width);
132     }
133
134     /**
135      * Get a formatter option
136      *
137      * @param string $key
138      * @param array $defaults
139      * @param mixed $default
140      * @return mixed
141      */
142     public function get($key, $defaults = [], $default = false)
143     {
144         $value = $this->fetch($key, $defaults, $default);
145         return $this->parse($key, $value);
146     }
147
148     /**
149      * Return the XmlSchema to use with --format=xml for data types that support
150      * that.  This is used when an array needs to be converted into xml.
151      *
152      * @return XmlSchema
153      */
154     public function getXmlSchema()
155     {
156         return new XmlSchema();
157     }
158
159     /**
160      * Determine the format that was requested by the caller.
161      *
162      * @param array $defaults
163      * @return string
164      */
165     public function getFormat($defaults = [])
166     {
167         return $this->get(self::FORMAT, [], $this->get(self::DEFAULT_FORMAT, $defaults, ''));
168     }
169
170     /**
171      * Look up a key, and return its raw value.
172      *
173      * @param string $key
174      * @param array $defaults
175      * @param mixed $default
176      * @return mixed
177      */
178     protected function fetch($key, $defaults = [], $default = false)
179     {
180         $defaults = $this->defaultsForKey($key, $defaults, $default);
181         $values = $this->fetchRawValues($defaults);
182         return $values[$key];
183     }
184
185     /**
186      * Reduce provided defaults to the single item identified by '$key',
187      * if it exists, or an empty array otherwise.
188      *
189      * @param string $key
190      * @param array $defaults
191      * @return array
192      */
193     protected function defaultsForKey($key, $defaults, $default = false)
194     {
195         if (array_key_exists($key, $defaults)) {
196             return [$key => $defaults[$key]];
197         }
198         return [$key => $default];
199     }
200
201     /**
202      * Look up all of the items associated with the provided defaults.
203      *
204      * @param array $defaults
205      * @return array
206      */
207     protected function fetchRawValues($defaults = [])
208     {
209         return array_merge(
210             $defaults,
211             $this->getConfigurationData(),
212             $this->getOptions(),
213             $this->getInputOptions($defaults)
214         );
215     }
216
217     /**
218      * Given the raw value for a specific key, do any type conversion
219      * (e.g. from a textual list to an array) needed for the data.
220      *
221      * @param string $key
222      * @param mixed $value
223      * @return mixed
224      */
225     protected function parse($key, $value)
226     {
227         $optionFormat = $this->getOptionFormat($key);
228         if (!empty($optionFormat) && is_string($value)) {
229             return $this->$optionFormat($value);
230         }
231         return $value;
232     }
233
234     /**
235      * Convert from a textual list to an array
236      *
237      * @param string $value
238      * @return array
239      */
240     public function parsePropertyList($value)
241     {
242         return PropertyParser::parse($value);
243     }
244
245     /**
246      * Given a specific key, return the class method name of the
247      * parsing method for data stored under this key.
248      *
249      * @param string $key
250      * @return string
251      */
252     protected function getOptionFormat($key)
253     {
254         $propertyFormats = [
255             self::ROW_LABELS => 'PropertyList',
256             self::FIELD_LABELS => 'PropertyList',
257         ];
258         if (array_key_exists($key, $propertyFormats)) {
259             return "parse{$propertyFormats[$key]}";
260         }
261         return '';
262     }
263
264     /**
265      * Change the configuration data for this formatter options object.
266      *
267      * @param array $configurationData
268      * @return FormatterOptions
269      */
270     public function setConfigurationData($configurationData)
271     {
272         $this->configurationData = $configurationData;
273         return $this;
274     }
275
276     /**
277      * Change one configuration value for this formatter option.
278      *
279      * @param string $key
280      * @param mixed $value
281      * @return FormetterOptions
282      */
283     protected function setConfigurationValue($key, $value)
284     {
285         $this->configurationData[$key] = $value;
286         return $this;
287     }
288
289     /**
290      * Change one configuration value for this formatter option, but only
291      * if it does not already have a value set.
292      *
293      * @param string $key
294      * @param mixed $value
295      * @return FormetterOptions
296      */
297     public function setConfigurationDefault($key, $value)
298     {
299         if (!array_key_exists($key, $this->configurationData)) {
300             return $this->setConfigurationValue($key, $value);
301         }
302         return $this;
303     }
304
305     /**
306      * Return a reference to the configuration data for this object.
307      *
308      * @return array
309      */
310     public function getConfigurationData()
311     {
312         return $this->configurationData;
313     }
314
315     /**
316      * Set all of the options that were specified by the user for this request.
317      *
318      * @param array $options
319      * @return FormatterOptions
320      */
321     public function setOptions($options)
322     {
323         $this->options = $options;
324         return $this;
325     }
326
327     /**
328      * Change one option value specified by the user for this request.
329      *
330      * @param string $key
331      * @param mixed $value
332      * @return FormatterOptions
333      */
334     public function setOption($key, $value)
335     {
336         $this->options[$key] = $value;
337         return $this;
338     }
339
340     /**
341      * Return a reference to the user-specified options for this request.
342      *
343      * @return array
344      */
345     public function getOptions()
346     {
347         return $this->options;
348     }
349
350     /**
351      * Provide a Symfony Console InputInterface containing the user-specified
352      * options for this request.
353      *
354      * @param InputInterface $input
355      * @return type
356      */
357     public function setInput(InputInterface $input)
358     {
359         $this->input = $input;
360     }
361
362     /**
363      * Return all of the options from the provided $defaults array that
364      * exist in our InputInterface object.
365      *
366      * @param array $defaults
367      * @return array
368      */
369     public function getInputOptions($defaults)
370     {
371         if (!isset($this->input)) {
372             return [];
373         }
374         $options = [];
375         foreach ($defaults as $key => $value) {
376             if ($this->input->hasOption($key)) {
377                 $result = $this->input->getOption($key);
378                 if (isset($result)) {
379                     $options[$key] = $this->input->getOption($key);
380                 }
381             }
382         }
383         return $options;
384     }
385 }