Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php |
||
| 12 | class WidgetMapManager |
||
| 13 | { |
||
| 14 | private $em; |
||
| 15 | private $builder; |
||
| 16 | |||
| 17 | public function __construct(EntityManager $em, WidgetMapBuilder $builder) |
||
| 22 | |||
| 23 | /** |
||
| 24 | * Insert a WidgetMap in a view at given position. |
||
| 25 | * |
||
| 26 | * @param string $slotId |
||
| 27 | */ |
||
| 28 | public function insert(Widget $widget, View $view, $slotId, $position, $widgetReference) |
||
| 56 | |||
| 57 | /** |
||
| 58 | * moves a widget in a view. |
||
| 59 | * |
||
| 60 | * @param View $view |
||
| 61 | * @param array $sortedWidget |
||
| 62 | * |
||
| 63 | * @return void |
||
| 64 | */ |
||
| 65 | public function move(View $view, $sortedWidget) |
||
| 66 | { |
||
| 67 | /** @var WidgetMap $parentWidgetMap */ |
||
| 68 | $parentWidgetMap = $this->em->getRepository('VictoireWidgetMapBundle:WidgetMap')->find((int) $sortedWidget['parentWidgetMap']); |
||
| 69 | $position = $sortedWidget['position']; |
||
| 70 | $slot = $sortedWidget['slot']; |
||
| 71 | /** @var WidgetMap $widgetMap */ |
||
| 72 | $widgetMap = $this->em->getRepository('VictoireWidgetMapBundle:WidgetMap')->find((int) $sortedWidget['widgetMap']); |
||
| 73 | |||
| 74 | $originalParent = $widgetMap->getParent(); |
||
| 75 | $originalPosition = $widgetMap->getPosition(); |
||
| 76 | |||
| 77 | $children = $widgetMap->getChildren($view); |
||
| 78 | $beforeChild = !empty($children[WidgetMap::POSITION_BEFORE]) ? $children[WidgetMap::POSITION_BEFORE] : null; |
||
| 79 | $afterChild = !empty($children[WidgetMap::POSITION_AFTER]) ? $children[WidgetMap::POSITION_AFTER] : null; |
||
| 80 | |||
| 81 | $parentWidgetMapChildren = $this->getChildrenByView($parentWidgetMap); |
||
| 82 | |||
| 83 | $widgetMap = $this->moveWidgetMap($view, $widgetMap, $parentWidgetMap, $position, $slot); |
||
| 84 | |||
| 85 | // If the moved widgetMap has someone at both his before and after, arbitrary move UP the before side |
||
| 86 | // and find the first place after the before widgetMap hierarchy to place the after widgetMap. |
||
| 87 | $this->moveChildren($view, $beforeChild, $afterChild, $originalParent, $originalPosition); |
||
| 88 | |||
| 89 | foreach ($parentWidgetMapChildren['views'] as $_view) { |
||
| 90 | if ($_view->getId() !== $view->getId()) { |
||
| 91 | View Code Duplication | if (isset($parentWidgetMapChildren['before'][$_view->getId()])) { |
|
| 92 | $parentWidgetMapChildren['before'][$_view->getId()]->setParent($widgetMap); |
||
| 93 | } |
||
| 94 | View Code Duplication | if (isset($parentWidgetMapChildren['after'][$_view->getId()])) { |
|
| 95 | $parentWidgetMapChildren['after'][$_view->getId()]->setParent($widgetMap); |
||
| 96 | } |
||
| 97 | } |
||
| 98 | } |
||
| 99 | } |
||
| 100 | |||
| 101 | /** |
||
| 102 | * Delete the widget from the view. |
||
| 103 | * |
||
| 104 | * @param View $view |
||
| 105 | * @param Widget $widget |
||
| 106 | * |
||
| 107 | * @throws \Exception Widget map does not exists |
||
| 108 | */ |
||
| 109 | public function delete(View $view, Widget $widget) |
||
| 141 | |||
| 142 | /** |
||
| 143 | * the widget is owned by another view (a parent) |
||
| 144 | * so we add a new widget map that indicates we delete this widget. |
||
| 145 | * |
||
| 146 | * @param View $view |
||
| 147 | * @param WidgetMap $originalWidgetMap |
||
| 148 | * @param Widget $widgetCopy |
||
| 149 | * |
||
| 150 | * @throws \Exception |
||
| 151 | */ |
||
| 152 | public function overwrite(View $view, WidgetMap $originalWidgetMap, Widget $widgetCopy) |
||
| 166 | |||
| 167 | /** |
||
| 168 | * If the moved widgetMap has someone at both his before and after, arbitrary move UP the before side |
||
| 169 | * and find the first place after the before widgetMap hierarchy to place the after widgetMap. |
||
| 170 | * |
||
| 171 | * @param View $view |
||
| 172 | * @param $beforeChild |
||
| 173 | * @param $afterChild |
||
| 174 | * @param $originalParent |
||
| 175 | * @param $originalPosition |
||
| 176 | */ |
||
| 177 | public function moveChildren(View $view, $beforeChild, $afterChild, $originalParent, $originalPosition) |
||
| 195 | |||
| 196 | /** |
||
| 197 | * Create a copy of a WidgetMap in "overwrite" mode and insert it in the given view. |
||
| 198 | * |
||
| 199 | * @param WidgetMap $widgetMap |
||
| 200 | * @param View $view |
||
| 201 | * |
||
| 202 | * @throws \Exception |
||
| 203 | * |
||
| 204 | * @return WidgetMap |
||
| 205 | */ |
||
| 206 | protected function cloneWidgetMap(WidgetMap $widgetMap, View $view) |
||
| 220 | |||
| 221 | /** |
||
| 222 | * Move given WidgetMap as a child of given parent at given position and slot. |
||
| 223 | * |
||
| 224 | * @param View $view |
||
| 225 | * @param WidgetMap $widgetMap |
||
| 226 | * @param bool $parent |
||
| 227 | * @param bool $position |
||
| 228 | * @param bool $slot |
||
| 229 | * |
||
| 230 | * @return WidgetMap |
||
| 231 | */ |
||
| 232 | protected function moveWidgetMap(View $view, WidgetMap $widgetMap, $parent = false, $position = false, $slot = false) |
||
| 256 | |||
| 257 | /** |
||
| 258 | * Find return all the given WidgetMap children for each view where it's related. |
||
| 259 | * |
||
| 260 | * @param WidgetMap $widgetMap |
||
| 261 | * |
||
| 262 | * @return mixed |
||
| 263 | */ |
||
| 264 | protected function getChildrenByView(WidgetMap $widgetMap) |
||
| 285 | } |
||
| 286 |
The
EntityManagermight become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:If that code throws an exception and the
EntityManageris closed. Any other code which depends on the same instance of theEntityManagerduring this request will fail.On the other hand, if you instead inject the
ManagerRegistry, thegetManager()method guarantees that you will always get a usable manager instance.