2 namespace Consolidation\OutputFormatters\Options;
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;
10 * FormetterOptions holds information that affects the way a formatter
13 * There are three places where a formatter might get options from:
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.
21 * 2. Options specified by the user, e.g. by commandline options.
23 * 3. Default values associated with the formatter itself.
25 * This class caches configuration from sources (1) and (2), and expects
26 * to be provided the defaults, (3), whenever a value is requested.
28 class FormatterOptions
31 protected $configurationData = [];
33 protected $options = [];
34 /** var InputInterface */
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 const METADATA_TEMPLATE = 'metadata-template';
54 * Create a new FormatterOptions with the configuration data and the
55 * user-specified options for this request.
57 * @see FormatterOptions::setInput()
58 * @param array $configurationData
59 * @param array $options
61 public function __construct($configurationData = [], $options = [])
63 $this->configurationData = $configurationData;
64 $this->options = $options;
68 * Create a new FormatterOptions object with new configuration data (provided),
69 * and the same options data as this instance.
71 * @param array $configurationData
72 * @return FormatterOptions
74 public function override($configurationData)
76 $override = new self();
78 ->setConfigurationData($configurationData + $this->getConfigurationData())
79 ->setOptions($this->getOptions());
83 public function setTableStyle($style)
85 return $this->setConfigurationValue(self::TABLE_STYLE, $style);
88 public function setDelimiter($delimiter)
90 return $this->setConfigurationValue(self::DELIMITER, $delimiter);
93 public function setListDelimiter($listDelimiter)
95 return $this->setConfigurationValue(self::LIST_DELIMITER, $listDelimiter);
100 public function setIncludeFieldLables($includFieldLables)
102 return $this->setConfigurationValue(self::INCLUDE_FIELD_LABELS, $includFieldLables);
105 public function setListOrientation($listOrientation)
107 return $this->setConfigurationValue(self::LIST_ORIENTATION, $listOrientation);
110 public function setRowLabels($rowLabels)
112 return $this->setConfigurationValue(self::ROW_LABELS, $rowLabels);
115 public function setDefaultFields($fields)
117 return $this->setConfigurationValue(self::DEFAULT_FIELDS, $fields);
120 public function setFieldLabels($fieldLabels)
122 return $this->setConfigurationValue(self::FIELD_LABELS, $fieldLabels);
125 public function setDefaultStringField($defaultStringField)
127 return $this->setConfigurationValue(self::DEFAULT_STRING_FIELD, $defaultStringField);
130 public function setWidth($width)
132 return $this->setConfigurationValue(self::TERMINAL_WIDTH, $width);
136 * Get a formatter option
139 * @param array $defaults
140 * @param mixed $default
143 public function get($key, $defaults = [], $default = false)
145 $value = $this->fetch($key, $defaults, $default);
146 return $this->parse($key, $value);
150 * Return the XmlSchema to use with --format=xml for data types that support
151 * that. This is used when an array needs to be converted into xml.
155 public function getXmlSchema()
157 return new XmlSchema();
161 * Determine the format that was requested by the caller.
163 * @param array $defaults
166 public function getFormat($defaults = [])
168 return $this->get(self::FORMAT, [], $this->get(self::DEFAULT_FORMAT, $defaults, ''));
172 * Look up a key, and return its raw value.
175 * @param array $defaults
176 * @param mixed $default
179 protected function fetch($key, $defaults = [], $default = false)
181 $defaults = $this->defaultsForKey($key, $defaults, $default);
182 $values = $this->fetchRawValues($defaults);
183 return $values[$key];
187 * Reduce provided defaults to the single item identified by '$key',
188 * if it exists, or an empty array otherwise.
191 * @param array $defaults
194 protected function defaultsForKey($key, $defaults, $default = false)
196 if (array_key_exists($key, $defaults)) {
197 return [$key => $defaults[$key]];
199 return [$key => $default];
203 * Look up all of the items associated with the provided defaults.
205 * @param array $defaults
208 protected function fetchRawValues($defaults = [])
212 $this->getConfigurationData(),
214 $this->getInputOptions($defaults)
219 * Given the raw value for a specific key, do any type conversion
220 * (e.g. from a textual list to an array) needed for the data.
223 * @param mixed $value
226 protected function parse($key, $value)
228 $optionFormat = $this->getOptionFormat($key);
229 if (!empty($optionFormat) && is_string($value)) {
230 return $this->$optionFormat($value);
236 * Convert from a textual list to an array
238 * @param string $value
241 public function parsePropertyList($value)
243 return PropertyParser::parse($value);
247 * Given a specific key, return the class method name of the
248 * parsing method for data stored under this key.
253 protected function getOptionFormat($key)
256 self::ROW_LABELS => 'PropertyList',
257 self::FIELD_LABELS => 'PropertyList',
259 if (array_key_exists($key, $propertyFormats)) {
260 return "parse{$propertyFormats[$key]}";
266 * Change the configuration data for this formatter options object.
268 * @param array $configurationData
269 * @return FormatterOptions
271 public function setConfigurationData($configurationData)
273 $this->configurationData = $configurationData;
278 * Change one configuration value for this formatter option.
281 * @param mixed $value
282 * @return FormetterOptions
284 protected function setConfigurationValue($key, $value)
286 $this->configurationData[$key] = $value;
291 * Change one configuration value for this formatter option, but only
292 * if it does not already have a value set.
295 * @param mixed $value
296 * @return FormetterOptions
298 public function setConfigurationDefault($key, $value)
300 if (!array_key_exists($key, $this->configurationData)) {
301 return $this->setConfigurationValue($key, $value);
307 * Return a reference to the configuration data for this object.
311 public function getConfigurationData()
313 return $this->configurationData;
317 * Set all of the options that were specified by the user for this request.
319 * @param array $options
320 * @return FormatterOptions
322 public function setOptions($options)
324 $this->options = $options;
329 * Change one option value specified by the user for this request.
332 * @param mixed $value
333 * @return FormatterOptions
335 public function setOption($key, $value)
337 $this->options[$key] = $value;
342 * Return a reference to the user-specified options for this request.
346 public function getOptions()
348 return $this->options;
352 * Provide a Symfony Console InputInterface containing the user-specified
353 * options for this request.
355 * @param InputInterface $input
358 public function setInput(InputInterface $input)
360 $this->input = $input;
364 * Return all of the options from the provided $defaults array that
365 * exist in our InputInterface object.
367 * @param array $defaults
370 public function getInputOptions($defaults)
372 if (!isset($this->input)) {
376 foreach ($defaults as $key => $value) {
377 if ($this->input->hasOption($key)) {
378 $result = $this->input->getOption($key);
379 if (isset($result)) {
380 $options[$key] = $this->input->getOption($key);