ProtectedReferencesChecker   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 85
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 45
dl 0
loc 85
rs 10
c 0
b 0
f 0
wmc 14

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
B findProtectedIdsByClass() 0 28 7
B checkReferenceForProtection() 0 29 6
1
<?php
2
3
/*
4
 * This file is part of the OneGuard DynamicConfigurationBundle.
5
 *
6
 * (c) OneGuard <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace OneGuard\Bundle\DynamicConfigurationBundle;
13
14
use OneGuard\Bundle\DynamicConfigurationBundle\Entity\ConfigurationValue;
15
use OneGuard\Bundle\DynamicConfigurationBundle\Exception\ProtectedReferenceException;
16
use Symfony\Bridge\Doctrine\RegistryInterface;
17
18
class ProtectedReferencesChecker {
19
	/**
20
	 * @var RegistryInterface
21
	 */
22
	private $doctrine;
23
	/**
24
	 * @var DefinitionRegistry
25
	 */
26
	private $registry;
27
28
	public function __construct(RegistryInterface $doctrine, DefinitionRegistry $registry) {
29
		$this->doctrine = $doctrine;
30
		$this->registry = $registry;
31
	}
32
33
	/**
34
	 * @param string $class
35
	 * @param array|null $ids
36
	 * @return array
37
	 */
38
	public function findProtectedIdsByClass(string $class, array $ids = null) : array {
39
		$keys = [];
40
		foreach ($this->registry->keys() as $key) {
41
			$definition = $this->registry->get($key);
42
			if ($definition instanceof EntityDefinition and is_a($class, $definition->getClass(), true)) {
43
				$keys[] = $definition->getKey();
44
			}
45
		}
46
47
		if (empty($keys)) {
48
			return [];
49
		}
50
51
		$qb = $this->doctrine->getEntityManagerForClass(ConfigurationValue::class)->createQueryBuilder();
52
		$qb
53
			->select('DISTINCT (v.value)')
54
			->from(ConfigurationValue::class, 'v')
55
			->where($qb->expr()->in('v.key', ':keys'))
56
			->setParameter('keys', $keys);
57
58
		if ($ids !== null) {
59
			$qb
60
				->andWhere($qb->expr()->in('v.value', ':ids'))
61
				->setParameter('ids', $ids);
62
		}
63
64
		$protectedIds = $qb->getQuery()->getScalarResult();
65
		return empty($protectedIds) ? [] : array_merge(...$protectedIds);
66
	}
67
68
	/**
69
	 * @param $object
70
	 * @throws ProtectedReferenceException
71
	 * @throws \Doctrine\ORM\NoResultException
72
	 * @throws \Doctrine\ORM\NonUniqueResultException
73
	 */
74
	public function checkReferenceForProtection($object) {
75
		$id = $this->doctrine->getEntityManagerForClass(get_class($object))->getUnitOfWork()->getSingleIdentifierValue($object);
76
77
		$keys = [];
78
		foreach ($this->registry->keys() as $key) {
79
			$definition = $this->registry->get($key);
80
			if ($definition instanceof EntityDefinition and is_a($object, $definition->getClass())) {
81
				$keys[] = $definition->getKey();
82
			}
83
		}
84
85
		if (empty($keys)) {
86
			return;
87
		}
88
89
		$repo = $this->doctrine->getEntityManagerForClass(ConfigurationValue::class);
90
		$qb = $repo->createQueryBuilder();
91
		$countProtected = $qb
92
			->select('count(v)')
93
			->from(ConfigurationValue::class, 'v')
94
			->where($qb->expr()->in('v.key', ':keys'))
95
			->andWhere($qb->expr()->eq('v.value', ':id'))
96
			->getQuery()
97
			->setParameter('keys', $keys)
98
			->setParameter('id', $id)
99
			->getSingleScalarResult();
100
101
		if ($countProtected > 0) {
102
			throw new ProtectedReferenceException("Can't delete protected reference.");
103
		}
104
	}
105
}
106