Skip to content

Commit 9553d59

Browse files
authored
Merge pull request #44 from laminas/3.6.x-merge-up-into-3.7.x_bybmh3M6
Merge release 3.6.3 into 3.7.x
2 parents ca01d74 + abba193 commit 9553d59

File tree

6 files changed

+185
-8
lines changed

6 files changed

+185
-8
lines changed

src/ArrayUtils.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
namespace Laminas\Stdlib;
77

8+
use Iterator;
89
use Laminas\Stdlib\ArrayUtils\MergeRemoveKey;
910
use Laminas\Stdlib\ArrayUtils\MergeReplaceKeyInterface;
1011
use Traversable;
@@ -240,7 +241,11 @@ public static function iteratorToArray($iterator, $recursive = true)
240241
return iterator_to_array($iterator);
241242
}
242243

243-
if (is_object($iterator) && method_exists($iterator, 'toArray')) {
244+
if (
245+
is_object($iterator)
246+
&& ! $iterator instanceof Iterator
247+
&& method_exists($iterator, 'toArray')
248+
) {
244249
return $iterator->toArray();
245250
}
246251

src/Glob.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ protected static function systemGlob($pattern, $flags)
109109
*/
110110
protected static function fallbackGlob($pattern, $flags)
111111
{
112-
if (! $flags & self::GLOB_BRACE) {
112+
if (self::flagsIsEqualTo($flags, self::GLOB_BRACE)) {
113113
return static::systemGlob($pattern, $flags);
114114
}
115115

@@ -195,14 +195,19 @@ protected static function nextBraceSub($pattern, $begin, $flags)
195195
$current = $begin;
196196

197197
while ($current < $length) {
198-
if (! $flags & self::GLOB_NOESCAPE && $pattern[$current] === '\\') {
198+
$flagsEqualsNoEscape = self::flagsIsEqualTo($flags, self::GLOB_NOESCAPE);
199+
200+
if ($flagsEqualsNoEscape && $pattern[$current] === '\\') {
199201
if (++$current === $length) {
200202
break;
201203
}
202204

203205
$current++;
204206
} else {
205-
if (($pattern[$current] === '}' && $depth-- === 0) || ($pattern[$current] === ',' && $depth === 0)) {
207+
if (
208+
($pattern[$current] === '}' && $depth-- === 0)
209+
|| ($pattern[$current] === ',' && $depth === 0)
210+
) {
206211
break;
207212
} elseif ($pattern[$current++] === '{') {
208213
$depth++;
@@ -212,4 +217,10 @@ protected static function nextBraceSub($pattern, $begin, $flags)
212217

213218
return $current < $length ? $current : null;
214219
}
220+
221+
/** @internal */
222+
public static function flagsIsEqualTo(int $flags, int $otherFlags): bool
223+
{
224+
return (bool) ($flags & $otherFlags);
225+
}
215226
}

test/ArrayUtilsTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Laminas\Stdlib\ArrayUtils\MergeReplaceKeyInterface;
1212
use Laminas\Stdlib\Exception\InvalidArgumentException;
1313
use Laminas\Stdlib\Parameters;
14+
use LaminasTest\Stdlib\TestAsset\IteratorWithToArrayMethod;
1415
use PHPUnit\Framework\TestCase;
1516
use stdClass;
1617
use Traversable;
@@ -579,4 +580,30 @@ public function testInvalidCallableRaiseInvalidArgumentException(): void
579580
$this->expectException(InvalidArgumentException::class);
580581
ArrayUtils::filter([], "INVALID");
581582
}
583+
584+
/**
585+
* @link https://github.com/laminas/laminas-stdlib/issues/18
586+
*/
587+
public function testIteratorToArrayWithIteratorHavingMethodToArrayAndRecursiveIsFalse(): void
588+
{
589+
$arrayB = [
590+
'foo' => 'bar',
591+
];
592+
$iteratorB = new IteratorWithToArrayMethod($arrayB);
593+
594+
$arrayA = [
595+
'iteratorB' => $iteratorB,
596+
];
597+
$iterator = new IteratorWithToArrayMethod($arrayA);
598+
599+
$result = ArrayUtils::iteratorToArray($iterator, true);
600+
601+
$expectedResult = [
602+
'iteratorB' => [
603+
'foo' => 'bar',
604+
],
605+
];
606+
607+
$this->assertEquals($expectedResult, $result);
608+
}
582609
}

test/GlobTest.php

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use function count;
1212
use function defined;
1313
use function glob;
14+
use function realpath;
1415
use function str_repeat;
1516

1617
use const GLOB_BRACE;
@@ -23,15 +24,29 @@ public function testFallback(): void
2324
$this->markTestSkipped('GLOB_BRACE not available');
2425
}
2526

26-
self::assertEquals(
27-
glob(__DIR__ . '/_files/{alph,bet}a', GLOB_BRACE),
28-
Glob::glob(__DIR__ . '/_files/{alph,bet}a', Glob::GLOB_BRACE, true)
27+
$expected = glob(__DIR__ . '/_files/{alph,bet}a', GLOB_BRACE);
28+
$actual = Glob::glob(
29+
__DIR__ . '/_files/{alph,bet}a',
30+
Glob::GLOB_BRACE,
31+
true
32+
);
33+
34+
self::assertEquals($actual, $expected);
35+
36+
$notExpectedPath = realpath(__DIR__ . '/_files/{alph,bet}a');
37+
38+
self::assertNotContains(
39+
$notExpectedPath,
40+
$actual
2941
);
3042
}
3143

3244
public function testNonMatchingGlobReturnsArray(): void
3345
{
34-
$result = Glob::glob('/some/path/{,*.}{this,orthis}.php', Glob::GLOB_BRACE);
46+
$result = Glob::glob(
47+
'/some/path/{,*.}{this,orthis}.php',
48+
Glob::GLOB_BRACE
49+
);
3550
self::assertIsArray($result);
3651
}
3752

@@ -80,4 +95,56 @@ public function patternsProvider(): array
8095
],
8196
];
8297
}
98+
99+
public function testGlobWithoutGlobBraceFlag(): void
100+
{
101+
$expected = [
102+
realpath(__DIR__ . '/_files/{alph,bet}a'),
103+
];
104+
105+
self::assertEquals(
106+
glob(__DIR__ . '/_files/{alph,bet}a', 0),
107+
$expected
108+
);
109+
}
110+
111+
/**
112+
* @psalm-return array<array-key, array{
113+
* int,
114+
* int,
115+
* bool
116+
* }>
117+
*/
118+
public function flagsIsEqualsToMethodDataProvider(): array
119+
{
120+
return [
121+
[
122+
Glob::GLOB_BRACE,
123+
Glob::GLOB_BRACE,
124+
true,
125+
],
126+
[
127+
Glob::GLOB_BRACE,
128+
Glob::GLOB_NOSORT,
129+
false,
130+
],
131+
];
132+
}
133+
134+
/**
135+
* @dataProvider flagsIsEqualsToMethodDataProvider
136+
*/
137+
public function testFlagsIsEqualsToMethod(
138+
int $flags,
139+
int $otherFlags,
140+
bool $expected
141+
): void {
142+
/**
143+
* @psalm-suppress InternalMethod this test is specifically testing the behavior of this method,
144+
* to prevent regressions
145+
*/
146+
$actual = Glob::flagsIsEqualTo($flags, $otherFlags);
147+
148+
$this->assertEquals($expected, $actual);
149+
}
83150
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace LaminasTest\Stdlib\TestAsset;
6+
7+
use Iterator;
8+
use ReturnTypeWillChange;
9+
10+
use function current;
11+
use function key;
12+
use function next;
13+
use function reset;
14+
15+
class IteratorWithToArrayMethod implements Iterator
16+
{
17+
/** @var array */
18+
private $elements = [];
19+
20+
public function __construct(array $elements)
21+
{
22+
$this->elements = $elements;
23+
}
24+
25+
/** @return void */
26+
#[ReturnTypeWillChange]
27+
public function rewind()
28+
{
29+
reset($this->elements);
30+
}
31+
32+
/** @return mixed */
33+
#[ReturnTypeWillChange]
34+
public function current()
35+
{
36+
return current($this->elements);
37+
}
38+
39+
/** @return int|string */
40+
#[ReturnTypeWillChange]
41+
public function key()
42+
{
43+
return key($this->elements);
44+
}
45+
46+
/** @return mixed */
47+
#[ReturnTypeWillChange]
48+
public function next()
49+
{
50+
return next($this->elements);
51+
}
52+
53+
/** @return bool */
54+
#[ReturnTypeWillChange]
55+
public function valid()
56+
{
57+
$key = key($this->elements);
58+
return $key !== null && $key !== false;
59+
}
60+
61+
public function toArray(): array
62+
{
63+
return [
64+
'data from to array' => 'not good',
65+
];
66+
}
67+
}

test/_files/{alph,bet}a

Whitespace-only changes.

0 commit comments

Comments
 (0)