Passed
Push — Codacy ( a1e3c0...c4915f )
by Fabien
02:37
created

Xml2arrayFunctions::setStandardAttributes()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 10
cts 10
cp 1
rs 9.2
c 0
b 0
f 0
cc 4
eloc 8
nc 6
nop 3
crap 4
1
<?php
2
3
/*
4
 * This file is part of the FabienCrassat\CurriculumVitaeBundle Symfony bundle.
5
 *
6
 * (c) Fabien Crassat <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace FabienCrassat\CurriculumVitaeBundle\Entity;
13
14
use FabienCrassat\CurriculumVitaeBundle\Utility\AgeCalculator;
15
16
class Xml2arrayFunctions {
17
    private $language;
18
    private $file;
19
20
    /**
21
     * @param \SimpleXMLElement $file
22
     * @param string $language
23
     */
24 34
    public function __construct($file, $language = 'en') {
25 34
        $this->language = $language;
26 34
        $this->file     = $file;
27 34
    }
28
29
    /**
30
     * @param \SimpleXMLElement $xml
31
     * @param integer $recursiveDepth
32
     * @param boolean $format
33
     *
34
     * @return null|array
35
     */
36 31
    public function xml2array(\SimpleXMLElement $xml, $recursiveDepth = 0, $format = TRUE) {
37 31
        $recursiveDepth++;
38 31
        $result = array();
39
40
        // Extraction of the node
41 31
        $key   = trim($xml->getName());
42 31
        $value = trim((string) $xml);
43
44
        // Specific Attribute: do nothing when it is not the good language
45 31
        if ($xml->attributes()->lang) {
46 21
            if ($xml->attributes()->lang <> $this->language) {
47 18
                return NULL;
48
            }
49 19
            unset($xml->attributes()->lang);
50 19
        }
51
52
        // Specific Attributes changing the xml
53 31
        $key    = $this->setSpecificAttributeKeyWithGivenId($xml, $key);
54 31
        $value  = $this->setSpecificAttributeAge($xml, $recursiveDepth, $value);
55 31
        $result = $this->retrieveSpecificAttributeCrossRef($xml, $recursiveDepth, $result, $key);
56
        // Standard Attributes
57 31
        $result = $this->setStandardAttributes($xml, $result, $key);
58
        // Specific Key
59 31
        $value = $this->setValueForSpecificKeys($key, $value, $format);
60
61 31
        $result = $this->setValue($result, $key, $value);
62 31
        $result = $this->setChildren($xml, $recursiveDepth, $key, $result);
63
64 31
        return $result;
65
    }
66
67
    /**
68
     * @param array $arrayToSet
69
     * @param string $key
70
     * @param array|string $value
71
     *
72
     * @return array
73
     */
74 31
    private function setValue($arrayToSet, $key, $value) {
75 31
        if ($value <> '') {
76 28
            return array_merge($arrayToSet, array($key => $value));
77
        }
78 31
        return $arrayToSet;
79
    }
80
81
    /**
82
     * @param \SimpleXMLElement $xml
83
     * @param integer $depth
84
     * @param string $key
85
     * @param array $arrayXML
86
     *
87
     * @return array
88
     */
89 31
    private function setChildren(\SimpleXMLElement $xml, $depth, $key, array $arrayXML) {
90 31
        $return = $arrayXML;
91 31
        if ($xml->children()->count() > 0) {
92 29
            foreach($xml->children() as $childValue) {
93 29
                $child = $this->xml2array($childValue, $depth);
94 29
                if ($depth > 1 && ! empty($child)) {
95 21
                    $return = array_merge_recursive($return, array($key => $child));
96 29
                } elseif (! empty($child)) {
97 28
                    $return = array_merge_recursive($return, $child);
98 28
                }
99 29
            }
100 29
        }
101 31
        return $return;
102
    }
103
104
    /**
105
     * @param \SimpleXMLElement $xml
106
     * @param array $arrayToMerge
107
     * @param string $key
108
     *
109
     * @return array
110
     */
