MappedIterator::current()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 0
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Convenience class for generating iterators from iterators.
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License along
16
 * with this program; if not, write to the Free Software Foundation, Inc.,
17
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
 * http://www.gnu.org/copyleft/gpl.html
19
 *
20
 * @file
21
 * @author Aaron Schulz
22
 */
23
24
/**
25
 * Convenience class for generating iterators from iterators.
26
 *
27
 * @since 1.21
28
 */
29
class MappedIterator extends FilterIterator {
30
	/** @var callable */
31
	protected $vCallback;
32
	/** @var callable */
33
	protected $aCallback;
34
	/** @var array */
35
	protected $cache = [];
36
37
	protected $rewound = false; // boolean; whether rewind() has been called
38
39
	/**
40
	 * Build an new iterator from a base iterator by having the former wrap the
41
	 * later, returning the result of "value" callback for each current() invocation.
42
	 * The callback takes the result of current() on the base iterator as an argument.
43
	 * The keys of the base iterator are reused verbatim.
44
	 *
45
	 * An "accept" callback can also be provided which will be called for each value in
46
	 * the base iterator (post-callback) and will return true if that value should be
47
	 * included in iteration of the MappedIterator (otherwise it will be filtered out).
48
	 *
49
	 * @param Iterator|Array $iter
50
	 * @param callable $vCallback Value transformation callback
51
	 * @param array $options Options map (includes "accept") (since 1.22)
52
	 * @throws UnexpectedValueException
53
	 */
54
	public function __construct( $iter, $vCallback, array $options = [] ) {
55
		if ( is_array( $iter ) ) {
56
			$baseIterator = new ArrayIterator( $iter );
57
		} elseif ( $iter instanceof Iterator ) {
58
			$baseIterator = $iter;
59
		} else {
60
			throw new UnexpectedValueException( "Invalid base iterator provided." );
61
		}
62
		parent::__construct( $baseIterator );
63
		$this->vCallback = $vCallback;
64
		$this->aCallback = isset( $options['accept'] ) ? $options['accept'] : null;
65
	}
66
67
	public function next() {
68
		$this->cache = [];
69
		parent::next();
70
	}
71
72
	public function rewind() {
73
		$this->rewound = true;
74
		$this->cache = [];
75
		parent::rewind();
76
	}
77
78
	public function accept() {
79
		$value = call_user_func( $this->vCallback, $this->getInnerIterator()->current() );
80
		$ok = ( $this->aCallback ) ? call_user_func( $this->aCallback, $value ) : true;
81
		if ( $ok ) {
82
			$this->cache['current'] = $value;
83
		}
84
85
		return $ok;
86
	}
87
88
	public function key() {
89
		$this->init();
90
91
		return parent::key();
92
	}
93
94
	public function valid() {
95
		$this->init();
96
97
		return parent::valid();
98
	}
99
100
	public function current() {
101
		$this->init();
102
		if ( parent::valid() ) {
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (valid() instead of current()). Are you sure this is correct? If so, you might want to change this to $this->valid().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
103
			return $this->cache['current'];
104
		} else {
105
			return null; // out of range
106
		}
107
	}
108
109
	/**
110
	 * Obviate the usual need for rewind() before using a FilterIterator in a manual loop
111
	 */
112
	protected function init() {
113
		if ( !$this->rewound ) {
114
			$this->rewind();
115
		}
116
	}
117
}
118