Issues (115)

src/Locale/Locale.php (1 issue)

1
<?php
2
/*
3
 * citeproc-php
4
 *
5
 * @link        http://github.com/seboettg/citeproc-php for the source repository
6
 * @copyright   Copyright (c) 2016 Sebastian Böttger.
7
 * @license     https://opensource.org/licenses/MIT
8
 */
9
10
namespace Seboettg\CiteProc\Locale;
11
12
use InvalidArgumentException;
13
use Seboettg\CiteProc\Exception\CiteProcException;
14
use Seboettg\CiteProc\StyleSheet;
15
use Seboettg\Collection\ArrayList;
16
use Seboettg\Collection\Lists\ListInterface;
17
use Seboettg\Collection\Map\MapInterface;
18
use SimpleXMLElement;
19
use stdClass;
20
21
/**
22
 * Class Locale
23
 *
24
 * While localization data can be included in styles, locale files conveniently provide sets of default localization
25
 * data, consisting of terms, date formats and grammar options. These default localizations are drawn from the
26
 * “locales-xx-XX.xml” located in locales folder (which is included as git submodule). These default locales may be
27
 * redefined or supplemented with cs:locale elements, which should be placed in the style sheet directly after the
28
 * cs:info element.
29
 *
30
 * TODO: implement Locale Fallback (http://docs.citationstyles.org/en/stable/specification.html#locale-fallback)
31
 *
32
 * @package Seboettg\CiteProc\Locale
33
 * @author Sebastian Böttger <[email protected]>
34
 */
35
class Locale
36
{
37
    use LocaleXmlParserTrait;
38
39
    /**
40
     * @var SimpleXMLElement
41
     */
42
    private SimpleXMLElement $localeXml;
43
44
    /**
45
     * @var string
46
     */
47
    private string $language;
48
49
    /**
50
     * Locale constructor.
51
     * @throws CiteProcException
52
     */
53
    public function __construct(string $lang = "en-US", string $xmlString = null)
54
    {
55
        $this->language = $lang;
56
57
        if (!empty($xmlString)) {
58
            $this->localeXml = new SimpleXMLElement($xmlString);
59
        } else {
60
            $this->localeXml = new SimpleXMLElement(StyleSheet::loadLocales($lang));
61
        }
62
63
        $this->initLocaleXmlParser();
64
        $this->parseXml($this->localeXml);
65
    }
66
67
    /**
68
     * @param SimpleXMLElement $xml
69
     * @return $this
70
     */
71
    public function addXml(SimpleXMLElement $xml)
72
    {
73
        $lang = (string) $xml->attributes('http://www.w3.org/XML/1998/namespace')->{'lang'};
74
        if (empty($lang) || $this->getLanguage() === $lang || explode('-', $this->getLanguage())[0] === $lang) {
75
            $this->parseXml($xml);
76
        }
77
        return $this;
78
    }
79
80
    /**
81
     * @return string
82
     */
83
    public function getLanguage()
84
    {
85
        return $this->language;
86
    }
87
88
    public function filter(string $type, string $name, string $form = "long")
89
    {
90
        if ('options' === $type) {
91
            return $this->option($name);
92
        }
93
        if (!isset($this->{$type})) {
94
            throw new InvalidArgumentException("There is no locale of type \"$type\".");
95
        }
96
97
        /** @var MapInterface $localeList */
98
        $localeList = $this->{$type};
99
100
        if (is_null($name)) {
0 ignored issues
show
The condition is_null($name) is always false.
Loading history...
101
            $name = "";
102
        }
103
104
        /** @var ListInterface $list */
105
        $list = $localeList[$name];
106
107
        if (empty($list)) {
108
            $ret = new stdClass();
109
            $ret->name = null;
110
            $ret->single = null;
111
            $ret->multiple = null;
112
            return $ret;
113
        }
114
115
        //filter by form
116
        if ($type !== "options") {
117
            /** @var Term $value */
118
            return $list->filter(function ($term) use ($form) {
119
                return $term->form === $form;
120
            })->last();
121
        }
122
123
        return $list->last();
124
    }
125
126
    private function option(string $name)
127
    {
128
        $result = null;
129
        foreach ($this->options as $key => $value) {
130
            if ($key === $name) {
131
                if (is_array($value) && isset($value[1]) && is_array($value[1])) {
132
                    $result = reset($value[1]);
133
                } else {
134
                    $result = reset($value);
135
                }
136
            }
137
        }
138
        return $result;
139
    }
140
}
141