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 |
||
23 | class Tag extends ModelAbstract |
||
24 | { |
||
25 | use Sluggable; |
||
26 | use Validation; |
||
27 | |||
28 | const TABLE_NAME = 'ginopane_blogtaxonomy_tags'; |
||
29 | |||
30 | /** @deprecated */ |
||
31 | const CROSS_REFERENCE_TABLE_NAME = 'ginopane_blogtaxonomy_post_tag'; |
||
32 | |||
33 | const PIVOT_COLUMN = 'ginopane_blogtaxonomy_taggable'; |
||
34 | |||
35 | const PIVOT_TABLE = 'ginopane_blogtaxonomy_taggables'; |
||
36 | |||
37 | /** |
||
38 | * @var string The database table used by the model |
||
39 | */ |
||
40 | public $table = self::TABLE_NAME; |
||
41 | |||
42 | /** |
||
43 | * Specifying of implemented behaviours as strings is convenient when |
||
44 | * the target behaviour could be missing due to disabled or not installed |
||
45 | * plugin. You won't get an error, the plugin would simply work without model |
||
46 | * |
||
47 | * @var array |
||
48 | */ |
||
49 | public $implement = ['@RainLab.Translate.Behaviors.TranslatableModel']; |
||
50 | |||
51 | /** |
||
52 | * Translatable properties, indexed property will be available in queries |
||
53 | * |
||
54 | * @var array |
||
55 | */ |
||
56 | public $translatable = [ |
||
57 | 'name', |
||
58 | [ |
||
59 | 'slug', |
||
60 | 'index' => true |
||
61 | ] |
||
62 | ]; |
||
63 | |||
64 | /** |
||
65 | * @var array |
||
66 | */ |
||
67 | protected $slugs = ['slug' => 'name']; |
||
68 | |||
69 | /** |
||
70 | * Relations |
||
71 | * |
||
72 | * @var array |
||
73 | */ |
||
74 | public $morphedByMany = [ |
||
75 | 'posts' => [Post::class, 'name' => Tag::PIVOT_COLUMN], |
||
76 | 'series' => [Series::class, 'name' => Tag::PIVOT_COLUMN], |
||
77 | ]; |
||
78 | |||
79 | /** |
||
80 | * Fillable fields |
||
81 | * |
||
82 | * @var array |
||
83 | */ |
||
84 | public $fillable = [ |
||
85 | 'name', |
||
86 | 'slug', |
||
87 | ]; |
||
88 | |||
89 | /** |
||
90 | * Validation rules |
||
91 | * |
||
92 | * @var array |
||
93 | */ |
||
94 | public $rules = [ |
||
95 | 'name' => "required|unique:" . self::TABLE_NAME . "|min:2|regex:/^[\w\-\. ]+$/iu", |
||
96 | 'slug' => "required|unique:" . self::TABLE_NAME . "|min:2|regex:/^[\w\-]+$/iu" |
||
97 | ]; |
||
98 | |||
99 | /** |
||
100 | * The tag might be created via tag list and therefore it won't have a slug |
||
101 | */ |
||
102 | public function beforeValidate() |
||
109 | |||
110 | /** |
||
111 | * Validation messages |
||
112 | * |
||
113 | * @var array |
||
114 | */ |
||
115 | public $customMessages = [ |
||
116 | 'name.required' => Plugin::LOCALIZATION_KEY . 'form.tags.name_required', |
||
117 | 'name.unique' => Plugin::LOCALIZATION_KEY . 'form.tags.name_unique', |
||
118 | 'name.regex' => Plugin::LOCALIZATION_KEY . 'form.tags.name_invalid', |
||
119 | 'name.min' => Plugin::LOCALIZATION_KEY . 'form.tags.name_too_short', |
||
120 | |||
121 | 'slug.required' => Plugin::LOCALIZATION_KEY . 'form.tags.slug_required', |
||
122 | 'slug.unique' => Plugin::LOCALIZATION_KEY . 'form.tags.slug_unique', |
||
123 | 'slug.regex' => Plugin::LOCALIZATION_KEY . 'form.tags.slug_invalid', |
||
124 | 'slug.min' => Plugin::LOCALIZATION_KEY . 'form.tags.slug_too_short', |
||
125 | ]; |
||
126 | |||
127 | /** |
||
128 | * The attributes on which the post list can be ordered |
||
129 | * |
||
130 | * @var array |
||
131 | */ |
||
132 | public static $sortingOptions = [ |
||
133 | 'name asc' => Plugin::LOCALIZATION_KEY . 'order_options.name_asc', |
||
134 | 'name desc' => Plugin::LOCALIZATION_KEY . 'order_options.name_desc', |
||
135 | 'created_at asc' => Plugin::LOCALIZATION_KEY . 'order_options.created_at_asc', |
||
136 | 'created_at desc' => Plugin::LOCALIZATION_KEY . 'order_options.created_at_desc', |
||
137 | 'posts_count asc' => Plugin::LOCALIZATION_KEY . 'order_options.post_count_asc', |
||
138 | 'posts_count desc' => Plugin::LOCALIZATION_KEY . 'order_options.post_count_desc', |
||
139 | 'random' => Plugin::LOCALIZATION_KEY . 'order_options.random' |
||
140 | ]; |
||
141 | |||
142 | /** |
||
143 | * Returns post combined combined from posts with this tag and posts with series under this this tag |
||
144 | * |
||
145 | * @return int |
||
146 | */ |
||
147 | public function getCombinedPostCountAttribute(): int |
||
151 | |||
152 | /** |
||
153 | * @param array $params |
||
154 | * |
||
155 | * @return array |
||
156 | */ |
||
157 | protected function getModelUrlParams(array $params): array |
||
163 | |||
164 | /** |
||
165 | * @param Builder $query |
||
166 | * @param array $options |
||
167 | * |
||
168 | * @return void |
||
169 | */ |
||
170 | protected function withRelation(Builder $query, array $options) |
||
176 | |||
177 | /** |
||
178 | * @param Builder $query |
||
179 | * @param array $options |
||
180 | */ |
||
181 | protected function queryPostSlug(Builder $query, array $options) |
||
195 | |||
196 | /** |
||
197 | * @param Builder $query |
||
198 | * @param array $options |
||
199 | * |
||
200 | * @return void |
||
201 | */ |
||
202 | protected function queryDisplayEmpty(Builder $query, array $options) |
||
210 | |||
211 | /** |
||
212 | * @param Builder $query |
||
213 | * @param array $options |
||
214 | * |
||
215 | * @return void |
||
216 | */ |
||
217 | View Code Duplication | private function postRelation(Builder $query, array $options) |
|
241 | |||
242 | /** |
||
243 | * @param Builder $query |
||
244 | * @param array $options |
||
245 | * |
||
246 | * @return void |
||
247 | */ |
||
248 | View Code Duplication | private function seriesRelation(Builder $query, array $options) |
|
270 | } |
||
271 |
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.