Completed
Pull Request — master (#246)
by Tomáš
02:38
created

EntityManager::getDao()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 4
rs 10
c 1
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
/**
4
 * This file is part of the Kdyby (http://www.kdyby.org)
5
 *
6
 * Copyright (c) 2008 Filip Procházka ([email protected])
7
 *
8
 * For the full copyright and license information, please view the file license.txt that was distributed with this source code.
9
 */
10
11
namespace Kdyby\Doctrine;
12
13
use Doctrine;
14
use Doctrine\DBAL\DriverManager;
15
use Doctrine\ORM\AbstractQuery;
16
use Doctrine\ORM\ORMException;
17
use Doctrine\ORM\Query;
18
use Kdyby;
19
use Kdyby\Doctrine\QueryObject;
20
use Kdyby\Doctrine\Tools\NonLockingUniqueInserter;
21
use Kdyby\Persistence;
22
use Nette;
23
use Nette\Utils\ObjectMixin;
24
25
26
27
/**
28
 * @author Filip Procházka <[email protected]>
29
 *
30
 * @method \Kdyby\Doctrine\Connection getConnection()
31
 * @method \Kdyby\Doctrine\Configuration getConfiguration()
32
 * @method \Kdyby\Doctrine\EntityRepository getRepository($entityName)
33
 */
34
class EntityManager extends Doctrine\ORM\EntityManager implements Persistence\QueryExecutor, Persistence\Queryable
35
{
36
37
	/**
38
	 * @var NonLockingUniqueInserter
39
	 */
40
	private $nonLockingUniqueInserter;
41
42
	/**
43
	 * @var Diagnostics\Panel
44
	 */
45
	private $panel;
46
47
48
49
	protected function __construct(Doctrine\DBAL\Connection $conn, Doctrine\ORM\Configuration $config, Doctrine\Common\EventManager $eventManager)
50
	{
51
		parent::__construct($conn, $config, $eventManager);
52
53
		if ($conn instanceof Kdyby\Doctrine\Connection) {
54
			$conn->bindEntityManager($this);
55
		}
56
	}
57
58
59
60
	/**
61
	 * @internal
62
	 * @param Diagnostics\Panel $panel
63
	 */
64
	public function bindTracyPanel(Diagnostics\Panel $panel)
65
	{
66
		$this->panel = $panel;
67
	}
68
69
70
71
	/**
72
	 * @throws NotSupportedException
73
	 * @return \Kdyby\Doctrine\QueryBuilder
74
	 */
75
	public function createQueryBuilder($alias = NULL, $indexBy = NULL)
76
	{
77
		if ($alias !== NULL || $indexBy !== NULL) {
78
			throw new NotSupportedException('Use EntityRepository for $alias and $indexBy arguments to work.');
79
		}
80
81
		if (($config = $this->getConfiguration()) instanceof Configuration) {
82
			$class = $config->getQueryBuilderClassName();
83
			return new $class($this);
84
		}
85
86
		return new QueryBuilder($this);
87
	}
88
89
90
91
	/**
92
	 * @return \Kdyby\Doctrine\DqlSelection
93
	 */
94
	public function createSelection()
95
	{
96
		return new DqlSelection($this);
97
	}
98
99
100
101
	/**
102
	 * {@inheritdoc}
103
	 * @param string|array $entity
0 ignored issues
show
Documentation introduced by
There is no parameter named $entity. Did you maybe mean $entityName?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
104
	 * @return EntityManager
105
	 */
106
	public function clear($entityName = null)
107
	{
108
		foreach (is_array($entityName) ? $entityName : (func_get_args() + [0 => NULL]) as $item) {
109
			parent::clear($item);
110
		}
111
112
		return $this;
113
	}
114
115
116
117
	/**
118
	 * {@inheritdoc}
119
	 * @param object|array $entity
120
	 * @return EntityManager
121
	 */
122
	public function remove($entity)
123
	{
124
		foreach (is_array($entity) ? $entity : func_get_args() as $item) {
125
			parent::remove($item);
126
		}
127
128
		return $this;
129
	}
130
131
132
133
	/**
134
	 * {@inheritdoc}
135
	 * @param object|array $entity
136
	 * @return EntityManager
137
	 */
138
	public function persist($entity)
139
	{
140
		foreach (is_array($entity) ? $entity : func_get_args() as $item) {
141
			parent::persist($item);
142
		}
143
144
		return $this;
145
	}
146
147
148
149
	/**
150
	 * {@inheritdoc}
151
	 * @param object|array $entity
152
	 * @return EntityManager
153
	 */
154
	public function flush($entity = null)
155
	{
156
		try {
157
			parent::flush($entity);
158
159
		} catch (\Exception $e) {
160
			if ($this->panel) {
161
				$this->panel->markExceptionOwner($this, $e);
162
			}
163
164
			throw $e;
165
		}
166
167
		return $this;
168
	}
169
170
171
172
	public function close()
173
	{
174
		if ($this->panel) {
175
			$this->panel->snapshotUnitOfWork($this);
176
		}
177
178
		parent::close();
179
	}
180
181
182
183
	/**
184
	 * Tries to persist the given entity and returns FALSE if an unique
185
	 * constaint was violated.
186
	 *
187
	 * Warning: On success you must NOT use the passed entity further
188
	 * in your application. Use the returned one instead!
189
	 *
190
	 * @param $entity
191
	 * @throws \Doctrine\DBAL\DBALException
192
	 * @throws \Exception
193
	 * @return bool|object
194
	 */
195
	public function safePersist($entity)
196
	{
197
		if ($this->nonLockingUniqueInserter === NULL) {
198
			$this->nonLockingUniqueInserter = new NonLockingUniqueInserter($this);
199
		}
200
201
		return $this->nonLockingUniqueInserter->persist($entity);
202
	}
203
204
205
206
	/**
207
	 * @param int $hydrationMode
208
	 * @return Doctrine\ORM\Internal\Hydration\AbstractHydrator
209
	 * @throws \Doctrine\ORM\ORMException
210
	 */
211
	public function newHydrator($hydrationMode)
212
	{
213
		switch ($hydrationMode) {
214
			case Hydration\HashHydrator::NAME:
215
				return new Hydration\HashHydrator($this);
216
217
			default:
218
				return parent::newHydrator($hydrationMode);
219
		}
220
	}
221
222
223
224
	/**
225
	 * Factory method to create EntityManager instances.
226
	 *
227
	 * @param \Doctrine\DBAL\Connection|array $conn
228
	 * @param \Doctrine\ORM\Configuration $config
229
	 * @param \Doctrine\Common\EventManager $eventManager
230
	 * @throws \Doctrine\ORM\ORMException
231
	 * @throws \InvalidArgumentException
232
	 * @throws \Doctrine\ORM\ORMException
233
	 * @return EntityManager
234
	 */
235
	public static function create($conn, Doctrine\ORM\Configuration $config, Doctrine\Common\EventManager $eventManager = NULL)
236
	{
237
		if (!$config->getMetadataDriverImpl()) {
238
			throw ORMException::missingMappingDriverImpl();
239
		}
240
241
		switch (TRUE) {
242
			case (is_array($conn)):
243
				$conn = DriverManager::getConnection(
244
					$conn, $config, ($eventManager ? : new Doctrine\Common\EventManager())
245
				);
246
				break;
247
248
			case ($conn instanceof Doctrine\DBAL\Connection):
249
				if ($eventManager !== NULL && $conn->getEventManager() !== $eventManager) {
250
					throw ORMException::mismatchedEventManager();
251
				}
252
				break;
253
254
			default:
255
				throw new \InvalidArgumentException("Invalid connection");
256
		}
257
258
		return new EntityManager($conn, $config, $conn->getEventManager());
259
	}
260
261
262
263
	/****************** Kdyby\Persistence\QueryExecutor *****************/
264
265
266
267
	/**
268
	 * @param \Kdyby\Persistence\Query|\Kdyby\Doctrine\QueryObject $queryObject
269
	 * @param int $hydrationMode
270
	 * @throws QueryException
271
	 * @return array|\Kdyby\Doctrine\ResultSet
272
	 */
273
	public function fetch(Persistence\Query $queryObject, $hydrationMode = AbstractQuery::HYDRATE_OBJECT)
274
	{
275
		try {
276
			return $queryObject->fetch($this, $hydrationMode);
0 ignored issues
show
Unused Code introduced by
The call to Query::fetch() has too many arguments starting with $hydrationMode.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
277
278
		} catch (\Exception $e) {
279
			throw $this->handleQueryException($e, $queryObject);
280
		}
281
	}
282
283
284
285
	/**
286
	 * @param \Kdyby\Persistence\Query|\Kdyby\Doctrine\QueryObject $queryObject
287
	 *
288
	 * @throws InvalidStateException
289
	 * @throws QueryException
290
	 * @return object|NULL
291
	 */
292
	public function fetchOne(Persistence\Query $queryObject)
293
	{
294
		try {
295
			return $queryObject->fetchOne($this);
296
297
		} catch (Doctrine\ORM\NoResultException $e) {
298
			return NULL;
299
300
		} catch (Doctrine\ORM\NonUniqueResultException $e) { // this should never happen!
301
			throw new InvalidStateException("You have to setup your query calling ->setMaxResult(1).", 0, $e);
302
303
		} catch (\Exception $e) {
304
			throw $this->handleQueryException($e, $queryObject);
305
		}
306
	}
307
308
309
310
	/**
311
	 * @param \Exception $e
312
	 * @param \Kdyby\Persistence\Query $queryObject
313
	 *
314
	 * @throws \Exception
315
	 */
316
	private function handleQueryException(\Exception $e, Persistence\Query $queryObject)
317
	{
318
		$lastQuery = $queryObject instanceof QueryObject ? $queryObject->getLastQuery() : NULL;
319
320
		return new QueryException($e, $lastQuery, '['.get_class($queryObject).'] '.$e->getMessage());
321
	}
322
323
324
325
	/*************************** Nette\Object ***************************/
326
327
328
329
	/**
330
	 * Access to reflection.
331
	 *
332
	 * @return \Nette\Reflection\ClassType
333
	 */
334
	public static function getReflection()
335
	{
336
		return new Nette\Reflection\ClassType(get_called_class());
337
	}
338
339
340
341
	/**
342
	 * Call to undefined method.
343
	 *
344
	 * @param string $name
345
	 * @param array $args
346
	 *
347
	 * @throws \Nette\MemberAccessException
348
	 * @return mixed
349
	 */
350
	public function __call($name, $args)
351
	{
352
		return ObjectMixin::call($this, $name, $args);
353
	}
354
355
356
357
	/**
358
	 * Call to undefined static method.
359
	 *
360
	 * @param string $name
361
	 * @param array $args
362
	 *
363
	 * @throws \Nette\MemberAccessException
364
	 * @return mixed
365
	 */
366
	public static function __callStatic($name, $args)
367
	{
368
		return ObjectMixin::callStatic(get_called_class(), $name, $args);
369
	}
370
371
372
373
	/**
374
	 * Adding method to class.
375
	 *
376
	 * @param $name
377
	 * @param null $callback
378
	 *
379
	 * @throws \Nette\MemberAccessException
380
	 * @return callable|null
381
	 */
382
	public static function extensionMethod($name, $callback = NULL)
383
	{
384
		if (strpos($name, '::') === FALSE) {
385
			$class = get_called_class();
386
		} else {
387
			list($class, $name) = explode('::', $name);
388
		}
389
		if ($callback === NULL) {
390
			return ObjectMixin::getExtensionMethod($class, $name);
391
		} else {
392
			ObjectMixin::setExtensionMethod($class, $name, $callback);
393
		}
394
	}
395
396
397
398
	/**
399
	 * Returns property value. Do not call directly.
400
	 *
401
	 * @param string $name
402
	 *
403
	 * @throws \Nette\MemberAccessException
404
	 * @return mixed
405
	 */
406
	public function &__get($name)
407
	{
408
		return ObjectMixin::get($this, $name);
409
	}
410
411
412
413
	/**
414
	 * Sets value of a property. Do not call directly.
415
	 *
416
	 * @param string $name
417
	 * @param mixed $value
418
	 *
419
	 * @throws \Nette\MemberAccessException
420
	 * @return void
421
	 */
422
	public function __set($name, $value)
423
	{
424
		ObjectMixin::set($this, $name, $value);
425
	}
426
427
428
429
	/**
430
	 * Is property defined?
431
	 *
432
	 * @param string $name
433
	 *
434
	 * @return bool
435
	 */
436
	public function __isset($name)
437
	{
438
		return ObjectMixin::has($this, $name);
439
	}
440
441
442
443
	/**
444
	 * Access to undeclared property.
445
	 *
446
	 * @param string $name
447
	 *
448
	 * @throws \Nette\MemberAccessException
449
	 * @return void
450
	 */
451
	public function __unset($name)
452
	{
453
		ObjectMixin::remove($this, $name);
454
	}
455
456
}
457