Completed
Pull Request — master (#26)
by Greg
02:36
created

FormatterOptions::initialize()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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