Completed
Pull Request — master (#178)
by ignace nyamagana
02:43
created

Records::fetchOne()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
/**
3
* This file is part of the League.csv library
4
*
5
* @license http://opensource.org/licenses/MIT
6
* @link https://github.com/thephpleague/csv/
7
* @version 8.1.1
8
* @package League.csv
9
*
10
* For the full copyright and license information, please view the LICENSE
11
* file that was distributed with this source code.
12
*/
13
namespace League\Csv;
14
15
use CallbackFilterIterator;
16
use Countable;
17
use DomDocument;
18
use Generator;
19
use Iterator;
20
use IteratorAggregate;
21
use JsonSerializable;
22
use League\Csv\Config\Validator;
23
24
/**
25
 * A class to extract and convert data from a CSV
26
 *
27
 * @package League.csv
28
 * @since  3.0.0
29
 *
30
 */
31
class Records implements Countable, IteratorAggregate, JsonSerializable
32
{
33
    use Validator;
34
35
    /**
36
     * @var array
37
     */
38
    protected $headers;
39
40
    /**
41
     * @var Iterator
42
     */
43
    protected $iterator;
44
45
    /**
46
     * New Instance
47
     *
48
     * @param AbstractCsv $csv
0 ignored issues
show
Bug introduced by
There is no parameter named $csv. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
49
     * @param Query       $query
0 ignored issues
show
Bug introduced by
There is no parameter named $query. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
50
     */
51
    public function __construct(Iterator $iterator, array $headers)
52
    {
53
        $this->iterator = $iterator;
54
        $this->headers = $headers;
55
    }
56
57
    /**
58
     * @inheritdoc
59
     */
60
    public function __destruct()
61
    {
62
        $this->iterator = null;
63
        $this->headers = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array of property $headers.

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...
64
    }
65
66
    /**
67
     * Returns a HTML table representation of the CSV Table
68
     *
69
     * @param string $class_attr optional classname
70
     *
71
     * @return string
72
     */
73
    public function toHTML($class_attr = 'table-csv-data')
74
    {
75
        $doc = $this->toXML('table', 'tr', 'td');
76
        $doc->documentElement->setAttribute('class', $class_attr);
77
78
        return $doc->saveHTML($doc->documentElement);
79
    }
80
81
    /**
82
     * Transforms a CSV into a XML
83
     *
84
     * @param string $root_name XML root node name
85
     * @param string $row_name  XML row node name
86
     * @param string $cell_name XML cell node name
87
     *
88
     * @return DomDocument
89
     */
90
    public function toXML($root_name = 'csv', $row_name = 'row', $cell_name = 'cell')
91
    {
92
        $doc = new DomDocument('1.0', 'UTF-8');
93
        $root = $doc->createElement($root_name);
94
        foreach ($this->iterator as $row) {
95
            $row_element = $doc->createElement($row_name);
96
            array_walk($row, function ($value) use (&$row_element, $doc, $cell_name) {
97
                $content = $doc->createTextNode($value);
98
                $cell = $doc->createElement($cell_name);
99
                $cell->appendChild($content);
100
                $row_element->appendChild($cell);
101
            });
102
            $root->appendChild($row_element);
103
        }
104
        $doc->appendChild($root);
105
106
        return $doc;
107
    }
108
109
    /**
110
     * @inheritdoc
111
     */
112
    public function getIterator()
113
    {
114
        return $this->iterator;
115
    }
116
117
    /**
118
     * @inheritdoc
119
     */
120
    public function count()
121
    {
122
        return iterator_count($this);
123
    }
124
125
    /**
126
     * @inheritdoc
127
     */
128
    public function jsonSerialize()
129
    {
130
        return $this->fetchAll();
131
    }
132
133
    /**
134
     * Returns a sequential array of all founded records
135
     *
136
     * @return array
137
     */
138
    public function fetchAll()
139
    {
140
        return iterator_to_array($this, false);
141
    }
142
143
    /**
144
     * Returns the first row from the founded records
145
     *
146
     * @return array
147
     */
148
    public function fetchOne()
149
    {
150
        $this->iterator->rewind();
151
152
        return (array) $this->iterator->current();
153
    }
154
155
    /**
156
     * Returns the next value from a specific record column
157
     *
158
     * By default if no column index is provided the first column of the founded records is returned
159
     *
160
     * @param int $column_index CSV column index
161
     *
162
     * @return Iterator
163
     */
164
    public function fetchColumn($column_index = 0)
165
    {
166
        $column_index = $this->validateInteger($column_index, 0, 'the column index must be a positive integer or 0');
167
168
        $filter = function ($row) use ($column_index) {
169
            return isset($row[$column_index]);
170
        };
171
172
        $select = function ($row) use ($column_index) {
173
            return $row[$column_index];
174
        };
175
176
        return new MapIterator(new CallbackFilterIterator($this->iterator, $filter), $select);
177
    }
178
179
    /**
180
     * Fetches the next key-value pairs from a result set (first
181
     * column is the key, second column is the value).
182
     *
183
     * By default if no column index is provided:
184
     * - the first CSV column is used to provide the keys
185
     * - the second CSV column is used to provide the value
186
     *
187
     * @param int $offset_id The column index to serve as offset
188
     * @param int $value_id  The column index to serve as value
189
     *
190
     * @return Generator
191
     */
192
    public function fetchPairs($offset_id = 0, $value_id = 1)
193
    {
194
        $offset_id = $this->validateInteger($offset_id, 0, 'the offset column index must be a positive integer or 0');
195
        $value_id = $this->validateInteger($value_id, 0, 'the value column index must be a positive integer or 0');
196
        $filter = function ($row) use ($offset_id) {
197
            return isset($row[$offset_id]);
198
        };
199
        $select = function ($row) use ($offset_id, $value_id) {
200
            return [$row[$offset_id], isset($row[$value_id]) ? $row[$value_id] : null];
201
        };
202
203
        $iterator = new MapIterator(new CallbackFilterIterator($this->iterator, $filter), $select);
204
        foreach ($iterator as $row) {
205
            yield $row[0] => $row[1];
206
        }
207
    }
208
209
    /**
210
     * Fetch the next row from a result set
211
     *
212
     * The rows are presented as associated arrays
213
     *
214
     * @return Iterator
215
     */
216
    public function fetchAssoc()
217
    {
218
        $count = count($this->headers);
219
        $combine_array = function (array $row) use ($count) {
220
            if ($count != count($row)) {
221
                $row = array_slice(array_pad($row, $count, null), 0, $count);
222
            }
223
224
            return array_combine($this->headers, $row);
225
        };
226
227
        return new MapIterator($this->iterator, $combine_array);
228
    }
229
}
230