Completed
Pull Request — master (#11)
by Vladimir
02:33
created

DataManager   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 174
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
dl 0
loc 174
rs 10
c 0
b 0
f 0
wmc 19
lcom 1
cbo 5

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getDataItems() 0 4 1
A parseDataItems() 0 9 3
A parseDataSets() 0 22 3
A fromCsv() 0 13 2
A fromJson() 0 4 1
A fromXml() 0 4 1
A fromYaml() 0 4 1
A fromYml() 0 4 1
A handleDependencies() 0 10 3
B handleTrackableItem() 0 24 3
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->scanTrackableItems($folder);
56
        }
57
    }
58
59
    /**
60
     * Loop through all of the DataSets specified in `$dataSets`. Each DataSet contains a name and a folder location
61
     *
62
     * For each folder, supported file type is read, parsed, and made available through `$this->getDataItems()`
63
     *
64
     * @param string[] $dataSets An array of DataSets
65
     */
66
    public function parseDataSets ($dataSets)
67
    {
68
        if ($dataSets === null) { return; }
69
70
        /**
71
         * The information which each DataSet has from the configuration file
72
         *
73
         * $dataSet['name']   string The name of the collection
74
         *         ['folder'] string The folder where this collection has its ContentItems
75
         *
76
         * @var $dataSet array
77
         */
78
        foreach ($dataSets as $dataSet)
79
        {
80
            $this->scanTrackableItems(
81
                $dataSet['folder'],
82
                array(
83
                    'namespace' => $dataSet['name']
84
                )
85
            );
86
        }
87
    }
88
89
    /**
90
     * {@inheritdoc}
91
     */
92
    protected function handleTrackableItem ($filePath, $options = array())
93
    {
94
        $relFilePath = $this->fs->getRelativePath($filePath);
95
        $ext     = strtolower($this->fs->getExtension($filePath));
96
        $name    = $this->fs->getBaseName($filePath);
97
        $content = file_get_contents($filePath);
98
        $fxnName = 'from' . ucfirst($ext);
99
100
        if (method_exists(get_called_class(), $fxnName))
101
        {
102
            $this->handleDependencies($ext);
103
            $this->saveOptions($relFilePath, $options);
104
            $this->addArrayToTracker(
105
                $name,
106
                $this->$fxnName($content),
107
                $relFilePath,
108
                (array_key_exists('namespace', $options)) ? $options['namespace'] : null
109
            );
110
        }
111
        else
112
        {
113
            $this->output->warning("There is no function to handle '$ext' file format.");
114
        }
115
    }
116
117
    /**
118
     * Convert from CSV into an associative array
119
     *
120
     * @param  string $content CSV formatted text
121
     *
122
     * @return array
123
     */
124
    private function fromCsv ($content)
125
    {
126
        $rows    = array_map("str_getcsv", explode("\n", trim($content)));
127
        $columns = array_shift($rows);
128
        $csv     = array();
129
130
        foreach ($rows as $row)
131
        {
132
            $csv[] = array_combine($columns, $row);
133
        }
134
135
        return $csv;
136
    }
137
138
    /**
139
     * Convert from JSON into an associative array
140
     *
141
     * @param  string $content JSON formatted text
142
     *
143
     * @return array
144
     */
145
    private function fromJson ($content)
146
    {
147
        return json_decode($content, true);
148
    }
149
150
    /**
151
     * Convert from XML into an associative array
152
     *
153
     * @param  string $content XML formatted text
154
     *
155
     * @return array
156
     */
157
    private function fromXml ($content)
158
    {
159
        return json_decode(json_encode(simplexml_load_string($content)), true);
160
    }
161
162
    /**
163
     * Convert from YAML into an associative array
164
     *
165
     * @param  string $content YAML formatted text
166
     *
167
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be array|string|\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...
168
     */
169
    private function fromYaml ($content)
170
    {
171
        return Yaml::parse($content, Yaml::PARSE_DATETIME);
172
    }
173
174
    /**
175
     * An alias for handling `*.yml` files
176
     *
177
     * @param  string $content YAML formatted text
178
     *
179
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be array|string|\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...
180
     */
181
    private function fromYml ($content)
182
    {
183
        return $this->fromYaml($content);
184
    }
185
186
    /**
187
     * @param string $extension
188
     *
189
     * @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...
190
     *
191
     * @throws DependencyMissingException
192
     */
193
    private function handleDependencies ($extension)
194
    {
195
        if ($extension === 'xml' && !function_exists('simplexml_load_string'))
196
        {
197
            $this->output->critical('XML support is not available in your PHP installation. For XML support, please install the appropriate package for your system:');
198
            $this->output->critical('  e.g. php7.0-xml');
199
200
            throw new DependencyMissingException('XML support is not available with the current PHP installation.');
201
        }
202
    }
203
}