111 31
    private function setStandardAttributes(\SimpleXMLElement $xml, $arrayToMerge, $key) {
112
        // Standard Attributes (without Specific thanks to unset())
113 31
        $attributes = array();
114 31
        foreach($xml->attributes() as $attributeKey => $attributeValue) {
115 25
            if ($this->isStandardAttributes($attributeKey)) {
116 16
                $attributes[$attributeKey] = trim($attributeValue);
117 16
            }
118 31
        }
119 31
        if (count($attributes) > 0) {
120 16
            return array_merge_recursive($arrayToMerge, array($key => $attributes));
121
        }
122 31
        return $arrayToMerge;
123
    }
124
125 25
    private function isStandardAttributes($attribute)
126
    {
127
        return $attribute <> 'id'
128 25
            && $attribute <> 'ref'
129 25
            && $attribute <> 'lang'
130 25
            && $attribute <> 'crossref';
131
    }
132
133
    /**
134
     * @param \SimpleXMLElement $xml
135
     * @param string $keyValue
136
     *
137
     * @return string
138
     */
139 31
    private function setSpecificAttributeKeyWithGivenId(\SimpleXMLElement $xml, $keyValue) {
140
        // Specific Attribute: change the key with the given id
141 31
        if ($xml->attributes()->id) {
142 19
            return (string) $xml->attributes()->id;
143
        }
144 31
        return $keyValue;
145
    }
146
147
    /**
148
     * @param \SimpleXMLElement $xml
149
     * @param integer $depth
150
     * @param string $age
151
     *
152
     * @return string
153
     */
154 31
    private function setSpecificAttributeAge(\SimpleXMLElement $xml, $depth, $age) {
155
        // Specific Attribute: Retreive the age
156 31
        if ($xml->attributes()->getAge) {
157 11
            $crossref = $this->file->xpath(trim($xml->attributes()->getAge));
158 11
            $birthday = $this->xml2array(clone $crossref[0], $depth, FALSE);
159 11
            $birthday = implode('', $birthday);
160
161 11
            $ageCalculator = new AgeCalculator((string) $birthday);
162
163 11
            return (string) $ageCalculator->age();
164
        }
165 31
        return $age;
166
    }
167
168
    /**
169
     * @param \SimpleXMLElement $xml
170
     * @param integer $depth
171
     * @param array $arrayXML
172
     * @param string $key
173
     *
174
     * @return array
175
     */
176 31
    private function retrieveSpecificAttributeCrossRef(\SimpleXMLElement $xml, $depth, array $arrayXML, $key) {
177
        // Specific Attribute: Retrieve the given crossref
178 31
        if ($xml->attributes()->crossref) {
179 14
            $crossref = $this->file->xpath(trim($xml->attributes()->crossref));
180 14
            $temp     = array();
181 14
            foreach ($crossref as $value) {
182 14
                $resultArray = $this->xml2array($value, $depth);
183
184 14
                if($resultArray) $temp = array_merge($temp, $resultArray);
185 14
            }
186 14
            return array_merge($arrayXML, array($key => $temp));
187
        }
188 31
        return $arrayXML;
189
    }
190
191
    /**
192
     * @param string $key
193
     * @param string $value
194
     * @param boolean $format
195
     *
196
     * @return string|string[]
197
     */
198 31
    private function setValueForSpecificKeys($key, $value, $format) {
199 31
        if ($key == 'birthday') {
200 12
            return $this->setValueForBirthdayKey($value, $format);
201
        }
202 31
        elseif ($key == 'item') {
203 9
            return array($value); // convert to apply array_merge()
204
        }
205
206 31
        return $value;
207
    }
208
209
    /**
210
     * Specific Key: Format to french date format
211
     *
212
     * @param string $date
213
     * @param boolean $format
214
     *
215
     * @return string
216
     */
217 12
    private function setValueForBirthdayKey($date, $format) {
218 12
        if ($format) {
219 12
            setlocale(LC_TIME, array('fra_fra', 'fr', 'fr_FR', 'fr_FR.UTF8'));
220 12
            return strftime('%d %B %Y', strtotime(date($date)));
221
        }
222 11
        return $date;
223
    }
224
}
225