Skip to content

Commit 05a3bd1

Browse files
authored
Added basic Pool implementation (#428)
* Added basic Pool implementation * Added PHPStan errors to the baseline
1 parent b9f1582 commit 05a3bd1

File tree

4 files changed

+229
-0
lines changed

4 files changed

+229
-0
lines changed

phpstan-baseline.neon

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21125,6 +21125,21 @@ parameters:
2112521125
count: 1
2112621126
path: src/lib/Repository/URLWildcardService.php
2112721127

21128+
-
21129+
message: "#^Result of \\|\\| is always false\\.$#"
21130+
count: 1
21131+
path: src/lib/Repository/URLWildcardService.php
21132+
21133+
-
21134+
message: "#^Variable \\$patterns in empty\\(\\) always exists and is not falsy\\.$#"
21135+
count: 1
21136+
path: src/lib/Repository/URLWildcardService.php
21137+
21138+
-
21139+
message: "#^Variable \\$placeholders in empty\\(\\) always exists and is not falsy\\.$#"
21140+
count: 1
21141+
path: src/lib/Repository/URLWildcardService.php
21142+
2112821143
-
2112921144
message: "#^Parameter \\#3 \\$hashType of method Ibexa\\\\Contracts\\\\Core\\\\Repository\\\\PasswordHashService\\:\\:isValidPassword\\(\\) expects int\\|null, string given\\.$#"
2113021145
count: 1

src/contracts/Pool/Pool.php

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Contracts\Core\Pool;
10+
11+
use Ibexa\Core\Base\Exceptions\InvalidArgumentException;
12+
13+
/**
14+
* @template T of object
15+
* @implements \Ibexa\Contracts\Core\Pool\PoolInterface<T>
16+
*/
17+
final class Pool implements PoolInterface
18+
{
19+
private const DEFAULT_EXCEPTION_MESSAGE_TEMPLATE = 'Could not find %s for \'%s\'. Valid values are: %s';
20+
21+
private string $class;
22+
23+
/** @var iterable<string,T> */
24+
private iterable $entries;
25+
26+
private string $exceptionArgumentName = '$alias';
27+
28+
private string $exceptionMessageTemplate = self::DEFAULT_EXCEPTION_MESSAGE_TEMPLATE;
29+
30+
/**
31+
* @param iterable<string,T> $entries
32+
*/
33+
public function __construct(string $class, iterable $entries = [])
34+
{
35+
$this->class = $class;
36+
$this->entries = $entries;
37+
}
38+
39+
public function has(string $alias): bool
40+
{
41+
return $this->findEntry($alias) !== null;
42+
}
43+
44+
/**
45+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
46+
*
47+
* @return T
48+
*/
49+
public function get(string $alias)
50+
{
51+
$entry = $this->findEntry($alias);
52+
53+
if ($entry === null) {
54+
$entriesAliases = $this->getEntriesAliases();
55+
$availableAliases = empty($entriesAliases) ? '' : "'" . implode("', '", $entriesAliases) . "'";
56+
57+
throw new InvalidArgumentException(
58+
$this->exceptionArgumentName,
59+
sprintf($this->exceptionMessageTemplate, $this->class, $alias, $availableAliases)
60+
);
61+
}
62+
63+
return $entry;
64+
}
65+
66+
/**
67+
* @return T|null
68+
*/
69+
private function findEntry(string $needle)
70+
{
71+
foreach ($this->entries as $type => $mapper) {
72+
if ($needle === $type) {
73+
return $mapper;
74+
}
75+
}
76+
77+
return null;
78+
}
79+
80+
/**
81+
* @return iterable<string,T>
82+
*/
83+
public function getEntries(): iterable
84+
{
85+
return $this->entries;
86+
}
87+
88+
/**
89+
* @return string[]
90+
*/
91+
private function getEntriesAliases(): array
92+
{
93+
$aliases = [];
94+
foreach ($this->entries as $alias => $entry) {
95+
$aliases[] = $alias;
96+
}
97+
98+
return $aliases;
99+
}
100+
101+
public function setExceptionArgumentName(string $exceptionArgumentName): void
102+
{
103+
$this->exceptionArgumentName = $exceptionArgumentName;
104+
}
105+
106+
public function setExceptionMessageTemplate(string $exceptionMessageTemplate): void
107+
{
108+
$this->exceptionMessageTemplate = $exceptionMessageTemplate;
109+
}
110+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Contracts\Core\Pool;
10+
11+
/**
12+
* @template T of object
13+
*/
14+
interface PoolInterface
15+
{
16+
public function has(string $alias): bool;
17+
18+
/**
19+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException
20+
*
21+
* @return T
22+
*/
23+
public function get(string $alias);
24+
25+
/**
26+
* @return iterable<string,T>
27+
*/
28+
public function getEntries(): iterable;
29+
30+
public function setExceptionArgumentName(string $exceptionArgumentName): void;
31+
32+
public function setExceptionMessageTemplate(string $exceptionMessageTemplate): void;
33+
}

tests/lib/Pool/PoolTest.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Tests\Core\Pool;
10+
11+
use Ibexa\Contracts\Core\Pool\Pool;
12+
use Ibexa\Core\Base\Exceptions\InvalidArgumentException;
13+
use PHPUnit\Framework\TestCase;
14+
use stdClass;
15+
16+
final class PoolTest extends TestCase
17+
{
18+
private stdClass $foo;
19+
20+
private stdClass $bar;
21+
22+
/** @var \Ibexa\Contracts\Core\Pool\Pool<\stdClass> */
23+
private Pool $pool;
24+
25+
protected function setUp(): void
26+
{
27+
$this->foo = new stdClass();
28+
$this->bar = new stdClass();
29+
$entries = [
30+
'foo' => $this->foo,
31+
'bar' => $this->bar,
32+
];
33+
34+
$this->pool = new Pool(
35+
stdClass::class,
36+
$entries
37+
);
38+
}
39+
40+
public function testHas(): void
41+
{
42+
self::assertTrue($this->pool->has('foo'));
43+
self::assertFalse($this->pool->has('baz'));
44+
}
45+
46+
public function testGet(): void
47+
{
48+
self::assertSame($this->foo, $this->pool->get('foo'));
49+
50+
$this->expectException(InvalidArgumentException::class);
51+
$this->expectExceptionMessage(
52+
sprintf(
53+
"Argument '%s' is invalid: Could not find stdClass for 'baz'. Valid values are: 'foo', 'bar'",
54+
'$alias'
55+
)
56+
);
57+
58+
$this->pool->get('baz');
59+
}
60+
61+
public function testGetEntries(): void
62+
{
63+
self::assertSame(
64+
[
65+
'foo' => $this->foo,
66+
'bar' => $this->bar,
67+
],
68+
$this->pool->getEntries()
69+
);
70+
}
71+
}

0 commit comments

Comments
 (0)