Passed
Push — new-api ( 18d26d...074931 )
by Sebastian
04:59
created

Locale::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 9
c 0
b 0
f 0
nc 1
nop 9
dl 0
loc 20
ccs 10
cts 10
cp 1
crap 1
rs 9.9666

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
declare(strict_types=1);
3
/*
4
 * citeproc-php
5
 *
6
 * @link        http://github.com/seboettg/citeproc-php for the source repository
7
 * @copyright   Copyright (c) 2016 Sebastian Böttger.
8
 * @license     https://opensource.org/licenses/MIT
9
 */
10
11
namespace Seboettg\CiteProc\Locale;
12
13
use InvalidArgumentException;
14
use Seboettg\CiteProc\Config\Locale as LocaleConfig;
15
use Seboettg\CiteProc\Exception\CiteProcException;
16
use Seboettg\Collection\ArrayList as ArrayList;
17
use Seboettg\Collection\ArrayList\ArrayListInterface;
18
use SimpleXMLElement;
19
use stdClass;
20
use function Seboettg\CiteProc\loadLocales;
21
22
/**
23
 * Class Locale
24
 *
25
 * While localization data can be included in styles, locale files conveniently provide sets of default localization
26
 * data, consisting of terms, date formats and grammar options. These default localizations are drawn from the
27
 * “locales-xx-XX.xml” located in locales folder (which is included as git submodule). These default locales may be
28
 * redefined or supplemented with cs:locale elements, which should be placed in the style sheet directly after the
29
 * cs:info element.
30
 *
31
 * TODO: implement Locale Fallback (http://docs.citationstyles.org/en/stable/specification.html#locale-fallback)
32
 *
33
 * @package Seboettg\CiteProc\Locale
34
 * @author Sebastian Böttger <[email protected]>
35
 */
