Completed
Push — releases/v0.2.1 ( b63a3e...ff9fbc )
by Luke
02:49
created

AbstractRow::key()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * CSVelte: Slender, elegant CSV for PHP
4
 * Inspired by Python's CSV module and Frictionless Data and the W3C's CSV
5
 * standardization efforts, CSVelte was written in an effort to take all the
6
 * suck out of working with CSV.
7
 *
8
 * @version   v0.2.1
9
 * @copyright Copyright (c) 2016 Luke Visinoni <[email protected]>
10
 * @author    Luke Visinoni <[email protected]>
11
 * @license   https://github.com/deni-zen/csvelte/blob/master/LICENSE The MIT License (MIT)
12
 */
13
namespace CSVelte\Table;
14
15
use \Iterator;
16
use \Countable;
17
use \ArrayAccess;
18
use CSVelte\Flavor;
19
20
use \OutOfBoundsException;
21
use \InvalidArgumentException;
22
use CSVelte\Exception\ImmutableException;
23
24
use function CSVelte\collect;
25
26
/**
27
 * Table row abstract base class
28
 * Represents a row of tabular data (represented by CSVelte\Table\Data objects)
29
 *
30
 * @package CSVelte
31
 * @subpackage CSVelte\Table
32
 * @since v0.1
33
 * @todo On all of the ArrayAccess methods, the docblocks say that $offset can be
34
 *     either an integer offset or a string index, but that isn't true, they must
35
 *     be an integer offset. Fix docblocks.
36
 */
