Passed
Push — master ( 6ec87a...fbe757 )
by George
03:22
created

Base::getSchemaKeyFromName()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3.0416

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 10
ccs 5
cts 6
cp 0.8333
rs 9.4285
cc 3
eloc 5
nc 3
nop 1
crap 3.0416
1
<?php
2
namespace JsonTable;
3
4
/**
5
 * @package    JSON table
6
 */
7
abstract class Base
8
{
9
    /**
10
     * @static
11
     *
12
     * @var string Schema JSON
13
     */
14
    protected static $schemaJson;
15
16
    /**
17
     * @static
18
     *
19
     * @var string The path and name of the file to analyse.
20
     */
21
    protected static $fileName;
22
23
    /**
24
     * @static
25
     *
26
     * @var array The columns found in the header.
27
     *                This is used to validate that each row has the correct number of columns
28
     *                and to get the column name from it's position.
29
     */
30
    protected static $headerColumns;
31
32
    /**
33
     * @static
34
     *
35
     * @var object The SplFileObject of the CSV file.
36
     */
37
    protected static $file;
38
39
    /**
40
     * @var object The PDO object.
41
     */
42
    public static $pdoConnection;
43
44
45
    /**
46
     * Set the schema.
47
     *
48
     * @param string $schemaJson The schema conforming to the JSON table schema specification.
49
     * @see http://dataprotocols.org/json-table-schema
50
     *
51
     * @return void
52
     *
53
     * @throws \Exception if the schema is not a valid JSON string.
54
     * @throws \Exception if the schema is an invalid data type.
55
     */
56 45
    public function setSchema($schemaJson)
57
    {
58 45
        if (is_string($schemaJson)) {
59 42
            if (is_null($schemaJson = json_decode($schemaJson))) {
60 1
                throw new \Exception('The schema is not a valid JSON string.');
61
            }
62 44
        } elseif (!is_object($schemaJson)) {
63 3
            throw new \Exception('Invalid schema data type.');
64
        }
65
66 41
        foreach ($schemaJson->fields as &$field) {
67 41
            $field->name = strtolower($field->name);
68 41
        }
69 41
        unset($field);
70
71 41
        self::$schemaJson = $schemaJson;
72 41
    }
73
74
75
    /**
76
     * Set the file.
77
     * This checks that the file exists.
78
     *
79
     * @param   string  $fileName    The path and name of the file to analyse.
80
     * @see http://dataprotocols.org/json-table-schema
81
     *
82
     * @return  boolean Whether the file was successfully set.
83
     */
84 48
    public function setFile($fileName)
85
    {
86 48
        if (file_exists($fileName)) {
87 41
            self::$fileName = (string) $fileName;
88 41
            return true;
89
        }
90
91 7
        return false;
92
    }
93
94
95
    /**
96
     * Set the database connection.
97
     *
98
     * @static
99
     *
100
     * @param object $pdoConnection The PDO object.
101
     *
102
     * @return boolean Whether the connection was valid.
103
     */
104 45
    public function setPdoConnection($pdoConnection)
105
    {
106 45
        if ($pdoConnection instanceof \PDO) {
107 39
            self::$pdoConnection = $pdoConnection;
108 39
            return true;
109
        }
110
111 6
        return false;
112
    }
113
114
115
    /**
116
     * Open a handle to the file to be analysed.
117
     *
118
     * @static
119
     *
120
     * @return void
121
     *
122
     * @throws \Exception if a CSV file has not been set.
123
     */
124 41
    protected static function openFile()
125
    {
126 41
        if (empty(self::$fileName)) {
127 1
            throw new \Exception('CSV file not set.');
128
        }
129
130 40
        self::$file = new \SplFileObject(self::$fileName);
131 40
        self::$file->setFlags(\SplFileObject::READ_CSV | \SplFileObject::SKIP_EMPTY);
132 40
    }
133
134
135
    /**
136
     * Set the CSV header columns from those in the file.
137
     * These are stored in lowercase as all column to schema checking is considered as case insensitive.
138
     *
139
     * @static
140
     *
141
     * @return true on success.
142
     */
143 40
    protected static function setCsvHeaderColumns()
144
    {
145 40
        self::$file->rewind();
146 40
        self::$headerColumns = array_map('strtolower', self::$file->current());
147 40
        return true;
148
    }
149
150
151
    /**
152
     * Rewind the CSV file pointer to the first line of data.
153
     *
154
     * @static
155
     *
156
     * @return void
157
     */
158 38
    protected static function rewindFilePointerToFirstData()
159
    {
160 38
        self::$file->seek(1);
161 38
    }
162
163
164
    /**
165
     * Get the data from the current CSV file row and move the pointer on to the next row.
166
     *
167
     * @static
168
     *
169
     * @return array|boolean The CSV data or false if the end of the file has been reached.
170
     */
171 38
    protected static function loopThroughFileRows()
172
    {
173 38
        if (self::$file->eof()) {
174
            return false;
175
        }
176
177 38
        $csvRow = self::$file->current();
178 38
        self::$file->next();
179
180 38
        return $csvRow;
181
    }
182
183
184
    /**
185
     * Get the key of the field with the specified name from the schema.
186
     * This can be used to validate that a column exists in the schema.
187
     *
188
     * @param string $fieldName The field name.
189
     *
190
     * @return int The key ID or false if the field is not found.
191
     */
192 38
    protected function getSchemaKeyFromName($fieldName)
193
    {
194 38
        foreach (self::$schemaJson->fields as $key => $field) {
195 38
            if ($field->name === $fieldName) {
196 38
                return $key;
197
            }
198 37
        }
199
200
        return false;
201
    }
202
203
204
    /**
205
     * Get the position of the field with the specified name from the CSV file.
206
     * This can be used to validate that a column exists in the CSV file.
207
     *
208
     * @param string $fieldName The field name.
209
     *
210
     * @return int The position or false if the field is not found.
211
     */
212 37
    protected function getCsvPositionFromName($fieldName)
213
    {
214 37
        return array_search($fieldName, self::$headerColumns);
215
    }
216
217
218
    /**
219
     * Get the schema object for a column, given the columns position in the CSV file.
220
     *
221
     * @param int $csvColumnPosition The position of the column in the CSV file.
222
     *
223
     * @return object The schema column.
224
     */
225 38
    protected function getSchemaColumnFromCsvColumnPosition($csvColumnPosition)
226
    {
227 38
        $csvColumnName = self::$headerColumns[$csvColumnPosition];
228 38
        $schemaKey = $this->getSchemaKeyFromName($csvColumnName);
229
230 38
        return self::$schemaJson->fields[$schemaKey];
231
    }
232
233
234
    /**
235
     * Get the type of the specified column.
236
     *
237
     * @param object $schemaColumn The schema column object to examine.
238
     *
239
     * @return string The type.
240
     */
241 38
    protected function getColumnType($schemaColumn)
242
    {
243 38
        return (property_exists($schemaColumn, 'type')) ? $schemaColumn->type : 'string';
244
    }
245
246
247
    /**
248
     * Get the format of the specified column.
249
     *
250
     * @param object $schemaColumn The schema column object to examine.
251
     *
252
     * @return string The format or null if no format is specified.
253
     */
254 38
    protected function getColumnFormat($schemaColumn)
255
    {
256 38
        return (property_exists($schemaColumn, 'format')) ? $schemaColumn->format : 'default';
257
    }
258
}
259