Passed
Push — master ( a08f5c...b87926 )
by Daniel
02:23
created

ConfiguredXmlToCsv::transformKnownElements()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 0
loc 17
rs 9.2
cc 4
eloc 14
nc 4
nop 4
1
<?php
2
3
/*
4
 * The MIT License
5
 *
6
 * Copyright 2017 Daniel Popiniuc.
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a copy
9
 * of this software and associated documentation files (the "Software"), to deal
10
 * in the Software without restriction, including without limitation the rights
11
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
 * copies of the Software, and to permit persons to whom the Software is
13
 * furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included in
16
 * all copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
 * THE SOFTWARE.
25
 */
26
27
namespace danielgp\configured_xml2csv;
28
29
trait ConfiguredXmlToCsv
30
{
31
32
    protected $csvEolString;
33
    protected $csvFieldSeparator;
34
35
    private function cleanStringElement($initialString, $configuredFeatures)
36
    {
37
        $cleanedString = $initialString;
38
        if (array_key_exists('transformation', $configuredFeatures)) {
39
            $cleanedString = $this->cleanStringElementSpecific($initialString, $configuredFeatures);
40
        }
41
        return $cleanedString;
42
    }
43
44
    private function cleanStringElementSpecific($initialString, $configuredFeatures)
45
    {
46
        $knownCleaningTechniques = $this->knownCleaningTechniques();
47
        $cleanedString           = $initialString;
48
        foreach ($configuredFeatures['transformation'] as $crtCleaningTechnique) {
49
            if (is_array($knownCleaningTechniques[$crtCleaningTechnique])) {
50
                $cleanedString = call_user_func_array($knownCleaningTechniques[$crtCleaningTechnique][0], [
51
                    $knownCleaningTechniques[$crtCleaningTechnique][1],
52
                    $knownCleaningTechniques[$crtCleaningTechnique][2],
53
                    $cleanedString,
54
                ]);
55
            } else {
56
                $cleanedString = call_user_func($knownCleaningTechniques[$crtCleaningTechnique], $cleanedString);
57
            }
58
        }
59
        return $cleanedString;
60
    }
61
62
    private function evaluateMultipleInstanceOfSameElement($desiredEvaluationType, $arrayValues)
63
    {
64
        $knownEvaluationTechniques = $this->knownEvaluationTechniques();
65
        return call_user_func($knownEvaluationTechniques[$desiredEvaluationType], $arrayValues);
66
    }
67
68
    private function knownCleaningTechniques()
69
    {
70
        return [
71
            'html_entity_decode'         => 'html_entity_decode',
72
            'htmlspecialchars'           => 'htmlspecialchars',
73
            'str_replace__double_space'  => ['str_replace', '  ', ' '],
74
            'str_replace__nbsp__space'   => ['str_replace', '&nbsp;', ' '],
75
            'str_replace__tripple_space' => ['str_replace', '   ', ' '],
76
            'strip_tags'                 => 'strip_tags',
77
            'trim'                       => 'trim',
78
        ];
79
    }
80
81
    private function knownEvaluationTechniques()
82
    {
83
        return [
84
            'minimum' => 'min',
85
            'maximum' => 'max',
86
        ];
87
    }
88
89
    private function outputToCsvOneLine($lineCunter, $outputCsvArray)
90
    {
91
        $sReturn = [];
92
        if ($lineCunter == 0) {
93
            $sReturn[] = implode($this->csvFieldSeparator, array_keys($outputCsvArray[$lineCunter]));
94
        }
95
        $sReturn[] = implode($this->csvFieldSeparator, array_values($outputCsvArray[$lineCunter]));
96
        return implode($this->csvEolString, $sReturn);
97
    }
98
99
    private function processMultipleInstancesOfSameElement($config, $arr, $name)
100
    {
101
        $crncy     = $config['features'][$name]['multiple']['currency'];
102
        $optnl     = $config['features'][$name]['multiple']['discounter'];
103
        $mnyValues = [];
104
        foreach ($arr as $key => $val) {
105
            $attribs = $val->attributes();
106
            if ($key == $name) {
107
                $mnyValues[] = $attribs[$crncy] - ($attribs[$crncy] * $attribs[$optnl]) / 100;
108
            }
109
        }
110
        $evalType = $config['features'][$name]['multiple']['evaluation type'];
111
        return $this->evaluateMultipleInstanceOfSameElement($evalType, $mnyValues);
112
    }
113
114
    protected function readConfiguration($filePath, $fileBaseName)
115
    {
116
        $jSonContent = $this->readFileContent($filePath, $fileBaseName);
117
        return json_decode($jSonContent, true);
118
    }
119
120
    protected function readFileContent($filePath, $fileBaseName)
121
    {
122
        $fName    = $filePath . DIRECTORY_SEPARATOR . $fileBaseName;
123
        $fFile    = fopen($fName, 'r');
124
        $fContent = fread($fFile, filesize($fName));
125
        fclose($fFile);
126
        return $fContent;
127
    }
128
129
    private function transformKnownElements($config, $xmlIterator, $name, $data)
130
    {
131
        $cleanedData = $data;
132
        switch ($config['features'][$name]['type']) {
133
            case 'integer':
134
                $cleanedData = (int) $data;
135
                break;
136
            case 'multiple':
137
                $arr         = $xmlIterator->current();
138
                $cleanedData = $this->processMultipleInstancesOfSameElement($config, $arr, $name);
139
                break;
140
            case 'string':
141
                $cleanedData = $this->cleanStringElement($data, $config['features'][$name]);
142
                break;
143
        }
144
        return $cleanedData;
145
    }
146
147
    public function xmlToCSV($text)
148
    {
149
        $cnfg           = $this->readConfiguration(__DIR__, 'configuration.json');
150
        $xmlItrtr       = new \SimpleXMLIterator($text);
151
        $outputCsvArray = [];
152
        $lineCunter     = 0;
153
        $csvLine        = [];
154
        for ($xmlItrtr->rewind(); $xmlItrtr->valid(); $xmlItrtr->next()) {
155
            foreach ($xmlItrtr->getChildren() as $name => $data) {
156
                if (array_key_exists($name, $cnfg['features'])) {
157
                    $hdr                               = $cnfg['features'][$name]['header'];
158
                    $cleanedData                       = $this->transformKnownElements($cnfg, $xmlItrtr, $name, $data);
159
                    $outputCsvArray[$lineCunter][$hdr] = $cleanedData;
160
                }
161
            }
162
            $csvLine[] = $this->outputToCsvOneLine($lineCunter, $outputCsvArray);
163
            $lineCunter++;
164
        }
165
        return implode($this->csvEolString, $csvLine);
166
    }
167
}
168