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

DataManager::fromYml()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
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\Finder\Finder;
16
use Symfony\Component\Yaml\Yaml;
17
18
/**
19
 * Class DataManager
20
 *
21
 * This class handles everything in regards to DataItems and DataSets. This class supports reading the following data
22
 * types:
23
 *
24
 *   - CSV
25
 *   - JSON
26
 *   - XML
27
 *   - YAML
28
 *
29
 * @package allejo\stakx\Object
30
 */
31
class DataManager extends TrackingManager
32
{
33
    /**
34
     * Get all of the DataItems and DataSets in this manager
35
     *
36
     * @return array
37
     */
38
    public function getDataItems ()
39
    {
40
        return $this->trackedItems;
41
    }
42
43
    /**
44
     * Loop through all of the DataItems specified in `$folders`. Each folder will have contain just DataItems.
45
     *
46
     * For each folder, supported file type is read, parsed, and made available through `$this->getDataItems()`
47
     *
48
     * @param string[] $folders  An array of folders to be searched for to contain DataItems
49
     */
50
    public function parseDataItems ($folders)
51
    {
52
        if ($folders === null) { return; }
53
54
        foreach ($folders as $folder)
55
        {
56
            $this->parseTrackableItems($folder);
57
        }
58
    }
59
60
    /**
61
     * Loop through all of the DataSets specified in `$dataSets`. Each DataSet contains a name and a folder location
62
     *
63
     * For each folder, supported file type is read, parsed, and made available through `$this->getDataItems()`
64
     *
65
     * @param string[] $dataSets An array of DataSets
66
     */
67
    public function parseDataSets ($dataSets)
68
    {
69
        if ($dataSets === null) { return; }
70
71
        /**
72
         * The information which each DataSet has from the configuration file
73
         *
74
         * $dataSet['name']   string The name of the collection
75
         *         ['folder'] string The folder where this collection has its ContentItems
76
         *
77
         * @var $dataSet array
78
         */
79
        foreach ($dataSets as $dataSet)
80
        {
81
            $this->parseTrackableItems($dataSet['folder'], $dataSet['name']);
82
        }
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88
    protected function parseTrackableItems ($folder, $alias = null)
89
    {
90
        $dataItems = array();
91
        $finder    = new Finder();
92
        $finder->files()
93
               ->ignoreDotFiles(true)
94
               ->ignoreUnreadableDirs()
95
               ->in($this->fs->absolutePath($folder));
96
97
        foreach ($finder as $dataItem)
98
        {
99
            $ext     = strtolower($this->fs->getExtension($dataItem));
100
            $name    = $this->fs->getBaseName($dataItem);
101
            $content = file_get_contents($dataItem);
102
            $fxnName = 'from' . ucfirst($ext);
103
104
            if (method_exists(get_called_class(), $fxnName))
105
            {
106
                $this->handleDependencies($ext);
107
                $this->saveToTracker(
108
                    $name,
109
                    $this->$fxnName($content),
110
                    $this->fs->getRelativePath($dataItem),
111
                    (!is_null($alias)) ? $alias : null
112
                );
113
            }
114
            else
115
            {
116
                $this->output->warning("There is no function to handle '$ext' file format.");
117
            }
118
        }
119
120
        return $dataItems;
121
    }
122
123
    /**
124
     * Convert from CSV into an associative array
125
     *
126
     * @param  string $content CSV formatted text
127
     *
128
     * @return array
129
     */
130
    private function fromCsv ($content)
131
    {
132
        $rows    = array_map("str_getcsv", explode("\n", trim($content)));
133
        $columns = array_shift($rows);
134
        $csv     = array();
135
136
        foreach ($rows as $row)
137
        {
138
            $csv[] = array_combine($columns, $row);
139
        }
140
141
        return $csv;
142
    }
143
144
    /**
145
     * Convert from JSON into an associative array
146
     *
147
     * @param  string $content JSON formatted text
148
     *
149
     * @return array
150
     */
151
    private function fromJson ($content)
152
    {
153
        return json_decode($content, true);
154
    }
155
156
    /**
157
     * Convert from XML into an associative array
158
     *
159
     * @param  string $content XML formatted text
160
     *
161
     * @return array
162
     */
163
    private function fromXml ($content)
164
    {
165
        return json_decode(json_encode(simplexml_load_string($content)), true);
166
    }
167
168
    /**
169
     * Convert from YAML into an associative array
170
     *
171
     * @param  string $content YAML formatted text
172
     *
173
     * @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...
174
     */
175
    private function fromYaml ($content)
176
    {
177
        return Yaml::parse($content, Yaml::PARSE_DATETIME);
178
    }
179
180
    /**
181
     * An alias for handling `*.yml` files
182
     *
183
     * @param  string $content YAML formatted text
184
     *
185
     * @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...
186
     */
187
    private function fromYml ($content)
188
    {
189
        return $this->fromYaml($content);
190
    }
191
192
    /**
193
     * @param string $extension
194
     *
195
     * @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...
196
     *
197
     * @throws DependencyMissingException
198
     */
199
    private function handleDependencies ($extension)
200
    {
201
        if ($extension === 'xml' && !function_exists('simplexml_load_string'))
202
        {
203
            $this->output->critical('XML support is not available in your PHP installation. For XML support, please install the appropriate package for your system:');
204
            $this->output->critical('  e.g. php7.0-xml');
205
206
            throw new DependencyMissingException('XML support is not available with the current PHP installation.');
207
        }
208
    }
209
}