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 |
||
| 36 | class AdminController extends Controller |
||
| 37 | { |
||
| 38 | public static $DEPARTMENT_ENTITY_DATA = [ |
||
| 39 | 'entity' => 'department', |
||
| 40 | 'entityClassName' => 'AppBundle\Entity\Department', |
||
| 41 | 'entityFormType' => 'AppBundle\Form\Type\DepartmentType', |
||
| 42 | 'query' => 'SELECT d FROM AppBundle:Department d LEFT JOIN d.head h', |
||
| 43 | 'defaultSortFieldName' => 'd.name', |
||
| 44 | 'columns' => [ |
||
| 45 | ['size' => '5', 'sort_field' => 'd.name', 'name' => 'department.name'], |
||
| 46 | ['size' => '4', 'sort_field' => 'h.displayName', 'name' => 'department.head'], |
||
| 47 | ], |
||
| 48 | 'data_columns' => ['name', 'head'] |
||
| 49 | ]; |
||
| 50 | |||
| 51 | public static $COMPANY_ENTITY_DATA = [ |
||
| 52 | 'entity' => 'company', |
||
| 53 | 'entityClassName' => 'AppBundle\Entity\Company', |
||
| 54 | 'entityFormType' => 'AppBundle\Form\Type\CompanyType', |
||
| 55 | 'query' => 'SELECT c FROM AppBundle:Company c', |
||
| 56 | 'defaultSortFieldName' => 'c.name', |
||
| 57 | 'columns' => [ |
||
| 58 | ['size' => '2', 'sort_field' => 'c.code', 'name' => 'company.code'], |
||
| 59 | ['size' => '7', 'sort_field' => 'c.name', 'name' => 'company.name'], |
||
| 60 | ], |
||
| 61 | 'data_columns' => ['code', 'name'] |
||
| 62 | ]; |
||
| 63 | |||
| 64 | public static $WORKCENTER_ENTITY_DATA = [ |
||
| 65 | 'entity' => 'workcenter', |
||
| 66 | 'entityClassName' => 'AppBundle\Entity\Workcenter', |
||
| 67 | 'entityFormType' => 'AppBundle\Form\Type\WorkcenterType', |
||
| 68 | 'query' => 'SELECT w FROM AppBundle:Workcenter w JOIN w.company c', |
||
| 69 | 'defaultSortFieldName' => 'c.name', |
||
| 70 | 'columns' => [ |
||
| 71 | ['size' => '4', 'sort_field' => 'c.name', 'name' => 'form.company'], |
||
| 72 | ['size' => '5', 'sort_field' => 'w.name', 'name' => 'form.name'], |
||
| 73 | ], |
||
| 74 | 'data_columns' => ['company', 'name'] |
||
| 75 | ]; |
||
| 76 | |||
| 77 | public static $GROUP_ENTITY_DATA = [ |
||
| 78 | 'entity' => 'group', |
||
| 79 | 'entityClassName' => 'AppBundle\Entity\Group', |
||
| 80 | 'entityFormType' => 'AppBundle\Form\Type\GroupType', |
||
| 81 | 'query' => 'SELECT g FROM AppBundle:Group g JOIN g.training t', |
||
| 82 | 'defaultSortFieldName' => 'g.name', |
||
| 83 | 'columns' => [ |
||
| 84 | ['size' => '4', 'sort_field' => 'g.name', 'name' => 'form.name'], |
||
| 85 | ['size' => '5', 'sort_field' => 'g.training', 'name' => 'form.training'] |
||
| 86 | ], |
||
| 87 | 'data_columns' => ['name', 'training'] |
||
| 88 | ]; |
||
| 89 | |||
| 90 | public static $TRAINING_ENTITY_DATA = [ |
||
| 91 | 'entity' => 'training', |
||
| 92 | 'entityClassName' => 'AppBundle\Entity\Training', |
||
| 93 | 'entityFormType' => 'AppBundle\Form\Type\TrainingType', |
||
| 94 | 'query' => 'SELECT t FROM AppBundle:Training t JOIN t.department d', |
||
| 95 | 'defaultSortFieldName' => 't.name', |
||
| 96 | 'columns' => [ |
||
| 97 | ['size' => '4', 'sort_field' => 't.name', 'name' => 'form.name'], |
||
| 98 | ['size' => '3', 'sort_field' => 'd.name', 'name' => 'form.department'], |
||
| 99 | ['size' => '2', 'sort_field' => 't.programHours', 'name' => 'form.program_hours'] |
||
| 100 | ], |
||
| 101 | 'data_columns' => ['name', 'department', 'programHours'] |
||
| 102 | ]; |
||
| 103 | |||
| 104 | public static $NON_SCHOOL_DAY_ENTITY_DATA = [ |
||
| 105 | 'entity' => 'non_school_day', |
||
| 106 | 'entityClassName' => 'AppBundle\Entity\NonSchoolDay', |
||
| 107 | 'entityFormType' => 'AppBundle\Form\Type\NonSchoolDayType', |
||
| 108 | 'query' => 'SELECT n FROM AppBundle:NonSchoolDay n', |
||
| 109 | 'defaultSortFieldName' => 'n.date', |
||
| 110 | 'columns' => [ |
||
| 111 | ['size' => '2', 'sort_field' => 'n.date', 'name' => 'form.date'], |
||
| 112 | ['size' => '7', 'sort_field' => 'n.name', 'name' => 'form.name'] |
||
| 113 | ], |
||
| 114 | 'data_columns' => ['date', 'name'] |
||
| 115 | ]; |
||
| 116 | |||
| 117 | /** |
||
| 118 | * @Route("/admin", name="admin_menu", methods={"GET"}) |
||
| 119 | * @Security("is_granted('ROLE_ADMIN')") |
||
| 120 | */ |
||
| 121 | public function indexAction() |
||
| 122 | { |
||
| 123 | $menuItem = $this->get('app.menu_builders_chain')->getMenuItemByRouteName('admin_menu'); |
||
| 124 | |||
| 125 | return $this->render('admin/menu.html.twig', |
||
| 126 | [ |
||
| 127 | 'menu_item' => $menuItem |
||
| 128 | ]); |
||
| 129 | } |
||
| 130 | |||
| 131 | public function genericIndexAction($entityData, Request $request, $items = null, Query $query = null) |
||
| 132 | { |
||
| 133 | /** @var EntityManager $em */ |
||
| 134 | $em = $this->getDoctrine()->getManager(); |
||
| 135 | |||
| 136 | if (null === $query) { |
||
| 137 | $query = $em->createQuery($entityData['query']); |
||
| 138 | |||
| 139 | if (null !== $items) { |
||
| 140 | $query->setParameters($items); |
||
| 141 | } |
||
| 142 | } |
||
| 143 | |||
| 144 | $paginator = $this->get('knp_paginator'); |
||
| 145 | $pagination = $paginator->paginate( |
||
| 146 | $query, |
||
| 147 | $request->query->getInt('page', 1), |
||
| 148 | $this->getParameter('page.size'), |
||
| 149 | [ |
||
| 150 | 'defaultSortFieldName' => $entityData['defaultSortFieldName'], |
||
| 151 | 'defaultSortDirection' => 'asc' |
||
| 152 | ] |
||
| 153 | ); |
||
| 154 | |||
| 155 | $menuItem = $this->get('app.menu_builders_chain')->getMenuItemByRouteName(isset($entityData['parent']) |
||
| 156 | ? $entityData['parent'] |
||
| 157 | : $request->get('_route')); |
||
| 158 | |||
| 159 | $options = [ |
||
| 160 | 'menu_item' => $menuItem, |
||
| 161 | 'title' => isset($entityData['title']) ? $entityData['title'] : null, |
||
| 162 | 'pagination' => $pagination, |
||
| 163 | 'entity' => $entityData['entity'], |
||
| 164 | 'columns' => $entityData['columns'], |
||
| 165 | 'data_columns' => $entityData['data_columns'] |
||
| 166 | ]; |
||
| 167 | |||
| 168 | if (isset($entityData['breadcrumb'])) { |
||
| 169 | $options['breadcrumb'] = $entityData['breadcrumb']; |
||
| 170 | } |
||
| 171 | |||
| 172 | if (isset($entityData['back_path'])) { |
||
| 173 | $options['back_path'] = $entityData['back_path']; |
||
| 174 | } |
||
| 175 | |||
| 176 | if (isset($entityData['path_options'])) { |
||
| 177 | $options['path_options'] = $entityData['path_options']; |
||
| 178 | } |
||
| 179 | |||
| 180 | return $this->render(isset($entityData['manage_template']) ? $entityData['manage_template'] |
||
| 181 | : 'admin/manage_generic.html.twig', $options); |
||
| 182 | } |
||
| 183 | |||
| 184 | public function genericFormAction($entityData, $element, Request $request) |
||
| 185 | { |
||
| 186 | $em = $this->getDoctrine()->getManager(); |
||
| 187 | |||
| 188 | $new = (null === $element); |
||
| 189 | if ($new) { |
||
| 190 | $element = new $entityData['entityClassName']; |
||
| 191 | $em->persist($element); |
||
| 192 | } |
||
| 193 | |||
| 194 | $form = $this->createForm($entityData['entityFormType'], $element); |
||
| 195 | |||
| 196 | $form->handleRequest($request); |
||
| 197 | |||
| 198 | $menuItem = $this->get('app.menu_builders_chain')->getMenuItemByRouteName('admin_' . $entityData['entity']); |
||
| 199 | |||
| 200 | View Code Duplication | if ($form->isSubmitted() && $form->isValid()) { |
|
|
|
|||
| 201 | |||
| 202 | // Probar a guardar los cambios |
||
| 203 | try { |
||
| 204 | $em->flush(); |
||
| 205 | $this->addFlash('success', $this->get('translator')->trans('alert.saved', [], 'user')); |
||
| 206 | return $this->redirectToRoute($menuItem->getRouteName(), $menuItem->getRouteParams()); |
||
| 207 | } catch (\Exception $e) { |
||
| 208 | $this->addFlash('error', $this->get('translator')->trans('alert.not_saved', [], 'user')); |
||
| 209 | } |
||
| 210 | } |
||
| 211 | |||
| 212 | $title = ((string) $element) ?: $this->get('translator')->trans('form.new', [], $entityData['entity']); |
||
| 213 | |||
| 214 | return $this->render(isset($entityData['form_template']) ? $entityData['form_template'] : 'admin/form_generic.html.twig', [ |
||
| 215 | 'form' => $form->createView(), |
||
| 216 | 'new' => $new, |
||
| 217 | 'menu_item' => $menuItem, |
||
| 218 | 'breadcrumb' => [ |
||
| 219 | ['fixed' => $title] |
||
| 220 | ], |
||
| 221 | 'element' => $element, |
||
| 222 | 'title' => $title, |
||
| 223 | 'entity' => $entityData['entity'] |
||
| 224 | ]); |
||
| 225 | } |
||
| 226 | |||
| 227 | public function genericDeleteAction($entityData, $element, Request $request) |
||
| 228 | { |
||
| 229 | if ('POST' === $request->getMethod() && $request->request->has('delete')) { |
||
| 230 | |||
| 231 | // Eliminar el departamento de la base de datos |
||
| 232 | $this->getDoctrine()->getManager()->remove($element); |
||
| 233 | try { |
||
| 234 | $this->getDoctrine()->getManager()->flush(); |
||
| 235 | $this->addFlash('success', $this->get('translator')->trans('alert.deleted', [], $entityData['entity'])); |
||
| 236 | } catch (\Exception $e) { |
||
| 237 | $this->addFlash('error', $this->get('translator')->trans('alert.not_deleted', [], $entityData['entity'])); |
||
| 238 | } |
||
| 239 | return $this->redirectToRoute('admin_' . $entityData['entity']); |
||
| 240 | } |
||
| 241 | |||
| 242 | $title = (string) $element; |
||
| 243 | |||
| 244 | $breadcrumb = [ |
||
| 245 | ['fixed' => $title, 'path' => 'admin_' . $entityData['entity'] . '_form', 'options' => ['id' => $element->getId()]], |
||
| 246 | ['caption' => 'menu.delete'] |
||
| 247 | ]; |
||
| 248 | |||
| 249 | return $this->render(':admin:delete_generic.html.twig', [ |
||
| 250 | 'menu_item' => $this->get('app.menu_builders_chain')->getMenuItemByRouteName('admin_departments'), |
||
| 251 | 'breadcrumb' => $breadcrumb, |
||
| 252 | 'title' => $title, |
||
| 253 | 'element' => $element, |
||
| 254 | 'entity' => $entityData['entity'] |
||
| 255 | ]); |
||
| 256 | } |
||
| 257 | |||
| 258 | /** |
||
| 259 | * @Route("/admin/departamentos", name="admin_department", methods={"GET"}) |
||
| 260 | * @Security("is_granted('ROLE_ADMIN')") |
||
| 261 | */ |
||
| 262 | public function departmentsIndexAction(Request $request) |
||
| 263 | { |
||
| 264 | return $this->genericIndexAction(self::$DEPARTMENT_ENTITY_DATA, $request); |
||
| 265 | } |
||
| 266 | |||
| 267 | /** |
||
| 268 | * @Route("/admin/departamentos/nuevo", name="admin_department_new", methods={"GET", "POST"}) |
||
| 269 | * @Route("/admin/departamentos/{id}", name="admin_department_form", methods={"GET", "POST"}, requirements={"id": "\d+"}) |
||
| 270 | * @Security("is_granted('ROLE_ADMIN')") |
||
| 271 | */ |
||
| 272 | public function departmentsFormAction(Department $element = null, Request $request) |
||
| 273 | { |
||
| 274 | return $this->genericFormAction(self::$DEPARTMENT_ENTITY_DATA, $element, $request); |
||
| 275 | } |
||
| 276 | |||
| 277 | /** |
||
| 278 | * @Route("/admin/departamentos/eliminar/{id}", name="admin_department_delete", methods={"GET", "POST"}, requirements={"id": "\d+"} ) |
||
| 279 | * @Security("is_granted('ROLE_ADMIN')") |
||
| 280 | */ |
||
| 281 | public function deleteElementAction(Department $element, Request $request) |
||
| 282 | { |
||
| 283 | return $this->genericDeleteAction(self::$DEPARTMENT_ENTITY_DATA, $element, $request); |
||
| 284 | } |
||
| 285 | |||
| 286 | /** |
||
| 287 | * @Route("/empresas", name="admin_company", methods={"GET"}) |
||
| 288 | * @Security("is_granted('ROLE_DEPARTMENT_HEAD')") |
||
| 289 | */ |
||
| 290 | public function companiesIndexAction(Request $request) |
||
| 291 | { |
||
| 292 | return $this->genericIndexAction(self::$COMPANY_ENTITY_DATA, $request); |
||
| 293 | } |
||
| 294 | |||
| 295 | /** |
||
| 296 | * @Route("/empresas/nueva", name="admin_company_new", methods={"GET", "POST"}) |
||
| 297 | * @Route("/empresas/{id}", name="admin_company_form", methods={"GET", "POST"}, requirements={"id": "\d+"}) |
||
| 298 | * @Security("is_granted('ROLE_DEPARTMENT_HEAD')") |
||
| 299 | */ |
||
| 300 | public function companyFormAction(Company $element = null, Request $request) |
||
| 301 | { |
||
| 302 | return $this->genericFormAction(self::$COMPANY_ENTITY_DATA, $element, $request); |
||
| 303 | } |
||
| 304 | |||
| 305 | /** |
||
| 306 | * @Route("/empresas/eliminar/{id}", name="admin_company_delete", methods={"GET", "POST"}, requirements={"id": "\d+"} ) |
||
| 307 | * @Security("is_granted('ROLE_DEPARTMENT_HEAD')") |
||
| 308 | */ |
||
| 309 | public function companyDeleteAction(Company $element, Request $request) |
||
| 310 | { |
||
| 311 | return $this->genericDeleteAction(self::$COMPANY_ENTITY_DATA, $element, $request); |
||
| 312 | } |
||
| 313 | |||
| 314 | /** |
||
| 315 | * @Route("/admin/grupos", name="admin_group", methods={"GET"}) |
||
| 316 | * @Security("is_granted('ROLE_DEPARTMENT_HEAD')") |
||
| 317 | */ |
||
| 318 | public function groupIndexAction(Request $request) |
||
| 319 | { |
||
| 320 | return $this->genericIndexAction(self::$GROUP_ENTITY_DATA, $request); |
||
| 321 | } |
||
| 322 | |||
| 323 | /** |
||
| 324 | * @Route("/admin/grupos/nuevo", name="admin_group_new", methods={"GET", "POST"}) |
||
| 325 | * @Route("/admin/grupos/{id}", name="admin_group_form", methods={"GET", "POST"}, requirements={"id": "\d+"}) |
||
| 326 | * @Security("is_granted('ROLE_ADMIN')") |
||
| 327 | */ |
||
| 328 | public function groupFormAction(Group $element = null, Request $request) |
||
| 329 | { |
||
| 330 | return $this->genericFormAction(self::$GROUP_ENTITY_DATA, $element, $request); |
||
| 331 | } |
||
| 332 | |||
| 333 | /** |
||
| 334 | * @Route("/admin/grupos/eliminar/{id}", name="admin_group_delete", methods={"GET", "POST"}, requirements={"id": "\d+"} ) |
||
| 335 | * @Security("is_granted('ROLE_ADMIN')") |
||
| 336 | */ |
||
| 337 | public function groupDeleteAction(Group $element, Request $request) |
||
| 338 | { |
||
| 339 | return $this->genericDeleteAction(self::$GROUP_ENTITY_DATA, $element, $request); |
||
| 340 | } |
||
| 341 | |||
| 342 | /** |
||
| 343 | * @Route("/admin/ensenanzas", name="admin_training", methods={"GET"}) |
||
| 344 | * @Security("is_granted('ROLE_ADMIN')") |
||
| 345 | */ |
||
| 346 | public function trainingIndexAction(Request $request) |
||
| 347 | { |
||
| 348 | return $this->genericIndexAction(self::$TRAINING_ENTITY_DATA, $request); |
||
| 349 | } |
||
| 350 | |||
| 351 | /** |
||
| 352 | * @Route("/admin/ensenanzas/nueva", name="admin_training_new", methods={"GET", "POST"}) |
||
| 353 | * @Route("/admin/ensenanzas/{id}", name="admin_training_form", methods={"GET", "POST"}, requirements={"id": "\d+"}) |
||
| 354 | * @Security("is_granted('ROLE_ADMIN')") |
||
| 355 | */ |
||
| 356 | public function trainingFormAction(Training $element = null, Request $request) |
||
| 357 | { |
||
| 358 | return $this->genericFormAction(self::$TRAINING_ENTITY_DATA, $element, $request); |
||
| 359 | } |
||
| 360 | |||
| 361 | /** |
||
| 362 | * @Route("/admin/ensenanzas/eliminar/{id}", name="admin_training_delete", methods={"GET", "POST"}, requirements={"id": "\d+"} ) |
||
| 363 | * @Security("is_granted('ROLE_ADMIN')") |
||
| 364 | */ |
||
| 365 | public function trainingDeleteAction(Training $element, Request $request) |
||
| 366 | { |
||
| 367 | return $this->genericDeleteAction(self::$TRAINING_ENTITY_DATA, $element, $request); |
||
| 368 | } |
||
| 369 | |||
| 370 | /** |
||
| 371 | * @Route("/admin/diasnolectivos", name="admin_non_school_day", methods={"GET"}) |
||
| 372 | * @Security("is_granted('ROLE_ADMIN')") |
||
| 373 | */ |
||
| 374 | public function nonSchoolDayIndexAction(Request $request) |
||
| 375 | { |
||
| 376 | return $this->genericIndexAction(self::$NON_SCHOOL_DAY_ENTITY_DATA, $request); |
||
| 377 | } |
||
| 378 | |||
| 379 | /** |
||
| 380 | * @Route("/admin/diasnolectivos/nuevo", name="admin_non_school_day_new", methods={"GET", "POST"}) |
||
| 381 | * @Route("/admin/diasnolectivos/{id}", name="admin_non_school_day_form", methods={"GET", "POST"}) |
||
| 382 | * @Security("is_granted('ROLE_ADMIN')") |
||
| 383 | */ |
||
| 384 | public function nonSchoolDayFormAction(NonSchoolDay $element = null, Request $request) |
||
| 385 | { |
||
| 386 | return $this->genericFormAction(self::$NON_SCHOOL_DAY_ENTITY_DATA, $element, $request); |
||
| 387 | } |
||
| 388 | |||
| 389 | /** |
||
| 390 | * @Route("/admin/diasnolectivos/eliminar/{id}", name="admin_non_school_day_delete", methods={"GET", "POST"}) |
||
| 391 | * @Security("is_granted('ROLE_ADMIN')") |
||
| 392 | */ |
||
| 393 | public function workcenterDeleteAction(Workcenter $element, Request $request) |
||
| 394 | { |
||
| 395 | return $this->genericDeleteAction(self::$WORKCENTER_ENTITY_DATA, $element, $request); |
||
| 396 | } |
||
| 397 | |||
| 398 | /** |
||
| 399 | * @Route("/centros", name="admin_workcenter", methods={"GET"}) |
||
| 400 | * @Security("is_granted('ROLE_DEPARTMENT_HEAD')") |
||
| 401 | */ |
||
| 402 | public function workcenterIndexAction(Request $request) |
||
| 406 | |||
| 407 | /** |
||
| 408 | * @Route("/centros/nuevo", name="admin_workcenter_new", methods={"GET", "POST"}) |
||
| 409 | * @Route("/centros/{id}", name="admin_workcenter_form", methods={"GET", "POST"}) |
||
| 410 | * @Security("is_granted('ROLE_DEPARTMENT_HEAD')") |
||
| 411 | */ |
||
| 412 | public function workcenterFormAction(Workcenter $element = null, Request $request) |
||
| 413 | { |
||
| 414 | return $this->genericFormAction(self::$WORKCENTER_ENTITY_DATA, $element, $request); |
||
| 415 | } |
||
| 416 | |||
| 417 | /** |
||
| 418 | * @Route("/centros/eliminar/{id}", name="admin_workcenter_delete", methods={"GET", "POST"}) |
||
| 419 | * @Security("is_granted('ROLE_DEPARTMENT_HEAD')") |
||
| 420 | */ |
||
| 421 | public function nonSchoolDayDeleteAction(Workcenter $element, Request $request) |
||
| 422 | { |
||
| 423 | return $this->genericDeleteAction(self::$WORKCENTER_ENTITY_DATA, $element, $request); |
||
| 424 | } |
||
| 425 | } |
||
| 426 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.