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 |
||
11 | class QueryBuilderFlex extends QueryBuilderHandler |
||
12 | { |
||
13 | /** @var string The column name of the column dedicated to storing the name of the model */ |
||
14 | private $modelNameColumn; |
||
15 | |||
16 | /** @var Model|string The FQN of the model object this QueryBuilder instance is for */ |
||
17 | private $modelType = null; |
||
18 | |||
19 | /** @var int The amount of results per page with regards to result pagination */ |
||
20 | private $resultsPerPage; |
||
21 | |||
22 | // |
||
23 | // Factories |
||
24 | // |
||
25 | |||
26 | /** |
||
27 | * Create a QueryBuilder instance for a specific table. |
||
28 | * |
||
29 | * @param string $tableName |
||
30 | * |
||
31 | * @throws Exception If there is no database connection configured. |
||
32 | * |
||
33 | * @return QueryBuilderFlex |
||
34 | */ |
||
35 | View Code Duplication | public static function createForTable($tableName) |
|
46 | |||
47 | /** |
||
48 | * Creeate a QueryBuilder instance to work with a Model. |
||
49 | * |
||
50 | * @param string $modelType The FQN for the model that |
||
51 | * |
||
52 | * @throws Exception If there is no database connection configured. |
||
53 | * |
||
54 | * @return QueryBuilderFlex |
||
55 | */ |
||
56 | View Code Duplication | public static function createForModel($modelType) |
|
68 | |||
69 | // |
||
70 | // Overridden QueryBuilder Functions |
||
71 | // |
||
72 | |||
73 | /** |
||
74 | * {@inheritdoc} |
||
75 | */ |
||
76 | public function __construct(\Pixie\Connection $connection = null) |
||
82 | |||
83 | /** |
||
84 | * {@inheritdoc} |
||
85 | */ |
||
86 | public function limit($limit) |
||
92 | |||
93 | /** |
||
94 | * {@inheritdoc} |
||
95 | */ |
||
96 | protected function whereHandler($key, $operator = null, $value = null, $joiner = 'AND') |
||
104 | |||
105 | // |
||
106 | // QueryBuilderFlex unique functions |
||
107 | // |
||
108 | |||
109 | /** |
||
110 | * Request that only non-deleted Models should be returned. |
||
111 | * |
||
112 | * @return static |
||
113 | */ |
||
114 | public function active() |
||
136 | |||
137 | /** |
||
138 | * An alias for QueryBuilder::getModels(), with fast fetching on by default and no return of results. |
||
139 | * |
||
140 | * @param bool $fastFetch Whether to perform one query to load all the model data instead of fetching them one by |
||
141 | * one |
||
142 | * |
||
143 | * @throws \Pixie\Exception |
||
144 | * |
||
145 | * @return void |
||
146 | */ |
||
147 | public function addToCache($fastFetch = true) |
||
151 | |||
152 | /** |
||
153 | * Get the amount of pages this query would have. |
||
154 | * |
||
155 | * @return int |
||
156 | */ |
||
157 | public function countPages() |
||
161 | |||
162 | /** |
||
163 | * Request that a specific model is not returned. |
||
164 | * |
||
165 | * @param Model|int $model The ID or model you don't want to get |
||
166 | * |
||
167 | * @return static |
||
168 | */ |
||
169 | public function except($model) |
||
179 | |||
180 | /** |
||
181 | * Only show results from a specific page. |
||
182 | * |
||
183 | * This method will automatically take care of the calculations for a correct OFFSET. |
||
184 | * |
||
185 | * @param int|null $page The page number (or null to show all pages - counting starts from 0) |
||
186 | * |
||
187 | * @return static |
||
188 | */ |
||
189 | public function fromPage($page) |
||
204 | |||
205 | /** |
||
206 | * Perform the query and get the results as Models. |
||
207 | * |
||
208 | * @param bool $fastFetch Whether to perform one query to load all the model data instead of fetching them one by |
||
209 | * one (ignores cache) |
||
210 | * |
||
211 | * @throws \Pixie\Exception |
||
212 | * |
||
213 | * @return array |
||
214 | */ |
||
215 | public function getModels($fastFetch = false) |
||
236 | |||
237 | /** |
||
238 | * Perform the query and get back the results in an array of names. |
||
239 | * |
||
240 | * @throws UnexpectedValueException When no name column has been specified |
||
241 | * |
||
242 | * @return string[] An array of the type $id => $name |
||
243 | */ |
||
244 | public function getNames() |
||
257 | |||
258 | /** |
||
259 | * Set the model this QueryBuilder will be working this. |
||
260 | * |
||
261 | * This information is used for automatically retrieving table names, eager columns, and lazy columns for these |
||
262 | * models. |
||
263 | * |
||
264 | * @param string $modelType The FQN of the model this QueryBuilder will be working with |
||
265 | * |
||
266 | * @return $this |
||
267 | */ |
||
268 | public function setModelType($modelType) |
||
274 | |||
275 | /** |
||
276 | * Set the column that'll be used as the human-friendly name of the model. |
||
277 | * |
||
278 | * @param string $columnName |
||
279 | * |
||
280 | * @return static |
||
281 | */ |
||
282 | public function setNameColumn($columnName) |
||
292 | |||
293 | /** |
||
294 | * Make sure that Models invisible to a player are not returned. |
||
295 | * |
||
296 | * Note that this method does not take PermissionModel::canBeSeenBy() into |
||
297 | * consideration for performance purposes, so you will have to override this |
||
298 | * in your query builder if necessary. |
||
299 | * |
||
300 | * @param Player $player The player in question |
||
301 | * @param bool $showDeleted Use false to hide deleted models even from admins |
||
302 | * |
||
303 | * @return static |
||
304 | */ |
||
305 | public function visibleTo(Player $player, $showDeleted = false) |
||
326 | } |
||
327 |
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.