Complex classes like EntityManager often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use EntityManager, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
34 | class EntityManager extends Doctrine\ORM\EntityManager implements Persistence\QueryExecutor, Persistence\Queryable |
||
35 | { |
||
36 | |||
37 | use \Kdyby\StrictObjects\Scream; |
||
38 | |||
39 | /** |
||
40 | * @var NonLockingUniqueInserter |
||
41 | */ |
||
42 | private $nonLockingUniqueInserter; |
||
43 | |||
44 | /** |
||
45 | * @var \Kdyby\Doctrine\Diagnostics\EntityManagerUnitOfWorkSnapshotPanel |
||
46 | */ |
||
47 | private $panel; |
||
48 | |||
49 | |||
50 | |||
51 | protected function __construct(Doctrine\DBAL\Connection $conn, Doctrine\ORM\Configuration $config, Doctrine\Common\EventManager $eventManager) |
||
52 | { |
||
53 | parent::__construct($conn, $config, $eventManager); |
||
54 | |||
55 | if ($conn instanceof Kdyby\Doctrine\Connection) { |
||
56 | $conn->bindEntityManager($this); |
||
57 | } |
||
58 | } |
||
59 | |||
60 | |||
61 | |||
62 | /** |
||
63 | * @internal |
||
64 | * @param EntityManagerUnitOfWorkSnapshotPanel $panel |
||
65 | */ |
||
66 | public function bindTracyPanel(EntityManagerUnitOfWorkSnapshotPanel $panel) |
||
67 | { |
||
68 | $this->panel = $panel; |
||
69 | } |
||
70 | |||
71 | |||
72 | |||
73 | /** |
||
74 | * @throws NotSupportedException |
||
75 | * @return \Kdyby\Doctrine\QueryBuilder |
||
76 | */ |
||
77 | public function createQueryBuilder($alias = NULL, $indexBy = NULL) |
||
78 | { |
||
79 | if ($alias !== NULL || $indexBy !== NULL) { |
||
80 | throw new NotSupportedException('Use EntityRepository for $alias and $indexBy arguments to work.'); |
||
81 | } |
||
82 | |||
83 | $config = $this->getConfiguration(); |
||
84 | if ($config instanceof Configuration) { |
||
85 | $class = $config->getQueryBuilderClassName(); |
||
86 | return new $class($this); |
||
87 | } |
||
88 | |||
89 | return new QueryBuilder($this); |
||
90 | } |
||
91 | |||
92 | |||
93 | |||
94 | /** |
||
95 | * @param string|array|null $entityName if given, only entities of this type will get detached |
||
96 | * @return EntityManager |
||
97 | */ |
||
98 | public function clear($entityName = null) |
||
99 | { |
||
100 | foreach (is_array($entityName) ? $entityName : (func_get_args() + [0 => NULL]) as $item) { |
||
101 | parent::clear($item); |
||
102 | } |
||
103 | |||
104 | return $this; |
||
105 | } |
||
106 | |||
107 | |||
108 | |||
109 | /** |
||
110 | * @param object|array $entity |
||
111 | * @return EntityManager |
||
112 | */ |
||
113 | public function remove($entity) |
||
114 | { |
||
115 | foreach (is_array($entity) ? $entity : func_get_args() as $item) { |
||
116 | parent::remove($item); |
||
117 | } |
||
118 | |||
119 | return $this; |
||
120 | } |
||
121 | |||
122 | |||
123 | |||
124 | /** |
||
125 | * @param object|array $entity |
||
126 | * @return EntityManager |
||
127 | */ |
||
128 | public function persist($entity) |
||
136 | |||
137 | |||
138 | |||
139 | /** |
||
140 | * @param object|array|NULL $entity |
||
141 | * @return EntityManager |
||
142 | */ |
||
143 | public function flush($entity = null) |
||
158 | |||
159 | |||
160 | |||
161 | public function close() |
||
169 | |||
170 | |||
171 | |||
172 | /** |
||
173 | * Tries to persist the given entity and returns FALSE if an unique |
||
174 | * constaint was violated. |
||
175 | * |
||
176 | * Warning: On success you must NOT use the passed entity further |
||
177 | * in your application. Use the returned one instead! |
||
178 | * |
||
179 | * @param $entity |
||
180 | * @throws \Doctrine\DBAL\DBALException |
||
181 | * @throws \Exception |
||
182 | * @return bool|object |
||
183 | */ |
||
184 | public function safePersist($entity) |
||
192 | |||
193 | |||
194 | |||
195 | /** |
||
196 | * @param int $hydrationMode |
||
197 | * @return Doctrine\ORM\Internal\Hydration\AbstractHydrator |
||
198 | * @throws \Doctrine\ORM\ORMException |
||
199 | */ |
||
200 | public function newHydrator($hydrationMode) |
||
210 | |||
211 | |||
212 | |||
213 | /** |
||
214 | * Factory method to create EntityManager instances. |
||
215 | * |
||
216 | * @param \Doctrine\DBAL\Connection|array $conn |
||
217 | * @param \Doctrine\ORM\Configuration $config |
||
218 | * @param \Doctrine\Common\EventManager $eventManager |
||
219 | * @throws \Doctrine\ORM\ORMException |
||
220 | * @throws \InvalidArgumentException |
||
221 | * @throws \Doctrine\ORM\ORMException |
||
222 | * @return EntityManager |
||
223 | */ |
||
224 | public static function create($conn, Doctrine\ORM\Configuration $config, Doctrine\Common\EventManager $eventManager = NULL) |
||
249 | |||
250 | |||
251 | |||
252 | /****************** Kdyby\Persistence\QueryExecutor *****************/ |
||
253 | |||
254 | |||
255 | |||
256 | /** |
||
257 | * @param \Kdyby\Persistence\Query|\Kdyby\Doctrine\QueryObject $queryObject |
||
258 | * @param int $hydrationMode |
||
259 | * @throws QueryException |
||
260 | * @return array|\Kdyby\Doctrine\ResultSet |
||
261 | */ |
||
262 | public function fetch(Persistence\Query $queryObject, $hydrationMode = AbstractQuery::HYDRATE_OBJECT) |
||
271 | |||
272 | |||
273 | |||
274 | /** |
||
275 | * @param \Kdyby\Persistence\Query|\Kdyby\Doctrine\QueryObject $queryObject |
||
276 | * |
||
277 | * @throws InvalidStateException |
||
278 | * @throws QueryException |
||
279 | * @return object|NULL |
||
280 | */ |
||
281 | public function fetchOne(Persistence\Query $queryObject) |
||
296 | |||
297 | |||
298 | |||
299 | /** |
||
300 | * @param \Exception $e |
||
301 | * @param \Kdyby\Persistence\Query $queryObject |
||
302 | * |
||
303 | * @throws \Exception |
||
304 | */ |
||
305 | private function handleQueryException(\Exception $e, Persistence\Query $queryObject) |
||
311 | |||
312 | } |
||
313 |
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.