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 |
||
35 | class UsersController extends AppController |
||
36 | { |
||
37 | |||
38 | /** |
||
39 | * Add action. |
||
40 | * |
||
41 | * @return \Cake\Http\Response|null |
||
42 | * |
||
43 | * @throws \Aura\Intl\Exception |
||
44 | * @throws \Cake\ORM\Exception\RolledbackTransactionException |
||
45 | */ |
||
46 | public function add() |
||
47 | { |
||
48 | $user = $this->Users->newEntity(); |
||
49 | if ($this->request->is('post')) { |
||
50 | $user = $this->Users->patchEntity($user, $this->request->getData()); |
||
|
|||
51 | if (Filter::bool($user->get('notify'))) { |
||
52 | $user->set('token', Token::generate()); |
||
53 | } |
||
54 | |||
55 | $result = $this->Users->save($user); |
||
56 | if ($result) { |
||
57 | $this->Flash->success(__d('community', 'The user {0} has been saved.', sprintf( |
||
58 | '<strong>«%s»</strong>', |
||
59 | $result->get('login') |
||
60 | ))); |
||
61 | |||
62 | return $this->App->redirect(['apply' => ['action' => 'edit', $result->id]]); |
||
63 | } else { |
||
64 | $this->Flash->error(__d('community', 'User could not be updated. Please, try again.')); |
||
65 | } |
||
66 | } |
||
67 | |||
68 | $groups = $this->Users->Groups->getTreeList(); |
||
69 | |||
70 | $this |
||
71 | ->set(compact('user', 'groups')) |
||
72 | ->set('page_title', __d('community', 'Profiles: Add new user')); |
||
73 | } |
||
74 | |||
75 | /** |
||
76 | * Change user password action. |
||
77 | * |
||
78 | * @param null|int $id User id. |
||
79 | * @return \Cake\Http\Response|null |
||
80 | * |
||
81 | * @throws \Aura\Intl\Exception |
||
82 | */ |
||
83 | public function changePassword($id = null) |
||
84 | { |
||
85 | $user = $this->Users->get($id, ['contain' => []]); |
||
86 | $user->set('password', null); |
||
87 | |||
88 | View Code Duplication | if ($this->request->is(['patch', 'post', 'put'])) { |
|
89 | $user = $this->Users->patchEntity($user, $this->request->getData()); |
||
90 | if ($result = $this->Users->save($user)) { |
||
91 | $this->Flash->success(__d('community', 'Password has been updated.')); |
||
92 | return $this->App->redirect(['apply' => ['action' => 'edit', $result->id]]); |
||
93 | } else { |
||
94 | $this->Flash->error(__d('community', 'Password could not be updated. Please, try again.')); |
||
95 | } |
||
96 | } |
||
97 | |||
98 | $this |
||
99 | ->set(compact('user')) |
||
100 | ->set('page_title', __d('community', 'Profiles: {0} - change password', $user->name)); |
||
101 | } |
||
102 | |||
103 | /** |
||
104 | * Edit action. |
||
105 | * |
||
106 | * @param null|int $id User id. |
||
107 | * @return \Cake\Http\Response|null |
||
108 | * |
||
109 | * @throws \Aura\Intl\Exception |
||
110 | * @throws RecordNotFoundException |
||
111 | * @throws InvalidPrimaryKeyException |
||
112 | * @throws RolledbackTransactionException |
||
113 | */ |
||
114 | public function edit($id = null) |
||
115 | { |
||
116 | /** @var User $user */ |
||
117 | $user = $this->Users->get($id); |
||
118 | $groups = $this->Users->Groups->getTreeList(); |
||
119 | |||
120 | View Code Duplication | if ($this->request->is(['patch', 'post', 'put'])) { |
|
121 | $user = $this->Users->patchEntity($user, $this->request->getData()); |
||
122 | if ($result = $this->Users->save($user)) { |
||
123 | $this->Flash->success(__d('community', 'The user {0} has been saved.', sprintf( |
||
124 | '<strong>«%s»</strong>', |
||
125 | $result->get('login') |
||
126 | ))); |
||
127 | return $this->App->redirect([ |
||
128 | 'apply' => ['action' => 'edit', $result->id] |
||
129 | ]); |
||
130 | } else { |
||
131 | $this->Flash->error(__d('community', 'User could not be updated. Please, try again.')); |
||
132 | } |
||
133 | } |
||
134 | |||
135 | $this |
||
136 | ->set(compact('user', 'groups')) |
||
137 | ->set('page_title', __d('community', 'Profiles: Edit user - {0}', $user->name)); |
||
138 | } |
||
139 | |||
140 | /** |
||
141 | * Index action. |
||
142 | * |
||
143 | * @return void |
||
144 | * |
||
145 | * @throws \Aura\Intl\Exception |
||
146 | * @throws \RuntimeException |
||
147 | */ |
||
148 | public function index() |
||
158 | |||
159 | /** |
||
160 | * Initialization hook method. Implement this method to avoid having to overwrite the constructor and call parent. |
||
161 | * |
||
162 | * @return void |
||
163 | * |
||
164 | * @throws \JBZoo\Utils\Exception |
||
165 | * @throws \Cake\Core\Exception\Exception |
||
166 | */ |
||
167 | public function initialize() |
||
172 | |||
173 | /** |
||
174 | * Login action. |
||
175 | * |
||
176 | * @return \Cake\Http\Response|null |
||
177 | * |
||
178 | * @throws \Aura\Intl\Exception |
||
179 | */ |
||
180 | View Code Duplication | public function login() |
|
195 | |||
196 | /** |
||
197 | * Logout action. |
||
198 | * |
||
199 | * @return \Cake\Http\Response|null |
||
200 | */ |
||
201 | public function logout() |
||
205 | |||
206 | /** |
||
207 | * Process action. |
||
208 | * |
||
209 | * @return \Cake\Http\Response|null |
||
210 | * |
||
211 | * @throws \Aura\Intl\Exception |
||
212 | */ |
||
213 | public function process() |
||
218 | } |
||
219 |
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.