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 ProductsRepository 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 ProductsRepository, and based on these observations, apply Extract Interface, too.
| 1 | <?php | ||
| 13 | class ProductsRepository extends Repository | ||
| 14 | { | ||
| 15 | /** | ||
| 16 | * @return Product | ||
| 17 | */ | ||
| 18 | public function getModel() | ||
| 22 | |||
| 23 | /** | ||
| 24 | * Get all published products | ||
| 25 | * | ||
| 26 | * @return mixed | ||
| 27 | */ | ||
| 28 | public function getPublic() | ||
| 34 | |||
| 35 | /** | ||
| 36 | * Find product by id/slug. | ||
| 37 | * | ||
| 38 | * @param $slug | ||
| 39 | * @return Product | ||
| 40 | */ | ||
| 41 | View Code Duplication | public function find($slug) | |
| 54 | |||
| 55 | /** | ||
| 56 | * Create product. | ||
| 57 | * | ||
| 58 | * @param array $data | ||
| 59 | * @return Product | ||
| 60 | */ | ||
| 61 | public function create(array $data) | ||
| 77 | |||
| 78 | /** | ||
| 79 | * Update data. | ||
| 80 | * | ||
| 81 | * @param $product | ||
| 82 | * @param $data | ||
| 83 | * @return mixed | ||
| 84 | */ | ||
| 85 | public function update($product, $data) | ||
| 107 | |||
| 108 | /** | ||
| 109 | * Reformat date. | ||
| 110 | * | ||
| 111 | * @param $date | ||
| 112 | * @param string $delimiter | ||
| 113 | * @return mixed | ||
| 114 | */ | ||
| 115 | public function reformatDateString($date, $delimiter = '.') | ||
| 125 | |||
| 126 | /** | ||
| 127 | * Convert string date to \Carbon/Carbon timestamp. | ||
| 128 | * | ||
| 129 | * @param $date | ||
| 130 | * @return static | ||
| 131 | */ | ||
| 132 | public function dateToTimestamp($date) | ||
| 138 | |||
| 139 | /** | ||
| 140 | * Remove product row from table. | ||
| 141 | * | ||
| 142 | * @param $id | ||
| 143 | * @return bool|null | ||
| 144 | * @throws \Exception | ||
| 145 | */ | ||
| 146 | public function delete($id) | ||
| 150 | |||
| 151 | /** | ||
| 152 | * Get random products. | ||
| 153 | * | ||
| 154 | * @return \Illuminate\Database\Eloquent\Collection | ||
| 155 | */ | ||
| 156 | public function getSomeRandomProducts() | ||
| 184 | |||
| 185 | /** | ||
| 186 | * Get drafted product by id. | ||
| 187 | * | ||
| 188 | * @param $id | ||
| 189 | * @return mixed | ||
| 190 | */ | ||
| 191 | public function findDrafted($id) | ||
| 198 | |||
| 199 | public function getCount($id) | ||
| 206 | |||
| 207 | public function countInLotProduct($id) | ||
| 213 | |||
| 214 | public function search($filters) | ||
| 244 | |||
| 245 | /** | ||
| 246 | * Remove percent from sale if it exists. | ||
| 247 | * | ||
| 248 | * @param $sale | ||
| 249 | * @return int | ||
| 250 | */ | ||
| 251 | private function formatSale($sale) | ||
| 257 | |||
| 258 | /** | ||
| 259 | * Get same products. | ||
| 260 | * | ||
| 261 | * @param mixed | ||
| 262 | */ | ||
| 263 | public function getSameProduct($id,$limit=10) | ||
| 278 | |||
| 279 | /** | ||
| 280 | * Get public latest created products. | ||
| 281 | * | ||
| 282 | * @param int $count | ||
| 283 | * @return mixed | ||
| 284 | */ | ||
| 285 | public function getPublicLatest($count = 8) | ||
| 294 | |||
| 295 | /** | ||
| 296 | * Get popular products. | ||
| 297 | * | ||
| 298 | * @return mixed | ||
| 299 | */ | ||
| 300 | public function getFeaturedPublic($count = 8) | ||
| 310 | |||
| 311 | /** | ||
| 312 | * Get expire soon products. | ||
| 313 | * | ||
| 314 | * @param int $count | ||
| 315 | * @return mixed | ||
| 316 | */ | ||
| 317 | public function getPublicExpireSoon($count = 8) | ||
| 328 | |||
| 329 | /** | ||
| 330 | * Expire soon products. | ||
| 331 | * | ||
| 332 | * @param int $paginate | ||
| 333 | * @return mixed | ||
| 334 | */ | ||
| 335 | public function getExpireSoon($paginate = 10) | ||
| 359 | |||
| 360 | /** | ||
| 361 | * Create plain product for \App\Lot $lot | ||
| 362 | * | ||
| 363 | * @param Lot $lot | ||
| 364 | * @return static | ||
| 365 | */ | ||
| 366 | public function createPlain(Lot $lot) | ||
| 384 | |||
| 385 | public function saveProduct($product, array $data) | ||
| 399 | } | 
This check marks calls to methods that do not seem to exist on an object.
This is most likely the result of a method being renamed without all references to it being renamed likewise.