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 |
||
| 7 | trait ModelQuerying |
||
| 8 | { |
||
| 9 | /** |
||
| 10 | * Query. |
||
| 11 | * |
||
| 12 | * @var string |
||
| 13 | */ |
||
| 14 | public $query; |
||
| 15 | |||
| 16 | /** |
||
| 17 | * Allows filtering of the default query, for instance:. |
||
| 18 | * |
||
| 19 | * $queryFilter = [ |
||
| 20 | * 'whereNotNull' => ['parent_id'], |
||
| 21 | * 'where' => ['name', 'John'], |
||
| 22 | * ] |
||
| 23 | * |
||
| 24 | * Would result in an Eloquent query with the following scope: |
||
| 25 | * Model::whereNotNull('parent_id')->where('name', 'John')->get(); |
||
| 26 | * |
||
| 27 | * Note: This queryFilter is not used for custom filters and |
||
| 28 | * can also be overridden by setQueryFilter(); |
||
| 29 | * |
||
| 30 | * @var array |
||
| 31 | */ |
||
| 32 | protected $queryFilter = []; |
||
| 33 | |||
| 34 | /** |
||
| 35 | * Any array of Filters. |
||
| 36 | * |
||
| 37 | * Filter should be setup in the same fashion as a default |
||
| 38 | * $queryFilter is setup, however, inside an associative |
||
| 39 | * array. |
||
| 40 | * |
||
| 41 | * The associative array is your filter 'action' and is |
||
| 42 | * used as the filter label (and converted to a URL safe |
||
| 43 | * query parameter). |
||
| 44 | * |
||
| 45 | * @var array |
||
| 46 | */ |
||
| 47 | protected $filters = []; |
||
| 48 | |||
| 49 | /** |
||
| 50 | * The number of models to return for pagination. |
||
| 51 | * |
||
| 52 | * @var int |
||
| 53 | */ |
||
| 54 | protected $perPage = 15; |
||
| 55 | |||
| 56 | /** |
||
| 57 | * Order By - Column/Attribute to OrderBy. |
||
| 58 | * |
||
| 59 | * Primary Key of Model by default |
||
| 60 | * |
||
| 61 | * @var string |
||
| 62 | */ |
||
| 63 | protected $orderBy; |
||
| 64 | |||
| 65 | /** |
||
| 66 | * Sort By - Either Desc or Asc. |
||
| 67 | * |
||
| 68 | * @var string |
||
| 69 | */ |
||
| 70 | protected $sortBy; |
||
| 71 | |||
| 72 | /** |
||
| 73 | * Finds an existing Model entry and sets it to the current model. |
||
| 74 | * |
||
| 75 | * @param int $modelitemId |
||
| 76 | * |
||
| 77 | * @return |
||
| 78 | */ |
||
| 79 | public function find($modelitemId) |
||
| 85 | |||
| 86 | /** |
||
| 87 | * Returns Model Items, either all() or paginated(). |
||
| 88 | * |
||
| 89 | * Filtered by any defined query filters ($queryFilter) |
||
| 90 | * Ordered by Managed Model orderBy and sortBy methods |
||
| 91 | * |
||
| 92 | * @return |
||
| 93 | */ |
||
| 94 | public function items($count = false) |
||
| 100 | |||
| 101 | /** |
||
| 102 | * Returns All Model Items, either all() or paginated(). |
||
| 103 | * |
||
| 104 | * Filtered by any defined query filters ($queryFilter) |
||
| 105 | * Ordered by Managed Model orderBy and sortBy methods |
||
| 106 | * |
||
| 107 | * @return |
||
| 108 | */ |
||
| 109 | View Code Duplication | public function allItems($count = false) |
|
| 119 | |||
| 120 | /** |
||
| 121 | * Returns Model Items, either all() or paginated(). |
||
| 122 | * |
||
| 123 | * Filtered by any defined query filters ($queryFilter) |
||
| 124 | * Ordered by Managed Model orderBy and sortBy methods |
||
| 125 | * |
||
| 126 | * @return |
||
| 127 | */ |
||
| 128 | View Code Duplication | public function onlyTrashedItems($count = false) |
|
| 138 | |||
| 139 | /** |
||
| 140 | * Performs the Model Query. |
||
| 141 | * |
||
| 142 | * @return \Illuminate\Database\Eloquent\Collection |
||
| 143 | */ |
||
| 144 | private function query($count) |
||
| 165 | |||
| 166 | /** |
||
| 167 | * Return Totals of All, With Trashed and Only Trashed. |
||
| 168 | * |
||
| 169 | * @return array |
||
| 170 | */ |
||
| 171 | public function totals() |
||
| 183 | |||
| 184 | /** |
||
| 185 | * Return Managed Model OrderBy. |
||
| 186 | * |
||
| 187 | * Primary key is default. |
||
| 188 | * |
||
| 189 | * @return string |
||
| 190 | */ |
||
| 191 | public function orderBy() |
||
| 203 | |||
| 204 | /** |
||
| 205 | * Return Managed Model SortBy (Asc or Desc). |
||
| 206 | * |
||
| 207 | * Descending is default. |
||
| 208 | * |
||
| 209 | * @return string |
||
| 210 | */ |
||
| 211 | public function sortBy() |
||
| 223 | |||
| 224 | /** |
||
| 225 | * Get the number of models to return per page. |
||
| 226 | * |
||
| 227 | * @return int |
||
| 228 | */ |
||
| 229 | public function getPerPage() |
||
| 233 | |||
| 234 | /** |
||
| 235 | * Set the number of models to return per page. |
||
| 236 | * |
||
| 237 | * @param int $perPage |
||
| 238 | */ |
||
| 239 | public function setPerPage($perPage) |
||
| 243 | |||
| 244 | /** |
||
| 245 | * Apply the Query Filters. |
||
| 246 | * |
||
| 247 | * @return |
||
| 248 | */ |
||
| 249 | private function applyQueryFilters() |
||
| 259 | |||
| 260 | /** |
||
| 261 | * Apply the Query Filters specific to this Request. |
||
| 262 | * |
||
| 263 | * @return |
||
| 264 | */ |
||
| 265 | private function queryFilterRequest() |
||
| 277 | |||
| 278 | /** |
||
| 279 | * Create the Query Filter from Array. |
||
| 280 | * |
||
| 281 | * @return |
||
| 282 | */ |
||
| 283 | private function createQueryFilter() |
||
| 294 | |||
| 295 | /** |
||
| 296 | * Access the Query Filter. |
||
| 297 | * |
||
| 298 | * @return |
||
| 299 | */ |
||
| 300 | public function queryFilter() |
||
| 304 | |||
| 305 | /** |
||
| 306 | * Access the Query Filter Options. |
||
| 307 | * |
||
| 308 | * @return |
||
| 309 | */ |
||
| 310 | public function filters() |
||
| 314 | |||
| 315 | /** |
||
| 316 | * Associative array of safe filter names to |
||
| 317 | * their corresponding normal counterpart. |
||
| 318 | * |
||
| 319 | * @return |
||
| 320 | */ |
||
| 321 | public function safeFilters() |
||
| 331 | |||
| 332 | /** |
||
| 333 | * Set the Query Filter. |
||
| 334 | * |
||
| 335 | * @param array $filter |
||
| 336 | */ |
||
| 337 | public function setQueryFilter($filter = []) |
||
| 341 | } |
||
| 342 |
PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.
Let’s take a look at an example:
If we look at the
getEmail()method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:On the hand, if we look at the
setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call: