Completed
Push — master ( 4b90ae...869de7 )
by Andreas
02:32
created

createIteratorFromISO3166()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 2
nop 1
1
<?php
2
/**
3
 * Copyright (c) Andreas Heigl<[email protected]>
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining a copy
6
 * of this software and associated documentation files (the "Software"), to deal
7
 * in the Software without restriction, including without limitation the rights
8
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the Software is
10
 * furnished to do so, subject to the following conditions:
11
 *
12
 * The above copyright notice and this permission notice shall be included in
13
 * all copies or substantial portions of the Software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
 * THE SOFTWARE.
22
 *
23
 * @author    Andreas Heigl<[email protected]>
24
 * @copyright Andreas Heigl
25
 * @license   http://www.opensource.org/licenses/mit-license.php MIT-License
26
 * @since     09.03.2017
27
 * @link      http://github.com/heiglandreas/org.heigl.Holidaychecker
28
 */
29
30
namespace Org_Heigl\Holidaychecker;
31
32
use Org_Heigl\Holidaychecker\IteratorItem\Date;
33
use Org_Heigl\Holidaychecker\IteratorItem\Easter;
34
use Org_Heigl\Holidaychecker\IteratorItem\Relative;
35
36
class HolidayIteratorFactory
37
{
38
    /**
39
     * Create a HolidayIterator from an XML-File
40
     *
41
     * The provided XML-File has to validate against the holiday.xsd-file you
42
     * can find in this projects "share" folder.
43
     *
44
     * @param string $file
45
     *
46
     * @return \Org_Heigl\Holidaychecker\HolidayIterator
47
     */
48
    public function createIteratorFromXmlFile(string $file) : HolidayIterator
49
    {
50
        $iterator = new HolidayIterator();
51
52
        $dom = new \DOMDocument('1.0', 'UTF-8');
53
        $dom->load($file);
54
        $dom->xinclude();
55
56
        if (! $dom->schemaValidate(__DIR__ . '/../share/holidays.xsd')) {
57
            throw new \Exception('XML-File does not validate agains schema');
58
        }
59
        foreach ($dom->documentElement->childNodes as $child) {
60
            if (! $child instanceof \DOMElement) {
61
                continue;
62
            }
63
            $iterator->append($this->getElement($child));
64
        }
65
66
        return $iterator;
67
    }
68
69
    /**
70
     * Create a HolidayIterator from an ISO 3166-code.
71
     *
72
     * @param string $isoCode
73
     *
74
     * @return \Org_Heigl\Holidaychecker\HolidayIterator
75
     */
76
    public function createIteratorFromISO3166(string $isoCode) : HolidayIterator
77
    {
78
        $file = __DIR__ . '/../share/' . strtoupper($isoCode) . '.xml';
79
        if (! is_readable($file)) {
80
            throw new \UnexpectedValueException(sprintf(
81
                'There is no holiday-file for %s',
82
                $isoCode
83
            ));
84
        }
85
86
        return self::createIteratorFromXmlFile($file);
87
    }
88
89
90
    private function getElement(\DOMElement $child) : HolidayIteratorItemInterface
91
    {
92
        switch ($child->nodeName) {
93
            case 'easter':
94
                return new Easter(
95
                    $child->textContent,
96
                    $this->getFree($child),
97
                    $child->getAttribute('offset')
98
                );
99
            case 'date':
100
                return new Date(
101
                    $child->textContent,
102
                    $this->getFree($child),
103
                    $child->getAttribute('day'),
104
                    $child->getAttribute('month'),
105
                    ($child->hasAttribute('year')?$child->getAttribute('year'): null)
106
                );
107
            case 'relative':
108
                return new Relative(
109
                    $child->textContent,
110
                    $this->getFree($child),
111
                    $child->getAttribute('day'),
112
                    $child->getAttribute('month'),
113
                    $child->getAttribute('relation')
114
                );
115
        }
116
    }
117
118
    private function getFree(\DOMElement $element)
119
    {
120
        return ($element->getAttribute('free') === "true");
121
    }
122
}
123