Skip to content

Commit 2eaa7cc

Browse files
committed
initial commit
0 parents  commit 2eaa7cc

File tree

12 files changed

+264
-0
lines changed

12 files changed

+264
-0
lines changed

.editorconfig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
insert_final_newline = true
7+
trim_trailing_whitespace = true
8+
indent_style = tab
9+
indent_size = tab
10+
tab_width = 4
11+
12+
[*.yml]
13+
indent_style = space
14+
indent_size = 4
15+
16+
[composer.json]
17+
indent_style = space
18+
indent_size = 4

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
## ide
2+
/.idea/
3+
4+
## composer
5+
/composer.lock
6+
/vendor/

.travis.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
language: php
2+
php:
3+
- 7.4
4+
5+
before_install:
6+
- phpenv config-rm xdebug.ini || return 0 # Turn off XDebug
7+
8+
install:
9+
- travis_retry composer install --no-progress --prefer-dist # Install dependencies
10+
11+
after_failure:
12+
- for i in $(find tests -name \*.actual); do echo "--- $i"; cat $i; echo; echo; done # Print *.actual content
13+
14+
jobs:
15+
include:
16+
- stage: Tests
17+
php: 7.4
18+
script:
19+
- make tests
20+
21+
- stage: Code style
22+
php: 7.4
23+
script:
24+
- make cs
25+
26+
- stage: PHPStan
27+
php: 7.4
28+
script:
29+
- make phpstan
30+
31+
sudo: false
32+
33+
cache:
34+
directories:
35+
- $HOME/.composer/cache

LICENSE

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
MIT License
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
SOFTWARE.

Makefile

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
.PHONY: phpstan tests cs csfix lint
2+
3+
check: tests cs phpstan lint
4+
5+
vendor: composer.json composer.lock
6+
composer install
7+
8+
tests: vendor
9+
vendor/bin/tester -s -p php --colors 1 -C tests/cases
10+
11+
lint: vendor
12+
vendor/bin/linter src tests
13+
14+
cs: vendor
15+
vendor/bin/codesniffer src tests
16+
17+
csfix: vendor
18+
vendor/bin/codefixer src tests
19+
20+
phpstan: vendor
21+
vendor/bin/phpstan analyse -l max -c phpstan.neon src

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
## doctrine utility
2+
3+
[![Build Status](https://travis-ci.org/utilitte/doctrine.svg?branch=master)](https://travis-ci.org/utilitte/doctrine)
4+
[![Licence](https://img.shields.io/packagist/l/utilitte/doctrine.svg)](https://packagist.org/packages/utilitte/doctrine)
5+
[![Latest stable](https://img.shields.io/packagist/v/utilitte/doctrine.svg)](https://packagist.org/packages/utilitte/doctrine)

composer.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "utilitte/doctrine",
3+
"description": "",
4+
"license": "proprietary",
5+
"type": "library",
6+
"require": {
7+
"php": ">=7.4",
8+
"utilitte/php": "^1.0",
9+
"doctrine/orm": "^2.7",
10+
"doctrine/collections": "^1.6"
11+
},
12+
"require-dev": {
13+
"phpstan/phpstan": "^0.12.33",
14+
"phpstan/extension-installer": "^1.0",
15+
"phpstan/phpstan-deprecation-rules": "^0.12.2",
16+
"utilitte/qa": "~1.0.0",
17+
"nette/tester": "^2.3.0"
18+
},
19+
"autoload": {
20+
"psr-4": {
21+
"Utilitte\\Doctrine\\": "src/"
22+
}
23+
}
24+
}

phpstan.neon

Whitespace-only changes.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Utilitte\Doctrine\Association;
4+
5+
use Doctrine\Common\Collections\Collection;
6+
use Utilitte\Php\Arrays;
7+
use Utilitte\Php\ValueObject\ArraySynchronized;
8+
9+
final class ArrayCollectionSynchronizer
10+
{
11+
12+
public const REMOVE = 0b0001;
13+
public const ADD = 0b0010;
14+
15+
/**
16+
* @template T of object
17+
* @phpstan-param Collection<mixed, T> $collection
18+
* @phpstan-param T[] $values
19+
* @param object[] $values
20+
*/
21+
public static function synchronize(
22+
Collection $collection,
23+
array $values,
24+
int $options = self::ADD | self::REMOVE
25+
): ArraySynchronized
26+
{
27+
return self::synchronizeByComparator($collection, $values, null, $options);
28+
}
29+
30+
/**
31+
* @template T of object
32+
* @phpstan-param Collection<mixed, T> $collection
33+
* @phpstan-param T[] $values
34+
* @param object[] $values
35+
*/
36+
public static function synchronizeByComparator(
37+
Collection $collection,
38+
array $values,
39+
?callable $comparator = null,
40+
int $options = self::ADD | self::REMOVE
41+
): ArraySynchronized
42+
{
43+
$synchronized = Arrays::synchronize($collection->toArray(), $values, $comparator);
44+
45+
if ($opRemove = $options & self::REMOVE) {
46+
foreach ($synchronized->getRemoved() as $key => $_) {
47+
$collection->remove($key);
48+
}
49+
}
50+
51+
if ($opAdd = $options & self::ADD) {
52+
foreach ($synchronized->getAdded() as $element) {
53+
$collection->add($element);
54+
}
55+
}
56+
57+
return new ArraySynchronized(
58+
$opAdd ? $synchronized->getAdded() : [],
59+
$opRemove ? $synchronized->getRemoved() : [],
60+
$collection->toArray()
61+
);
62+
}
63+
64+
}

src/DoctrineIdentityExtractor.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Utilitte\Doctrine;
4+
5+
use Doctrine\ORM\EntityManagerInterface;
6+
use InvalidArgumentException;
7+
8+
final class DoctrineIdentityExtractor
9+
{
10+
11+
private EntityManagerInterface $em;
12+
13+
public function __construct(EntityManagerInterface $em)
14+
{
15+
$this->em = $em;
16+
}
17+
18+
/**
19+
* @param object[] $entities
20+
* @return mixed[]
21+
*/
22+
public function extractIdentities(iterable $entities, bool $allowMixing = false): array
23+
{
24+
$type = null;
25+
$ids = [];
26+
27+
foreach ($entities as $entity) {
28+
if (!is_object($entity)) {
29+
throw new InvalidArgumentException(
30+
sprintf('Given array must be an array of object, %s contained in array', gettype($entity))
31+
);
32+
}
33+
34+
$className = get_class($entity);
35+
36+
if (!$allowMixing) {
37+
$this->checkType($className, $type);
38+
}
39+
40+
$values = $this->em->getClassMetadata($className)->getIdentifierValues($entity);
41+
$ids[] = current($values);
42+
}
43+
44+
return $ids;
45+
}
46+
47+
private function checkType(string $class, ?string $type): void
48+
{
49+
if (!$type) {
50+
return;
51+
}
52+
53+
if ($type !== $class) {
54+
throw new InvalidArgumentException(
55+
sprintf('Given array must be an array of %s, %s contained in array', $type, $class)
56+
);
57+
}
58+
}
59+
60+
}

0 commit comments

Comments
 (0)