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:
Complex classes like PagesPresenter 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 PagesPresenter, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
13 | class PagesPresenter extends \AdminModule\BasePresenter |
||
14 | { |
||
15 | /* @var Page */ |
||
16 | |||
17 | private $page; |
||
18 | |||
19 | private $repository; |
||
20 | |||
21 | 1 | protected function beforeRender() |
|
22 | { |
||
23 | 1 | parent::beforeRender(); |
|
24 | 1 | } |
|
25 | |||
26 | 1 | protected function startup() |
|
27 | { |
||
28 | 1 | parent::startup(); |
|
29 | |||
30 | 1 | $this->repository = $this->em->getRepository('WebCMS\Entity\Page'); |
|
31 | 1 | } |
|
32 | |||
33 | 1 | protected function createComponentPageForm() |
|
34 | { |
||
35 | $repository = $this->em->getRepository('WebCMS\Entity\Page'); |
||
36 | $hierarchy = $repository->getTreeForSelect(array( |
||
37 | array('by' => 'root', 'dir' => 'ASC'), |
||
38 | array('by' => 'lft', 'dir' => 'ASC'), |
||
39 | ), array( |
||
40 | 'language = '.$this->state->language->getId(), |
||
41 | )); |
||
42 | |||
43 | $hierarchy = array(0 => $this->translation['Pick parent']) + $hierarchy; |
||
44 | |||
45 | // loads modules |
||
46 | $modules = $this->em->getRepository('WebCMS\Entity\Module')->findAll(); |
||
47 | $modulesToSelect = array(NULL => 'No module'); |
||
48 | foreach ($modules as $module) { |
||
49 | $objectModule = $this->createObject($module->getName()); |
||
50 | |||
51 | foreach ($objectModule->getPresenters() as $presenter) { |
||
52 | if ($presenter['frontend']) { |
||
53 | $modulesToSelect[$module->getId().'-'.$presenter['name']] = $module->getName().' '.$presenter['name']; |
||
54 | } |
||
55 | } |
||
56 | } |
||
57 | |||
58 | $layouts = array(); |
||
59 | foreach (Finder::findFiles('@*.latte')->in(APP_DIR.'/templates') as $key => $file) { |
||
60 | $layouts[str_replace(array('@', '.latte'), '', $file->getFileName())] = $file->getFileName(); |
||
61 | } |
||
62 | |||
63 | $form = $this->createForm(); |
||
64 | $form->addText('title', 'Name')->setAttribute('class', 'form-control')->setRequired(); |
||
|
|||
65 | 1 | $form->addText('redirect', 'Redirect')->setAttribute('class', 'form-control'); |
|
66 | $form->addText('class', 'Menu item class')->setAttribute('class', 'form-control'); |
||
67 | $form->addSelect('module', 'Module')->setTranslator(null)->setItems($modulesToSelect)->setAttribute('class', 'form-control')->setRequired(); |
||
68 | $form->addSelect('parent', 'Parent')->setTranslator(null)->setItems($hierarchy)->setAttribute('class', 'form-control'); |
||
69 | $form->addSelect('layout', 'Page layout')->setTranslator(null)->setItems($layouts)->setAttribute('class', 'form-control'); |
||
70 | $form->addCheckbox('default', 'Default'); |
||
71 | $form->addCheckbox('visible', 'Show'); |
||
72 | $form->addCheckbox('secured', 'Secured'); |
||
73 | |||
74 | $form->addSubmit('save', 'Save')->setAttribute('class', 'btn btn-success'); |
||
75 | |||
76 | $form->onSuccess[] = callback($this, 'pageFormSubmitted'); |
||
77 | |||
78 | 1 | if ($this->page) { |
|
79 | 1 | $form->setDefaults($this->page->toArray()); |
|
80 | 1 | if (is_object($this->page->getModule())) { |
|
81 | 1 | $form['module']->setDefaultValue($this->page->getModule()->getId().'-'.$this->page->getPresenter()); |
|
82 | 1 | } |
|
83 | 1 | } |
|
84 | |||
85 | 1 | return $form; |
|
86 | 1 | } |
|
87 | |||
88 | public function pageFormSubmitted(UI\Form $form) |
||
89 | { |
||
90 | $values = $form->getValues(); |
||
91 | |||
92 | $tmpBoxes = array(); |
||
93 | if ($values->parent) { |
||
94 | $parent = $this->em->find("WebCMS\Entity\Page", $values->parent); |
||
95 | // copy boxes |
||
96 | $tmpBoxes = $parent->getBoxes(); |
||
97 | } else { |
||
98 | $parent = null; |
||
99 | } |
||
100 | |||
101 | $this->setPageValues($values, $parent); |
||
102 | |||
103 | if (!$this->page->getId()) { |
||
104 | $this->em->persist($this->page); |
||
105 | |||
106 | $this->createBoxesFromParent($tmpBoxes); |
||
107 | |||
108 | $this->em->flush(); |
||
109 | $this->copyPermissions(); |
||
110 | } else { |
||
111 | $children = $this->page->getChildren(); |
||
112 | |||
113 | foreach ($children as $child) { |
||
114 | $this->generatePath($child); |
||
115 | } |
||
116 | } |
||
117 | |||
118 | // persist and generate path |
||
119 | $this->em->flush(); |
||
120 | $this->generatePath($this->page); |
||
121 | $this->em->flush(); |
||
122 | $this->generateSitemap(); |
||
123 | |||
124 | $this->flashMessage('Page has been added.', 'success'); |
||
125 | $this->forward('Pages:default'); |
||
126 | } |
||
127 | |||
128 | /** |
||
129 | * |
||
130 | * |
||
131 | * @param [type] $values [description] |
||
132 | */ |
||
133 | 1 | private function setPageValues($values, $parent) |
|
134 | { |
||
135 | if ($values->module) { |
||
136 | $parse = explode('-', $values->module); |
||
137 | $module = $this->em->find("WebCMS\Entity\Module", $parse[0]); |
||
138 | $presenter = $parse[1]; |
||
139 | } else { |
||
140 | $module = null; |
||
141 | $presenter = ''; |
||
142 | 1 | } |
|
143 | |||
144 | $this->page->setTitle($values->title); |
||
145 | |||
146 | if (!empty($values->redirect)) { |
||
147 | 1 | $this->page->setRedirect($values->redirect); |
|
148 | } else { |
||
149 | $this->page->setRedirect(null); |
||
150 | } |
||
151 | |||
152 | if ($module) { |
||
153 | $this->page->setModuleName($module->getName()); |
||
154 | } else { |
||
155 | $this->page->setModuleName(''); |
||
156 | } |
||
157 | |||
158 | $this->page->setVisible($values->visible); |
||
159 | $this->page->setDefault($values->default); |
||
160 | $this->page->setSecured($values->secured); |
||
161 | 1 | $this->page->setParent($parent); |
|
162 | $this->page->setLanguage($this->state->language); |
||
163 | 1 | $this->page->setModule($module); |
|
164 | $this->page->setPresenter($presenter); |
||
165 | $this->page->setPath('tmp value'); |
||
166 | $this->page->setClass($values->class); |
||
167 | $this->page->setLayout($values->layout); |
||
168 | } |
||
169 | |||
170 | /** |
||
171 | * |
||
172 | * |
||
173 | * @param [type] $boxes [description] |
||
174 | * @return [type] [description] |
||
175 | */ |
||
176 | private function createBoxesFromParent($boxes) |
||
190 | |||
191 | /** |
||
192 | * |
||
193 | * |
||
194 | * @return [type] [description] |
||
195 | */ |
||
196 | View Code Duplication | private function generatePath($page) |
|
197 | { |
||
198 | $path = $this->em->getRepository('WebCMS\Entity\Page')->getPath($page); |
||
199 | $final = array(); |
||
200 | foreach ($path as $p) { |
||
201 | if ($p->getParent() != NULL) { |
||
202 | $final[] = $p->getSlug(); |
||
203 | } |
||
204 | } |
||
205 | |||
206 | $page->setPath(implode('/', $final)); |
||
207 | } |
||
208 | |||
209 | /** |
||
210 | * |
||
211 | * |
||
212 | * @return [type] [description] |
||
213 | */ |
||
214 | private function copyPermissions() |
||
234 | |||
235 | 1 | protected function createComponentPagesGrid($name) |
|
290 | |||
291 | 1 | public function actionUpdatePage($id) |
|
299 | |||
300 | View Code Duplication | public function actionDeletePage($id) |
|
310 | |||
311 | public function renderUpdatePage($id) |
||
317 | |||
318 | 1 | public function renderDefault() |
|
322 | |||
323 | // Sorting |
||
324 | public function renderSorting($id) |
||
344 | |||
345 | public function actionMove($id, $oldPosition, $newPosition) |
||
357 | |||
358 | View Code Duplication | public function actionMoveUp($id, $step = 1) |
|
375 | |||
376 | View Code Duplication | public function actionMoveDown($id, $step = 1) |
|
393 | } |
||
394 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: