/
InsertIterator.php
134 lines (119 loc) · 3.68 KB
/
InsertIterator.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<?php
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 3.0.0
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Collection\Iterator;
use Cake\Collection\Collection;
/**
* This iterator will insert values into a property of each of the records returned.
* The values to be inserted come out of another traversal object. This is useful
* when you have two separate collections and want to merge them together by placing
* each of the values from one collection into a property inside the other collection.
*/
class InsertIterator extends Collection
{
/**
* The collection from which to extract the values to be inserted
*
* @var \Cake\Collection\Collection
*/
protected $_values;
/**
* Holds whether the values collection is still valid. (has more records)
*
* @var bool
*/
protected $_validValues = true;
/**
* An array containing each of the properties to be traversed to reach the
* point where the values should be inserted.
*
* @var array
*/
protected $_path;
/**
* The property name to which values will be assigned
*
* @var string
*/
protected $_target;
/**
* Constructs a new collection that will dynamically add properties to it out of
* the values found in $values.
*
* @param array|\Traversable $into The target collection to which the values will
* be inserted at the specified path.
* @param string $path A dot separated list of properties that need to be traversed
* to insert the value into the target collection.
* @param array|\Traversable $values The source collection from which the values will
* be inserted at the specified path.
*/
public function __construct($into, $path, $values)
{
parent::__construct($into);
if (!($values instanceof Collection)) {
$values = new Collection($values);
}
$path = explode('.', $path);
$target = array_pop($path);
$this->_path = $path;
$this->_target = $target;
$this->_values = $values;
}
/**
* Advances the cursor to the next record
*
* @return void
*/
public function next()
{
parent::next();
if ($this->_validValues) {
$this->_values->next();
}
$this->_validValues = $this->_values->valid();
}
/**
* Returns the current element in the target collection after inserting
* the value from the source collection into the specified path.
*
* @return mixed
*/
public function current()
{
$row = parent::current();
if (!$this->_validValues) {
return $row;
}
$pointer =& $row;
foreach ($this->_path as $step) {
if (!isset($pointer[$step])) {
return $row;
}
$pointer =& $pointer[$step];
}
$pointer[$this->_target] = $this->_values->current();
return $row;
}
/**
* Resets the collection pointer.
*
* @return void
*/
public function rewind()
{
parent::rewind();
$this->_values->rewind();
$this->_validValues = $this->_values->valid();
}
}