Completed
Pull Request — master (#25)
by Greg
02:33
created

FormatterOptions::setConfigurationValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 5
rs 9.4285
cc 1
eloc 3
nc 1
nop 2
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 INCLUDE_FIELD_LABELS = 'include-field-labels';
43
    const ROW_LABELS = 'row-labels';
44
    const FIELD_LABELS = 'field-labels';
45
    const DEFAULT_FIELDS = 'default-fields';
46
    const DEFAULT_STRING_FIELD = 'default-string-field';
47
    const DELIMITER = 'delimiter';
48
49
    public function __construct($configurationData = [], $options = [])
50
    {
51
        $this->configurationData = $configurationData;
52
        $this->options = $options;
53
    }
54
55
    public function override($configurationData)
56
    {
57
        $override = new self();
58
        $override
59
            ->setConfigurationData($configurationData + $this->getConfigurationData())
60
            ->setOptions($this->getOptions());
61
        return $override;
62
    }
63
64
    /**
65
     * Get a formatter option
66
     * @param string $key
67
     * @param array $defaults
68
     * @param mixed $default
69
     * @return mixed
70
     */
71
    public function get($key, $defaults = [], $default = false)
72
    {
73
        $value = $this->fetch($key, $defaults, $default);
74
        return $this->parse($key, $value);
75
    }
76
77
    public function getXmlSchema()
78
    {
79
        return new XmlSchema();
80
    }
81
82
    public function getFormat($defaults = [])
83
    {
84
        return $this->get(self::FORMAT, $defaults, $this->get(self::DEFAULT_FORMAT, $defaults, ''));
85
    }
86
87
    protected function fetch($key, $defaults = [], $default = false)
88
    {
89
        $values = array_merge(
90
            $defaults,
91
            $this->getConfigurationData(),
92
            $this->getOptions(),
93
            $this->getInputOptions($defaults)
94
        );
95
        if (array_key_exists($key, $values)) {
96
            return $values[$key];
97
        }
98
        return $default;
99
    }
100
101
    protected function parse($key, $value)
102
    {
103
        $optionFormat = $this->getOptionFormat($key);
104
        if ($optionFormat) {
105
            return $this->$optionFormat($value);
106
        }
107
        return $value;
108
    }
109
110
    public function parsePropertyList($value)
111
    {
112
        return PropertyParser::parse($value);
113
    }
114
115
    protected function getOptionFormat($key)
116
    {
117
        $propertyFormats = [
118
            self::ROW_LABELS => 'PropertyList',
119
            self::FIELD_LABELS => 'PropertyList',
120
        ];
121
        if (array_key_exists($key, $propertyFormats)) {
122
            return "parse{$propertyFormats[$key]}";
123
        }
124
        return false;
125
    }
126
127
    public function setConfigurationData($configurationData)
128
    {
129
        $this->configurationData = $configurationData;
130
        return $this;
131
    }
132
133
    protected function setConfigurationValue($key, $value)
134
    {
135
        $this->configurationData[$key] = $value;
136
        return $this;
137
    }
138
139
    public function setConfigurationDefault($key, $value)
140
    {
141
        if (!array_key_exists($key, $this->configurationData)) {
142
            return $this->setConfigurationValue($key, $value);
143
        }
144
        return $this;
145
    }
146
147
    public function getConfigurationData()
148
    {
149
        return $this->configurationData;
150
    }
151
152
    public function setOptions($options)
153
    {
154
        $this->options = $options;
155
        return $this;
156
    }
157
158
    public function setOption($key, $value)
159
    {
160
        $this->options[$key] = $value;
161
        return $this;
162
    }
163
164
    public function getOptions()
165
    {
166
        return $this->options;
167
    }
168
169
    public function setInput(InputInterface $input)
170
    {
171
        $this->input = $input;
172
    }
173
174
    public function getInputOptions($defaults)
175
    {
176
        if (!isset($this->input)) {
177
            return [];
178
        }
179
        $options = [];
180
        foreach ($defaults as $key => $value) {
181
            if ($this->input->hasOption($key)) {
182
                $result = $this->input->getOption($key);
183
                if (isset($result)) {
184
                    $options[$key] = $this->input->getOption($key);
185
                }
186
            }
187
        }
188
        return $options;
189
    }
190
}
191