Completed
Push — master ( 1e163d...8216e2 )
by Vladimir
18s
created

DataManager::parseDataSets()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 25
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 10
nc 3
nop 1
dl 0
loc 25
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file contains the DataManager class
5
 *
6
 * This file is part of the Stakx project.
7
 *
8
 * @copyright 2016 Vladimir Jimenez
9
 * @license   https://github.com/allejo/stakx/blob/master/LICENSE.md
10
 */
11
12
namespace allejo\stakx\Manager;
13
14
use allejo\stakx\Exception\DependencyMissingException;
15
use Symfony\Component\Yaml\Yaml;
16
17
/**
18
 * Class DataManager
19
 *
20
 * This class handles everything in regards to DataItems and DataSets. This class supports reading the following data
21
 * types:
22
 *
23
 *   - CSV
24
 *   - JSON
25
 *   - XML
26
 *   - YAML
27
 *
28
 * @package allejo\stakx\Object
29
 */
30
class DataManager extends TrackingManager
31
{
32
    /**
33
     * Get all of the DataItems and DataSets in this manager
34
     *
35
     * @return array
36
     */
37
    public function getDataItems ()
38
    {
39
        return $this->trackedItems;
40
    }
41
42
    /**
43
     * Loop through all of the DataItems specified in `$folders`. Each folder will have contain just DataItems.
44
     *
45
     * For each folder, supported file type is read, parsed, and made available through `$this->getDataItems()`
46
     *
47
     * @param string[] $folders  An array of folders to be searched for to contain DataItems
48
     */
49
    public function parseDataItems ($folders)
50
    {
51
        if ($folders === null) { return; }
52
53
        foreach ($folders as $folder)
54
        {
55
            $this->saveFolderDefinition($folder);
56
            $this->scanTrackableItems(
57
                $folder,
58
                array(),
59
                array(),
60
                array('/\.example$/')
61
            );
62
        }
63
    }
64
65
    /**
66
     * Loop through all of the DataSets specified in `$dataSets`. Each DataSet contains a name and a folder location
67
     *
68
     * For each folder, supported file type is read, parsed, and made available through `$this->getDataItems()`
69
     *
70
     * @param string[] $dataSets An array of DataSets
71
     */
72
    public function parseDataSets ($dataSets)
73
    {
74
        if ($dataSets === null) { return; }
75
76
        /**
77
         * The information which each DataSet has from the configuration file
78
         *
79
         * $dataSet['name']   string The name of the collection
80
         *         ['folder'] string The folder where this collection has its ContentItems
81
         *
82
         * @var $dataSet array
83
         */
84
        foreach ($dataSets as $dataSet)
85
        {
86
            $this->saveFolderDefinition($dataSet['folder'], array(
87
                'namespace' => $dataSet['name']
88
            ));
89
            $this->scanTrackableItems(
90
                $dataSet['folder'],
91
                array('namespace' => $dataSet['name']),
92
                array(''),
93
                array('/\.example$/')
94
            );
95
        }
96
    }
97
98
    /**
99
     * {@inheritdoc}
100
     */
101
    protected function handleTrackableItem ($filePath, $options = array())
102
    {
103
        $relFilePath = $this->fs->getRelativePath($filePath);
104
        $ext     = strtolower($this->fs->getExtension($filePath));
105
        $name    = $this->fs->getBaseName($filePath);
106
        $content = file_get_contents($filePath);
107
        $fxnName = 'from' . ucfirst($ext);
108
109
        if (method_exists(get_called_class(), $fxnName))
110
        {
111
            $this->handleDependencies($ext);
112
            $this->saveTrackerOptions($relFilePath, $options);
113
            $this->addArrayToTracker(
114
                $name,
115
                $this->$fxnName($content),
116
                $relFilePath,
117
                (array_key_exists('namespace', $options)) ? $options['namespace'] : null
118
            );
119
        }
120
        else
121
        {
122
            $this->output->warning("There is no function to handle '$ext' file format.");
123
        }
124
125
        return $name;
126
    }
127
128
    /**
129
     * Convert from CSV into an associative array
130
     *
131
     * @param  string $content CSV formatted text
132
     *
133
     * @return array
134
     */
135
    private function fromCsv ($content)
136
    {
137
        $rows    = array_map("str_getcsv", explode("\n", trim($content)));
138
        $columns = array_shift($rows);
139
        $csv     = array();
140
141
        foreach ($rows as $row)
142
        {
143
            $csv[] = array_combine($columns, $row);
144
        }
145
146
        return $csv;
147
    }
148
149
    /**
150
     * Convert from JSON into an associative array
151
     *
152
     * @param  string $content JSON formatted text
153
     *
154
     * @return array
155
     */
156
    private function fromJson ($content)
157
    {
158
        return json_decode($content, true);
159
    }
160
161
    /**
162
     * Convert from XML into an associative array
163
     *
164
     * @param  string $content XML formatted text
165
     *
166
     * @return array
167
     */
168
    private function fromXml ($content)
169
    {
170
        return json_decode(json_encode(simplexml_load_string($content)), true);
171
    }
172
173
    /**
174
     * Convert from YAML into an associative array
175
     *
176
     * @param  string $content YAML formatted text
177
     *
178
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be string|array|\stdClass? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
179
     */
180
    private function fromYaml ($content)
181
    {
182
        return Yaml::parse($content, Yaml::PARSE_DATETIME);
183
    }
184
185
    /**
186
     * An alias for handling `*.yml` files
187
     *
188
     * @param  string $content YAML formatted text
189
     *
190
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be string|array|\stdClass? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
191
     */
192
    private function fromYml ($content)
193
    {
194
        return $this->fromYaml($content);
195
    }
196
197
    /**
198
     * @param string $extension
199
     *
200
     * @todo 0.1.0 Create a help page on the main stakx website for this topic and link to it
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
201
     *
202
     * @throws DependencyMissingException
203
     */
204
    private function handleDependencies ($extension)
205
    {
206
        if ($extension === 'xml' && !function_exists('simplexml_load_string'))
207
        {
208
            $this->output->critical('XML support is not available in your PHP installation. For XML support, please install the appropriate package for your system:');
209
            $this->output->critical('  e.g. php7.0-xml');
210
211
            throw new DependencyMissingException('XML support is not available with the current PHP installation.');
212
        }
213
    }
214
}