36
class Locale
37
{
38
    /** @var SimpleXMLElement */
39
    private $localeXml;
40
41
    /** @var string */
42
    private $language;
43
44
    /** @var ArrayListInterface */
45
    private $options;
46
47
    /** @var ArrayListInterface */
48
    private $date;
49
50
    /** @var ArrayListInterface */
51
    private $terms;
52
53
    /** @var ArrayListInterface */
54
    private $optionsXml;
55
56
    /** @var ArrayListInterface */
57
    private $dateXml;
58
59
    /** @var ArrayListInterface */
60
    private $termsXml;
61
62
    /** @var LocaleParser */
63
    private $localeParser;
64
65
    /**
66
     * @param LocaleConfig $localeConfig
67
     * @param null $xmlString
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $xmlString is correct as it would always require null to be passed?
Loading history...
68
     * @return Locale
69
     * @throws CiteProcException
70
     */
71 184
    public static function factory(LocaleConfig $localeConfig, $xmlString = null): Locale
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$xmlString" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$xmlString"; expected 0 but found 1
Loading history...
72
    {
73 184
        $language = (string)$localeConfig;
74 184
        if (!empty($xmlString)) {
75
            $localeXml = new SimpleXMLElement($xmlString);
76
        } else {
77 184
            $localeXml = new SimpleXMLElement(loadLocales((string)$localeConfig));
78
        }
79 184
        $localeParser = new LocaleParser();
80 184
        list($options, $optionsXml, $date, $dateXml, $terms, $termsXml) = $localeParser->parse($localeXml);
81 184
        return new Locale(
82 184
            $localeParser,
83 184
            $localeXml,
84 184
            $language,
85 184
            $options,
86 184
            $optionsXml,
87 184
            $date,
88 184
            $dateXml,
89 184
            $terms,
90 184
            $termsXml
91
        );
92
    }
93
94
    /**
95
     * Locale constructor.
96
     * @param LocaleParser $localeParser
97
     * @param SimpleXMLElement $localeXml
98
     * @param string $language
99
     * @param ArrayListInterface $options
100
     * @param ArrayListInterface $optionsXml
101
     * @param ArrayListInterface $date
102
     * @param ArrayListInterface $dateXml
103
     * @param ArrayListInterface $terms
104
     * @param ArrayListInterface $termsXml
105
     */
106 184
    public function __construct(
107
        LocaleParser $localeParser,
108
        SimpleXMLElement $localeXml,
109
        string $language,
110
        ArrayListInterface $options,
111
        ArrayListInterface $optionsXml,
112
        ArrayListInterface $date,
113
        ArrayListInterface $dateXml,
114
        ArrayListInterface $terms,
115
        ArrayListInterface $termsXml
116
    ) {
117 184
        $this->localeParser = $localeParser;
118 184
        $this->localeXml = $localeXml;
119 184
        $this->language = $language;
120 184
        $this->options = $options;
121 184
        $this->optionsXml = $optionsXml;
122 184
        $this->date = $date;
123 184
        $this->dateXml = $dateXml;
124 184
        $this->terms = $terms;
125 184
        $this->termsXml = $termsXml;
126 184
    }
127
128
    /**
129
     * @param SimpleXMLElement $xml
130
     * @return $this
131
     */
132 54
    public function addXml(SimpleXMLElement $xml): Locale
133
    {
134 54
        $lang = (string) $xml->attributes('http://www.w3.org/XML/1998/namespace')->{'lang'};
135 54
        if (empty($lang) || $this->getLanguage() === $lang || explode('-', $this->getLanguage())[0] === $lang) {
136 51
            list($this->options, $this->optionsXml, $this->date, $this->dateXml, $this->terms, $this->termsXml) =
137 51
                $this->localeParser->parse(
138 51
                    $xml,
139 51
                    $this->options,
140 51
                    $this->optionsXml,
141 51
                    $this->date,
142 51
                    $this->dateXml,
143 51
                    $this->terms,
144 51
                    $this->termsXml
145
                );
146
        }
147 54
        return $this;
148
    }
149
150
    /**
151
     * @return string
152
     */
153 37
    public function getLanguage(): string
154
    {
155 37
        return $this->language;
156
    }
157
158
    /**
159
     * @param string $type
160
     * @param $name
161
     * @param string $form
162
     * @return stdClass|null|bool
163
     */
164 184
    public function filter(string $type, $name, string $form = "long")
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$form" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$form"; expected 0 but found 1
Loading history...
165
    {
166 184
        if ('options' === $type) {
167 183
            return $this->option($name);
168
        }
169 184
        if (!isset($this->{$type})) {
170
            throw new InvalidArgumentException("There is no locale of type \"$type\".");
171
        }
172
173
        /** @var ArrayList $localeList */
174 184
        $localeList = $this->{$type};
175
176 184
        if (is_null($name)) {
177
            $name = "";
178
        }
179
180
        //filter by name
181 184
        $array = $localeList->get($name);
182
183 184
        if (empty($array)) {
184 32
            $ret = new stdClass();
185 32
            $ret->name = null;
186 32
            $ret->single = null;
187 32
            $ret->multiple = null;
188 32
            return $ret;
189
        }
190
191
        //filter by form
192 184
        if ($type !== "options") {
193
            /** @var Term $value */
194
            $array = array_filter($array, function ($term) use ($form) {
195 184
                return $term->form === $form;
196 184
            });
197
        }
198
199 184
        return array_pop($array);
200
    }
201
202 183
    private function option($name)
203
    {
204 183
        $result = null;
205 183
        foreach ($this->options as $key => $value) {
206 183
            if ($key === $name) {
207 183
                if (is_array($value) && isset($value[1]) && is_array($value[1])) {
208 5
                    $result = reset($value[1]);
209
                } else {
210 183
                    $result = reset($value);
211
                }
212
            }
213
        }
214 183
        return $result;
215
    }
216
217
    /**
218
     * @return ArrayListInterface
219
     */
220 17
    public function getDateXml(): ?ArrayListInterface
221
    {
222 17
        return $this->dateXml;
223
    }
224
}
225