37
abstract class AbstractRow implements Iterator, Countable, ArrayAccess
38
{
39
    /**
40
     * An array of fields for this row
41
     * @var array
42
     */
43
    protected $fields;
44
45
    /**
46
     * Iterator position
47
     * @var int
48
     */
49
    protected $position;
50
51
    /**
52
     * Class constructor
53
     *
54
     * @param array|Iterator An array (or anything that looks like one) of data (fields)
55
     * @access public
56
     */
57 58
    public function __construct($fields)
58
    {
59 58
        $this->setFields($fields)
60 57
             ->rewind();
61 57
    }
62
63 58
    protected function setFields($fields)
64
    {
65 58
        if (!is_array($fields)) {
66 3
            if (is_object($fields) && method_exists($fields, 'toArray')) {
67 1
                $fields = $fields->toArray();
68 3
            } elseif ($fields instanceof Iterator) {
69 1
                $fields = iterator_to_array($fields);
70 1
            } else {
71 1
                throw new InvalidArgumentException(__CLASS__ . " requires an array, got: " . gettype($fields));
72
            }
73 2
        }
74 57
        $this->fields = collect(array_values($fields));
0 ignored issues
show
Documentation Bug introduced by
It seems like \CSVelte\collect(array_values($fields)) of type object<CSVelte\Collection> is incompatible with the declared type array of property $fields.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
75 57
        return $this;
76
    }
77
78 1
    public function __toString()
79
    {
80 1
        return $this->join();
81
    }
82
83
    /**
84
     * Join fields together using specified delimiter
85
     *
86
     * @param char The delimiter character
87
     * @return string
88
     * @access public
89
     */
90 17
    public function join($delimiter = ',')
91
    {
92 17
        return $this->fields->join($delimiter);
0 ignored issues
show
Bug introduced by
The method join cannot be called on $this->fields (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
93
    }
94
95
    /**
96
     * Convert object to an array
97
     *
98
     * @return array representation of the object
99
     * @access public
100
     */
101 25
    public function toArray()
102
    {
103 25
        return $this->fields->toArray();
0 ignored issues
show
Bug introduced by
The method toArray cannot be called on $this->fields (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
104
    }
105
106
    /** Begin SPL Countable Interface Method **/
107
108
    /**
109
     * Count fields within the row
110
     *
111
     * @return integer The amount of fields
112
     * @access public
113
     */
114 20
    public function count()
115
    {
116 20
        return count($this->fields);
117
    }
118
119
    /** Begin SPL Iterator Interface Methods **/
120
121
    /**
122
     * Get the current column's data object
123
     *
124
     * @return string
125
     * @access public
126
     */
127 57
    public function current()
128
    {
129 57
        return $this->fields->getValueAtPosition($this->position);
0 ignored issues
show
Bug introduced by
The method getValueAtPosition cannot be called on $this->fields (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
130
    }
131
132
    /**
133
     * Get the current key (column number or header, if available)
134
     *
135
     * @return string The "current" key
136
     * @access public
137
     * @todo Figure out if this can return a CSVelte\Table\HeaderData object so long as it
138
     *     has a __toString() method that generated the right key...
139
     */
140
    public function key()
141
    {
142
        return $this->position;
143
    }
144
145
    /**
146
     * Advance the internal pointer to the next column's data object
147
     * Also returns the next column's data object if there is one
148
     *
149
     * @return CSVelte\Table\Data The "next" column's data
150
     * @access public
151
     */
152 7
    public function next()
153
    {
154 7
        $this->position++;
155 7
        if ($this->valid()) return $this->current();
156 6
    }
157
158
    /**
159
     * Return the internal pointer to the first column and return that object
160
     *
161
     * @return null|AbstractRow
162
     */
163 57
    public function rewind()
164
    {
165 57
        $this->position = 0;
166 57
        if ($this->valid()) {
167 57
            return $this->current();
168
        }
169
    }
170
171
    /**
172
     * Is the current position within the row's data fields valid?
173
     *
174
     * @return boolean
175
     * @access public
176
     */
177 57
    public function valid()
178
    {
179 57
        return $this->fields->hasPosition($this->position);
0 ignored issues
show
Bug introduced by
The method hasPosition cannot be called on $this->fields (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
180
    }
181
182
    /** Begin SPL ArrayAccess Methods **/
183
184
    /**
185
     * Is there an offset at specified position
186
     *
187
     * @param integer Offset
188
     * @return boolean
189
     * @access public
190
     */
191 2
    public function offsetExists($offset)
192
    {
193 2
        return $this->fields->hasPosition($offset);
0 ignored issues
show
Bug introduced by
The method hasPosition cannot be called on $this->fields (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
194
    }
195
196
    /**
197
     * Retrieve offset at specified position or by header name
198
     *
199
     * @param integer|string Offset/index
200
     * @return CSVelte\Table\Data
201
     * @access public
202
     */
203 1
    public function offsetGet($offset)
204
    {
205 1
        return $this->fields->getValueAtPosition($offset);
0 ignored issues
show
Bug introduced by
The method getValueAtPosition cannot be called on $this->fields (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
206
    }
207
208
    /**
209
     * Set offset at specified position
210
     *
211
     * @param integer|string Offset/index
212
     * @param CSVelte\Table\Data
213
     * @return void
214
     * @access public
215
     * @throws CSVelte\Exception\ImmutableException
216
     */
217 2
    public function offsetSet($offset, $value)
218
    {
219
        // fields are immutable, cannot be set
220 2
        $this->raiseImmutableException();
221
    }
222
223
    /**
224
     * Unset offset at specified position/index
225
     *
226
     * @param integer|string Offset/index
227
     * @return void
228
     * @access public
229
     * @throws CSVelte\Exception\ImmutableException
230
     * @todo I'm not sure if these objects will stay immutable or not yet...
231
     */
232 1
    public function offsetUnset($offset)
233
    {
234 1
        $this->raiseImmutableException();
235
    }
236
237
    /**
238
     * Raise (throw) immutable exception
239
     *
240
     * @param string Message
241
     * @return void
242
     * @access protected
243
     * @throws CSVelte\Exception\ImmutableException
244
     */
245 3
    protected function raiseImmutableException($msg = null)
246
    {
247
        // fields are immutable, cannot be set
248 3
        throw new ImmutableException($msg ?: 'Cannot change immutable column data');
249
    }
250
}
251