Failed Conditions
Push — master ( 901929...f6cc12 )
by Jonathan
11:18
created

readOnlyRequiresManagedEntity()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\ORM;
6
7
use Doctrine\ORM\Mapping\AssociationMetadata;
8
use Doctrine\ORM\Mapping\ClassMetadata;
9
use function array_map;
10
use function count;
11
use function get_class;
12
use function gettype;
13
use function implode;
14
use function is_object;
15
use function method_exists;
16
use function reset;
17
use function spl_object_id;
18
use function sprintf;
19
20
/**
21
 * Contains exception messages for all invalid lifecycle state exceptions inside UnitOfWork
22
 */
23
class ORMInvalidArgumentException extends \InvalidArgumentException
24
{
25
    /**
26
     * @param object $entity
27
     *
28
     * @return ORMInvalidArgumentException
29
     */
30 1
    public static function scheduleInsertForManagedEntity($entity)
31
    {
32 1
        return new self('A managed+dirty entity ' . self::objToStr($entity) . ' can not be scheduled for insertion.');
33
    }
34
35
    /**
36
     * @param object $entity
37
     *
38
     * @return ORMInvalidArgumentException
39
     */
40 1
    public static function scheduleInsertForRemovedEntity($entity)
41
    {
42 1
        return new self('Removed entity ' . self::objToStr($entity) . ' can not be scheduled for insertion.');
43
    }
44
45
    /**
46
     * @param object $entity
47
     *
48
     * @return ORMInvalidArgumentException
49
     */
50 1
    public static function scheduleInsertTwice($entity)
51
    {
52 1
        return new self('Entity ' . self::objToStr($entity) . ' can not be scheduled for insertion twice.');
53
    }
54
55
    /**
56
     * @param string $className
57
     * @param object $entity
58
     *
59
     * @return ORMInvalidArgumentException
60
     */
61 6
    public static function entityWithoutIdentity($className, $entity)
62
    {
63 6
        return new self(
64 6
            "The given entity of type '" . $className . "' (" . self::objToStr($entity) . ') has no identity/no ' .
65 6
            'id values set. It cannot be added to the identity map.'
66
        );
67
    }
68
69
    /**
70
     * @param object $entity
71
     *
72
     * @return ORMInvalidArgumentException
73
     */
74 1
    public static function readOnlyRequiresManagedEntity($entity)
75
    {
76 1
        return new self('Only managed entities can be marked or checked as read only. But ' . self::objToStr($entity) . ' is not');
77
    }
78
79
    /**
80
     * @param array[][]|object[][] $newEntitiesWithAssociations non-empty an array of [$associationMetadata, $entity] pairs
81
     *
82
     * @return ORMInvalidArgumentException
83
     */
84 4
    public static function newEntitiesFoundThroughRelationships($newEntitiesWithAssociations)
85
    {
86 4
        $errorMessages = array_map(
87
            function (array $newEntityWithAssociation) : string {
88 4
                [$associationMetadata, $entity] = $newEntityWithAssociation;
89
90 4
                return self::newEntityFoundThroughRelationshipMessage($associationMetadata, $entity);
91 4
            },
92 4
            $newEntitiesWithAssociations
93
        );
94
95 4
        if (count($errorMessages) === 1) {
96 4
            return new self(reset($errorMessages));
97
        }
98
99
        return new self(
100
            'Multiple non-persisted new entities were found through the given association graph:'
101
            . "\n\n * "
102
            . implode("\n * ", $errorMessages)
103
        );
104
    }
105
106
    /**
107
     * @param object $entry
108
     *
109
     * @return ORMInvalidArgumentException
110
     */
111
    public static function newEntityFoundThroughRelationship(AssociationMetadata $association, $entry)
112
    {
113
        $message = "A new entity was found through the relationship '%s#%s' that was not configured to cascade "
114
            . 'persist operations for entity: %s. To solve this issue: Either explicitly call EntityManager#persist() '
115
            . 'on this unknown entity or configure cascade persist this association in the mapping for example '
116
            . '@ManyToOne(..,cascade={"persist"}).%s';
117
118
        $messageAppend = method_exists($entry, '__toString')
119
            ? ''
120
            : " If you cannot find out which entity causes the problem implement '%s#__toString()' to get a clue."
121
        ;
122
123
        return new self(sprintf(
124
            $message,
125
            $association->getSourceEntity(),
126
            $association->getName(),
127
            self::objToStr($entry),
128
            sprintf($messageAppend, $association->getTargetEntity())
129
        ));
130
    }
131
132
    /**
133
     * @param object $entry
134
     *
135
     * @return ORMInvalidArgumentException
136
     */
137
    public static function detachedEntityFoundThroughRelationship(AssociationMetadata $association, $entry)
138
    {
139
        $messsage = "A detached entity of type %s (%s) was found through the relationship '%s#%s' during cascading a persist operation.";
140
141
        return new self(sprintf(
142
            $messsage,
143
            $association->getTargetEntity(),
144
            self::objToStr($entry),
145
            $association->getSourceEntity(),
146
            $association->getName()
147
        ));
148
    }
149
150
    /**
151
     * @param object $entity
152
     *
153
     * @return ORMInvalidArgumentException
154
     */
155 1
    public static function entityNotManaged($entity)
156
    {
157 1
        return new self('Entity ' . self::objToStr($entity) . ' is not managed. An entity is managed if its fetched ' .
158 1
            'from the database or registered as new through EntityManager#persist');
159
    }
160
161
    /**
162
     * @param object $entity
163
     * @param string $operation
164
     *
165
     * @return ORMInvalidArgumentException
166
     */
167
    public static function entityHasNoIdentity($entity, $operation)
168
    {
169
        return new self('Entity has no identity, therefore ' . $operation . ' cannot be performed. ' . self::objToStr($entity));
170
    }
171
172
    /**
173
     * @param object $entity
174
     * @param string $operation
175
     *
176
     * @return ORMInvalidArgumentException
177
     */
178
    public static function entityIsRemoved($entity, $operation)
179
    {
180
        return new self('Entity is removed, therefore ' . $operation . ' cannot be performed. ' . self::objToStr($entity));
181
    }
182
183
    /**
184
     * @param object $entity
185
     * @param string $operation
186
     *
187
     * @return ORMInvalidArgumentException
188
     */
189
    public static function detachedEntityCannot($entity, $operation)
190
    {
191
        return new self('Detached entity ' . self::objToStr($entity) . ' cannot be ' . $operation);
192
    }
193
194
    /**
195
     * @param string $context
196
     * @param mixed  $given
197
     * @param int    $parameterIndex
198
     *
199
     * @return ORMInvalidArgumentException
200
     */
201 3
    public static function invalidObject($context, $given, $parameterIndex = 1)
202
    {
203 3
        return new self($context . ' expects parameter ' . $parameterIndex .
204 3
            ' to be an entity object, ' . gettype($given) . ' given.');
205
    }
206
207
    /**
208
     * @return ORMInvalidArgumentException
209
     */
210
    public static function invalidCompositeIdentifier()
211
    {
212
        return new self('Binding an entity with a composite primary key to a query is not supported. ' .
213
            'You should split the parameter into the explicit fields and bind them separately.');
214
    }
215
216
    /**
217
     * @return ORMInvalidArgumentException
218
     */
219 1
    public static function invalidIdentifierBindingEntity()
220
    {
221 1
        return new self('Binding entities to query parameters only allowed for entities that have an identifier.');
222
    }
223
224
    /**
225
     * @param mixed $actualValue
226
     *
227
     * @return self
228
     */
229 15
    public static function invalidAssociation(ClassMetadata $targetClass, AssociationMetadata $association, $actualValue)
230
    {
231 15
        $expectedType = $targetClass->getClassName();
232
233 15
        return new self(sprintf(
234 15
            'Expected value of type "%s" for association field "%s#$%s", got "%s" instead.',
235 15
            $expectedType,
236 15
            $association->getSourceEntity(),
237 15
            $association->getName(),
238 15
            is_object($actualValue) ? get_class($actualValue) : gettype($actualValue)
239
        ));
240
    }
241
242
    /**
243
     * Helper method to show an object as string.
244
     *
245
     * @param object $obj
246
     */
247 15
    private static function objToStr($obj) : string
248
    {
249 15
        return method_exists($obj, '__toString') ? (string) $obj : get_class($obj) . '@' . spl_object_id($obj);
250
    }
251
252
    /**
253
     * @param object $entity
254
     */
255 4
    private static function newEntityFoundThroughRelationshipMessage(AssociationMetadata $association, $entity) : string
256
    {
257
        return 'A new entity was found through the relationship \''
258 4
            . $association->getSourceEntity() . '#' . $association->getName() . '\' that was not'
259 4
            . ' configured to cascade persist operations for entity: ' . self::objToStr($entity) . '.'
260 4
            . ' To solve this issue: Either explicitly call EntityManager#persist()'
261 4
            . ' on this unknown entity or configure cascade persist'
262 4
            . ' this association in the mapping for example @ManyToOne(..,cascade={"persist"}).'
263 4
            . (method_exists($entity, '__toString')
264 1
                ? ''
265
                : ' If you cannot find out which entity causes the problem implement \''
266 4
                . $association->getTargetEntity() . '#__toString()\' to get a clue.'
267
            );
268
    }
269
}
270