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 |
||
| 51 | class FilesProvider implements IFullTextSearchProvider { |
||
| 52 | |||
| 53 | |||
| 54 | const FILES_PROVIDER_ID = 'files'; |
||
| 55 | |||
| 56 | |||
| 57 | /** @var IL10N */ |
||
| 58 | private $l10n; |
||
| 59 | |||
| 60 | /** @var ConfigService */ |
||
| 61 | private $configService; |
||
| 62 | |||
| 63 | /** @var FilesService */ |
||
| 64 | private $filesService; |
||
| 65 | |||
| 66 | /** @var SearchService */ |
||
| 67 | private $searchService; |
||
| 68 | |||
| 69 | /** @var ElasticSearchService */ |
||
| 70 | private $elasticSearchService; |
||
| 71 | |||
| 72 | /** @var MiscService */ |
||
| 73 | private $miscService; |
||
| 74 | |||
| 75 | |||
| 76 | /** @var Runner */ |
||
| 77 | private $runner; |
||
| 78 | |||
| 79 | /** @var IndexOptions */ |
||
| 80 | private $indexOptions = []; |
||
| 81 | |||
| 82 | |||
| 83 | View Code Duplication | public function __construct( |
|
|
|
|||
| 84 | IL10N $l10n, ConfigService $configService, FilesService $filesService, |
||
| 85 | SearchService $searchService, ElasticSearchService $elasticSearchService, |
||
| 86 | MiscService $miscService |
||
| 87 | ) { |
||
| 88 | $this->l10n = $l10n; |
||
| 89 | $this->configService = $configService; |
||
| 90 | $this->filesService = $filesService; |
||
| 91 | $this->searchService = $searchService; |
||
| 92 | $this->elasticSearchService = $elasticSearchService; |
||
| 93 | $this->miscService = $miscService; |
||
| 94 | } |
||
| 95 | |||
| 96 | /** |
||
| 97 | * return unique id of the provider |
||
| 98 | */ |
||
| 99 | public function getId() { |
||
| 100 | return self::FILES_PROVIDER_ID; |
||
| 101 | } |
||
| 102 | |||
| 103 | |||
| 104 | /** |
||
| 105 | * return name of the provider |
||
| 106 | */ |
||
| 107 | public function getName() { |
||
| 108 | return 'Files'; |
||
| 109 | } |
||
| 110 | |||
| 111 | |||
| 112 | /** |
||
| 113 | * @deprecated |
||
| 114 | * @return string |
||
| 115 | */ |
||
| 116 | public function getVersion() { |
||
| 117 | return ''; |
||
| 118 | } |
||
| 119 | |||
| 120 | |||
| 121 | /** |
||
| 122 | * @return array |
||
| 123 | */ |
||
| 124 | public function getConfiguration() { |
||
| 125 | return $this->configService->getConfig(); |
||
| 126 | } |
||
| 127 | |||
| 128 | |||
| 129 | /** |
||
| 130 | * @deprecated |
||
| 131 | * @return string |
||
| 132 | */ |
||
| 133 | public function getAppId() { |
||
| 134 | return ''; |
||
| 135 | } |
||
| 136 | |||
| 137 | |||
| 138 | public function setRunner(Runner $runner) { |
||
| 139 | $this->runner = $runner; |
||
| 140 | } |
||
| 141 | |||
| 142 | |||
| 143 | /** |
||
| 144 | * @param IndexOptions $options |
||
| 145 | */ |
||
| 146 | public function setIndexOptions($options) { |
||
| 147 | $this->indexOptions = $options; |
||
| 148 | } |
||
| 149 | |||
| 150 | |||
| 151 | /** |
||
| 152 | * @return array |
||
| 153 | */ |
||
| 154 | public function getOptionsTemplate() { |
||
| 155 | // 'template' => 'options.panel', |
||
| 156 | return [ |
||
| 157 | 'panel' => [ |
||
| 158 | 'options' => [ |
||
| 159 | [ |
||
| 160 | 'name' => 'files_within_dir', |
||
| 161 | 'title' => $this->l10n->t('Within current directory'), |
||
| 162 | 'type' => 'checkbox' |
||
| 163 | ], |
||
| 164 | [ |
||
| 165 | 'name' => 'files_local', |
||
| 166 | 'title' => $this->l10n->t('Within local files'), |
||
| 167 | 'type' => 'checkbox' |
||
| 168 | ], |
||
| 169 | [ |
||
| 170 | 'name' => 'files_external', |
||
| 171 | 'title' => $this->l10n->t('Within external files'), |
||
| 172 | 'type' => 'checkbox' |
||
| 173 | ], |
||
| 174 | [ |
||
| 175 | 'name' => 'files_group_folders', |
||
| 176 | 'title' => $this->l10n->t('Within group folders'), |
||
| 177 | 'type' => 'checkbox' |
||
| 178 | ], |
||
| 179 | [ |
||
| 180 | 'name' => 'files_extension', |
||
| 181 | 'title' => $this->l10n->t('Filter by extension'), |
||
| 182 | 'type' => 'input', |
||
| 183 | 'size' => 'small', |
||
| 184 | 'placeholder' => 'txt' |
||
| 185 | ] |
||
| 186 | ] |
||
| 187 | ], |
||
| 188 | 'navigation' => [ |
||
| 189 | 'icon' => 'icon-fts-files', |
||
| 190 | 'options' => [ |
||
| 191 | [ |
||
| 192 | 'name' => 'files_local', |
||
| 193 | 'title' => $this->l10n->t('Local Files'), |
||
| 194 | 'type' => 'checkbox' |
||
| 195 | ], |
||
| 196 | [ |
||
| 197 | 'name' => 'files_external', |
||
| 198 | 'title' => $this->l10n->t('External Files'), |
||
| 199 | 'type' => 'checkbox' |
||
| 200 | ], |
||
| 201 | [ |
||
| 202 | 'name' => 'files_group_folders', |
||
| 203 | 'title' => $this->l10n->t('Group Folders'), |
||
| 204 | 'type' => 'checkbox' |
||
| 205 | ], |
||
| 206 | [ |
||
| 207 | 'name' => 'files_extension', |
||
| 208 | 'title' => $this->l10n->t('Extension'), |
||
| 209 | 'type' => 'input', |
||
| 210 | 'size' => 'small', |
||
| 211 | 'placeholder' => 'txt' |
||
| 212 | ] |
||
| 213 | ] |
||
| 214 | ] |
||
| 215 | ]; |
||
| 216 | } |
||
| 217 | |||
| 218 | |||
| 219 | /** |
||
| 220 | * @deprecated |
||
| 221 | */ |
||
| 222 | public function getOptions() { |
||
| 223 | return $this->getOptionsTemplate(); |
||
| 224 | } |
||
| 225 | |||
| 226 | |||
| 227 | /** |
||
| 228 | * called when loading all providers. |
||
| 229 | * |
||
| 230 | * Loading some containers. |
||
| 231 | * |
||
| 232 | * @throws QueryException |
||
| 233 | */ |
||
| 234 | public function loadProvider() { |
||
| 235 | $app = new Application(); |
||
| 236 | |||
| 237 | $container = $app->getContainer(); |
||
| 238 | $this->configService = $container->query(ConfigService::class); |
||
| 239 | $this->filesService = $container->query(FilesService::class); |
||
| 240 | $this->searchService = $container->query(SearchService::class); |
||
| 241 | $this->elasticSearchService = $container->query(ElasticSearchService::class); |
||
| 242 | $this->miscService = $container->query(MiscService::class); |
||
| 243 | } |
||
| 244 | |||
| 245 | |||
| 246 | /** |
||
| 247 | * returns all indexable document for a user. |
||
| 248 | * There is no need to fill the document with content at this point. |
||
| 249 | * |
||
| 250 | * $platform is provided if the mapping needs to be changed. |
||
| 251 | * |
||
| 252 | * @param string $userId |
||
| 253 | * |
||
| 254 | * @return IndexDocument[] |
||
| 255 | * @throws InvalidPathException |
||
| 256 | * @throws NotFoundException |
||
| 257 | */ |
||
| 258 | public function generateIndexableDocuments($userId) { |
||
| 259 | $files = $this->filesService->getFilesFromUser($userId, $this->indexOptions); |
||
| 260 | |||
| 261 | return $files; |
||
| 262 | } |
||
| 263 | |||
| 264 | |||
| 265 | /** |
||
| 266 | * generate documents prior to the indexing. |
||
| 267 | * throw NoResultException if no more result |
||
| 268 | * |
||
| 269 | * @param IndexDocument[] $chunk |
||
| 270 | * |
||
| 271 | * @return IndexDocument[] |
||
| 272 | * @deprecated |
||
| 273 | */ |
||
| 274 | public function fillIndexDocuments($chunk) { |
||
| 275 | return []; |
||
| 276 | } |
||
| 277 | |||
| 278 | |||
| 279 | /** |
||
| 280 | * @param IndexDocument $document |
||
| 281 | */ |
||
| 282 | public function fillIndexDocument(IndexDocument $document) { |
||
| 283 | /** @var FilesDocument $document */ |
||
| 284 | $this->filesService->generateDocument($document); |
||
| 285 | $this->updateRunnerInfo('info', $document->getMimetype()); |
||
| 286 | } |
||
| 287 | |||
| 288 | |||
| 289 | /** |
||
| 290 | * @param IndexDocument $document |
||
| 291 | * |
||
| 292 | * @return bool |
||
| 293 | */ |
||
| 294 | public function isDocumentUpToDate($document) { |
||
| 295 | return $this->filesService->isDocumentUpToDate($document); |
||
| 296 | } |
||
| 297 | |||
| 298 | |||
| 299 | /** |
||
| 300 | * @param Index $index |
||
| 301 | * |
||
| 302 | * @return IndexDocument |
||
| 303 | * @throws InvalidPathException |
||
| 304 | * @throws NotFoundException |
||
| 305 | * @throws NotPermittedException |
||
| 306 | * @throws FileIsNotIndexableException |
||
| 307 | */ |
||
| 308 | public function updateDocument(Index $index) { |
||
| 309 | $document = $this->filesService->updateDocument($index); |
||
| 310 | $this->updateRunnerInfo('info', $document->getMimetype()); |
||
| 311 | |||
| 312 | return $document; |
||
| 313 | } |
||
| 314 | |||
| 315 | |||
| 316 | /** |
||
| 317 | * @param IFullTextSearchPlatform $platform |
||
| 318 | */ |
||
| 319 | public function onInitializingIndex(IFullTextSearchPlatform $platform) { |
||
| 322 | |||
| 323 | |||
| 324 | /** |
||
| 325 | * @param IFullTextSearchPlatform $platform |
||
| 326 | */ |
||
| 327 | public function onResettingIndex(IFullTextSearchPlatform $platform) { |
||
| 330 | |||
| 331 | |||
| 332 | /** |
||
| 333 | * not used yet |
||
| 334 | */ |
||
| 335 | public function unloadProvider() { |
||
| 337 | |||
| 338 | |||
| 339 | /** |
||
| 340 | * before a search, improve the request |
||
| 341 | * |
||
| 342 | * @param SearchRequest $request |
||
| 343 | */ |
||
| 344 | public function improveSearchRequest(SearchRequest $request) { |
||
| 347 | |||
| 348 | |||
| 349 | /** |
||
| 350 | * after a search, improve results |
||
| 351 | * |
||
| 352 | * @param SearchResult $searchResult |
||
| 353 | */ |
||
| 354 | public function improveSearchResult(SearchResult $searchResult) { |
||
| 357 | |||
| 358 | |||
| 359 | /** |
||
| 360 | * @param string $info |
||
| 361 | * @param string $value |
||
| 362 | */ |
||
| 363 | private function updateRunnerInfo($info, $value) { |
||
| 364 | if ($this->runner === null) { |
||
| 365 | return; |
||
| 366 | } |
||
| 367 | |||
| 368 | $this->runner->setInfo($info, $value); |
||
| 369 | } |
||
| 370 | |||
| 371 | |||
| 372 | } |
||
| 373 |
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.