Skip to content

Commit 991e85d

Browse files
Merge pull request #48 from tlueder/Fix-ObjectStorage-int
Allow index for ObjectStorage to be int
2 parents df2b6e6 + 3a28b6b commit 991e85d

File tree

3 files changed

+136
-4
lines changed

3 files changed

+136
-4
lines changed

stubs/ObjectStorage.stub

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,61 @@
22
namespace TYPO3\CMS\Extbase\Persistence;
33

44
/**
5-
* @template T
6-
* @implements \ArrayAccess<string, T>
7-
* @implements \Iterator<string, T>
5+
* @template TEntity
6+
* @implements \ArrayAccess<int, TEntity>
7+
* @implements \Iterator<int, TEntity>
8+
* @phpstan-type ObjectStorageInternal array{obj: TEntity, inf: mixed}
89
*/
9-
class ObjectStorage implements \ArrayAccess, \Iterator
10+
class ObjectStorage implements \Iterator, \ArrayAccess
1011
{
12+
/**
13+
* @var array<string, ObjectStorageInternal>
14+
*/
15+
protected $storage;
16+
17+
/**
18+
* @param TEntity $value
19+
* @param mixed $information
20+
*/
21+
public function offsetSet($value, $information);
22+
23+
/**
24+
* @param TEntity|int $value
25+
* @return bool
26+
*/
27+
public function offsetExists($value);
28+
29+
/**
30+
* @param TEntity|int $value
31+
*/
32+
public function offsetUnset($value);
33+
34+
/**
35+
* @param TEntity|int $value
36+
* @return ($value is int ? TEntity|null : mixed)
37+
*/
38+
public function offsetGet($value);
39+
40+
/**
41+
* This is different from the SplObjectStorage as the key in this implementation is the object hash (string).
42+
* @phpstan-ignore-next-line See https://forge.typo3.org/issues/98146
43+
* @return string|null
44+
*/
45+
public function key();
46+
47+
/**
48+
* @return array<TEntity>
49+
*/
50+
public function toArray();
51+
52+
/**
53+
* @return array<TEntity>
54+
*/
55+
public function getArray();
56+
57+
/**
58+
* @param TEntity $object
59+
* @return bool
60+
*/
61+
public function isRelationDirty($object);
1162
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace SaschaEgerer\PhpstanTypo3\Tests\Unit\Type;
4+
5+
use PHPStan\Testing\TypeInferenceTestCase;
6+
7+
class ObjectStorageStubFileTest extends TypeInferenceTestCase
8+
{
9+
10+
/**
11+
* @return iterable<mixed>
12+
*/
13+
public function dataFileAsserts(): iterable
14+
{
15+
yield from $this->gatherAssertTypes(__DIR__ . '/data/object-storage-stub-files.php');
16+
}
17+
18+
/**
19+
* @dataProvider dataFileAsserts
20+
* @param string $assertType
21+
* @param string $file
22+
* @param mixed ...$args
23+
*/
24+
public function testFileAsserts(
25+
string $assertType,
26+
string $file,
27+
...$args
28+
): void
29+
{
30+
$this->assertFileAsserts($assertType, $file, ...$args);
31+
}
32+
33+
public static function getAdditionalConfigFiles(): array
34+
{
35+
return [__DIR__ . '/../../../extension.neon'];
36+
}
37+
38+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php declare(strict_types = 1);
2+
3+
// phpcs:disable SlevomatCodingStandard.Namespaces.RequireOneNamespaceInFile.MoreNamespacesInFile
4+
// phpcs:disable Squiz.Classes.ClassFileName.NoMatch
5+
// phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses
6+
7+
namespace ObjectStorage\My\Test\Extension\Domain\Model;
8+
9+
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
10+
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
11+
use function PHPStan\Testing\assertType;
12+
13+
class MyModel extends AbstractEntity
14+
{
15+
16+
/** @var ObjectStorage<MyModel> */
17+
protected ObjectStorage $objectStorage;
18+
19+
public function foo(): void
20+
{
21+
$myModel = new MyModel();
22+
$this->objectStorage = new ObjectStorage();
23+
$this->objectStorage->attach($myModel);
24+
25+
assertType('TYPO3\CMS\Extbase\Persistence\ObjectStorage<' . self::class . '>', $this->objectStorage);
26+
27+
foreach ($this->objectStorage as $key => $value) {
28+
assertType('int', $key);
29+
assertType(self::class, $value);
30+
}
31+
32+
assertType(self::class . '|null', $this->objectStorage->offsetGet(0));
33+
34+
// We ignore errors in the next line as this will produce an
35+
// "Offset 0 does not exist on TYPO3\CMS\Extbase\Persistence\ObjectStorage<ObjectStorage\My\Test\Extension\Domain\Model\MyModel>
36+
// due to the weird implementation of ArrayAccess in ObjectStorage::offsetGet()
37+
// @phpstan-ignore-next-line
38+
assertType(self::class . '|null', $this->objectStorage[0]);
39+
40+
assertType('mixed', $this->objectStorage->offsetGet($myModel));
41+
}
42+
43+
}

0 commit comments

Comments
 (0)