Completed
Push — master ( ab1148...78a8ff )
by Christopher
02:58
created

DataReader::setEntries()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 20
rs 9.4285
cc 2
eloc 12
nc 2
nop 1
1
<?php
2
/**
3
 * @link http://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license http://www.yiiframework.com/license/
6
 */
7
8
namespace chrmorandi\ldap;
9
10
use Countable;
11
use Iterator;
12
use Yii;
13
use yii\base\InvalidCallException;
14
use yii\base\Object;
15
16
/**
17
 * DataReader represents a forward-only stream of rows from a query result set.
18
 *
19
 * The method returns [[toArray()]] all the rows in a single array.
20
 * Rows of data can also be read by iterating through the reader. For example,
21
 *
22
 * ```php
23
 * $command = $connection->createCommand('SELECT * FROM post');
24
 * $reader = $command->query();
25
 *
26
 * while ($row = $reader->read()) {
27
 *     $rows[] = $row;
28
 * }
29
 *
30
 * // equivalent to:
31
 * foreach ($reader as $row) {
32
 *     $rows[] = $row;
33
 * }
34
 *
35
 * // equivalent to:
36
 * $rows = $reader->readAll();
37
 * ```
38
 *
39
 * Note that since DataReader is a forward-only stream, you can only traverse it once.
40
 * Doing it the second time will throw an exception.
41
 *
42
 * @property integer $columnCount The number of columns in the result set. This property is read-only.
43
 * @property boolean $isClosed Whether the reader is closed or not. This property is read-only.
44
 * @property integer $rowCount Number of rows contained in the result. This property is read-only.
45
 *
46
 * @author Christopher Mota <[email protected]>
47
 * @since 1.0.0
48
 */
49
class DataReader extends Object implements Iterator, Countable
50
{
51
    /**
52
     * @var array data
53
     */
54
    private $entries = [];   
55
    /**
56
     * @var Connection
57
     */
58
    private $_conn;
59
    private $_closed = false;
60
    private $_row;
61
    private $_index = -1;
62
    private $_count = 0;
63
    private $_results;
64
65
66
    /**
67
     * Constructor.
68
     * @param Connection $conn connection interact with result
69
     * @param resource[]|resource $results result array of search in ldap directory
70
     * @param array $config name-value pairs that will be used to initialize the object properties
71
     */
72
    public function __construct(Connection $conn, $results, $config = [])
73
    {
74
        $this->_conn   = $conn;
75
        $this->_results = $results;
76
77
        if(is_array($this->_results)){
78
            foreach ($this->_results as $result) {
79
                $this->_count += $this->_conn->countEntries($result);
80
                $this->setEntries($result);
81
            }
82
        } else {
83
            $this->_count += $this->_conn->countEntries($this->_results);
84
            $this->setEntries($this->_results);
85
        }
86
        
87
88
        parent::__construct($config);
89
    }
90
    
91
    public function __destruct()
92
    {
93
        $this->close();
94
    }
95
    
96
    /**
97
     * 
98
     * @param resource $result
99
     * @return void
100
     */
101
    protected function setEntries($result){
102
        $identifier = ldap_first_entry(
103
            $this->_conn->resource,
104
            $result
105
        );
106
        
107
        $entries = [];
0 ignored issues
show
Unused Code introduced by
$entries is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
108
109
        while (false !== $identifier) {
110
            $this->entries[] = [
111
                'resource' => $identifier,
112
                'sortValue' => '',
113
            ];
114
115
            $identifier = ldap_next_entry(
116
                $this->_conn->resource,
117
                $identifier
118
            );
119
        }
120
    }
121
122
    /**
123
     * Get all entries as an array
124
     * @return array
125
     */
126
    public function toArray()
127
    {
128
        if ($this->_count <= 0) {
129
            return [];
130
        }
131
        
132
        $data = [];
133
        foreach ($this as $item) {
134
            $data[] = $item;
135
        }
136
        return $data;
137
    }
138
139
    /**
140
     * Closes the reader.
141
     * This frees up the resources allocated for executing this SQL statement.
142
     * Read attempts after this method call are unpredictable.
143
     */
144
    public function close()
145
    {
146
        if (is_resource($this->_results)) {
147
            $this->_closed = ldap_free_result($this->_results);
148
149
            $this->_results = null;
150
            $this->_row = null;
151
        }
152
    }
153
154
    /**
155
     * whether the reader is closed or not.
156
     * @return boolean whether the reader is closed or not.
157
     */
158
    public function getIsClosed()
159
    {
160
        return $this->_closed;
161
    }
162
163
    /**
164
     * Returns the number of rows in the result set.
165
     * This method is required by the Countable interface.
166
     * @return integer number of entries stored in the result.
167
     */
168
    public function count()
169
    {
170
        return $this->_count;
171
    }
172
173
    /**
174
     * Resets the iterator to the initial state.
175
     * This method is required by the interface [[\Iterator]].
176
     * @throws InvalidCallException if this method is invoked twice
177
     */
178
    public function rewind()
179
    {
180
        if ($this->_index < 0) {
181
            reset($this->entries);
182
            $nextEntry = current($this->entries);
183
            $this->_row = $nextEntry['resource'];
184
            $this->_index = 0;
185
        } else {
186
            throw new InvalidCallException('DataReader cannot rewind. It is a forward-only reader.');
187
        }
188
    }
189
190
    /**
191
     * Returns the result of the current item.
192
     * This method is required by the interface [[\Iterator]].
193
     * @return string the index of the current row.
194
     */
195
    public function key()
196
    {
197
        return ldap_get_dn($this->_conn->resource, $this->_row);
198
    }
199
200
    /**
201
     * Returns the current row.
202
     * This method is required by the interface [[\Iterator]].
203
     * @return mixed the current row.
204
     */
205
    public function current()
206
    {
207
        $entry = ['dn' => $this->key()];
208
209
        $resource = $this->_conn->resource;
210
        
211
        $name = ldap_first_attribute($resource, $this->_row);
212
        
213
        while ($name) {
214
            $data = @ldap_get_values_len($resource, $this->_row, $name);
215
216
            if (!$data) {
217
                $data = [];
218
            }
219
220
            if (isset($data['count'])) {
221
                unset($data['count']);
222
            }
223
224
            $attrName = $name;
225
            $entry[$attrName] = implode(",", $data);
226
227
            $name = ldap_next_attribute($resource, $this->_row);
228
        }
229
        
230
        ksort($entry, SORT_LOCALE_STRING);
231
        return $entry;
232
    }
233
234
    /**
235
     * Moves the internal pointer to the next row.
236
     * This method is required by the interface [[\Iterator]].
237
     */
238
    public function next()
239
    {
240
        next($this->entries);
241
        $nextEntry = current($this->entries);
242
        $this->_row = $nextEntry['resource'];
243
        $this->_index++;
244
    }
245
246
    /**
247
     * Returns whether there is a row of resource at current position.
248
     * This method is required by the interface [[\Iterator]].
249
     * @return boolean whether there is a row of data at current position.
250
     */
251
    public function valid()
252
    {
253
        return (is_resource($this->_row));
254
    }
255
}
256