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 ExceptionConversion 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 ExceptionConversion, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 27 | class ExceptionConversion extends Gateway |
||
| 28 | { |
||
| 29 | /** |
||
| 30 | * The wrapped gateway. |
||
| 31 | * |
||
| 32 | * @var Gateway |
||
| 33 | */ |
||
| 34 | protected $innerGateway; |
||
| 35 | |||
| 36 | /** |
||
| 37 | * Creates a new exception conversion gateway around $innerGateway. |
||
| 38 | * |
||
| 39 | * @param Gateway $innerGateway |
||
| 40 | */ |
||
| 41 | public function __construct(Gateway $innerGateway) |
||
| 45 | |||
| 46 | /** |
||
| 47 | * Get context definition for external storage layers. |
||
| 48 | * |
||
| 49 | * @return array |
||
| 50 | */ |
||
| 51 | View Code Duplication | public function getContext() |
|
| 61 | |||
| 62 | /** |
||
| 63 | * Inserts a new content object. |
||
| 64 | * |
||
| 65 | * @param \eZ\Publish\SPI\Persistence\Content\CreateStruct $struct |
||
| 66 | * @param mixed $currentVersionNo |
||
| 67 | * |
||
| 68 | * @return int ID |
||
| 69 | */ |
||
| 70 | View Code Duplication | public function insertContentObject(CreateStruct $struct, $currentVersionNo = 1) |
|
| 80 | |||
| 81 | /** |
||
| 82 | * Inserts a new version. |
||
| 83 | * |
||
| 84 | * @param \eZ\Publish\SPI\Persistence\Content\VersionInfo $versionInfo |
||
| 85 | * @param \eZ\Publish\SPI\Persistence\Content\Field[] $fields |
||
| 86 | * |
||
| 87 | * @return int ID |
||
| 88 | */ |
||
| 89 | View Code Duplication | public function insertVersion(VersionInfo $versionInfo, array $fields) |
|
| 99 | |||
| 100 | /** |
||
| 101 | * Updates an existing content identified by $contentId in respect to $struct. |
||
| 102 | * |
||
| 103 | * @param int $contentId |
||
| 104 | * @param \eZ\Publish\SPI\Persistence\Content\MetadataUpdateStruct $struct |
||
| 105 | * @param \eZ\Publish\SPI\Persistence\Content\VersionInfo $prePublishVersionInfo Provided on publish |
||
| 106 | */ |
||
| 107 | View Code Duplication | public function updateContent($contentId, MetadataUpdateStruct $struct, VersionInfo $prePublishVersionInfo = null) |
|
| 117 | |||
| 118 | /** |
||
| 119 | * Updates version $versionNo for content identified by $contentId, in respect to $struct. |
||
| 120 | * |
||
| 121 | * @param int $contentId |
||
| 122 | * @param int $versionNo |
||
| 123 | * @param \eZ\Publish\SPI\Persistence\Content\UpdateStruct $struct |
||
| 124 | */ |
||
| 125 | View Code Duplication | public function updateVersion($contentId, $versionNo, UpdateStruct $struct) |
|
| 135 | |||
| 136 | /** |
||
| 137 | * Updates "always available" flag for content identified by $contentId, in respect to $alwaysAvailable. |
||
| 138 | * |
||
| 139 | * @param int $contentId |
||
| 140 | * @param bool $newAlwaysAvailable New "always available" value |
||
| 141 | */ |
||
| 142 | View Code Duplication | public function updateAlwaysAvailableFlag($contentId, $newAlwaysAvailable) |
|
| 152 | |||
| 153 | /** |
||
| 154 | * Sets the state of object identified by $contentId and $version to $state. |
||
| 155 | * |
||
| 156 | * The $status can be one of STATUS_DRAFT, STATUS_PUBLISHED, STATUS_ARCHIVED |
||
| 157 | * |
||
| 158 | * @param int $contentId |
||
| 159 | * @param int $version |
||
| 160 | * @param int $status |
||
| 161 | * |
||
| 162 | * @return bool |
||
| 163 | */ |
||
| 164 | View Code Duplication | public function setStatus($contentId, $version, $status) |
|
| 174 | |||
| 175 | /** |
||
| 176 | * Inserts a new field. |
||
| 177 | * |
||
| 178 | * Only used when a new field is created (i.e. a new object or a field in a |
||
| 179 | * new language!). After that, field IDs need to stay the same, only the |
||
| 180 | * version number changes. |
||
| 181 | * |
||
| 182 | * @param \eZ\Publish\SPI\Persistence\Content $content |
||
| 183 | * @param \eZ\Publish\SPI\Persistence\Content\Field $field |
||
| 184 | * @param \eZ\Publish\Core\Persistence\Legacy\Content\StorageFieldValue $value |
||
| 185 | * |
||
| 186 | * @return int ID |
||
| 187 | */ |
||
| 188 | View Code Duplication | public function insertNewField(Content $content, Field $field, StorageFieldValue $value) |
|
| 198 | |||
| 199 | /** |
||
| 200 | * Inserts an existing field. |
||
| 201 | * |
||
| 202 | * Used to insert a field with an exsting ID but a new version number. |
||
| 203 | * |
||
| 204 | * @param Content $content |
||
| 205 | * @param Field $field |
||
| 206 | * @param StorageFieldValue $value |
||
| 207 | */ |
||
| 208 | View Code Duplication | public function insertExistingField(Content $content, Field $field, StorageFieldValue $value) |
|
| 218 | |||
| 219 | /** |
||
| 220 | * Updates an existing field. |
||
| 221 | * |
||
| 222 | * @param Field $field |
||
| 223 | * @param StorageFieldValue $value |
||
| 224 | */ |
||
| 225 | View Code Duplication | public function updateField(Field $field, StorageFieldValue $value) |
|
| 235 | |||
| 236 | /** |
||
| 237 | * Updates an existing, non-translatable field. |
||
| 238 | * |
||
| 239 | * @param \eZ\Publish\SPI\Persistence\Content\Field $field |
||
| 240 | * @param \eZ\Publish\Core\Persistence\Legacy\Content\StorageFieldValue $value |
||
| 241 | * @param int $contentId |
||
| 242 | */ |
||
| 243 | View Code Duplication | public function updateNonTranslatableField( |
|
| 256 | |||
| 257 | /** |
||
| 258 | * Loads data for a content object. |
||
| 259 | * |
||
| 260 | * Returns an array with the relevant data. |
||
| 261 | * |
||
| 262 | * @param mixed $contentId |
||
| 263 | * @param mixed $version |
||
| 264 | * @param string[] $translations |
||
| 265 | * |
||
| 266 | * @return array |
||
| 267 | */ |
||
| 268 | View Code Duplication | public function load($contentId, $version, array $translations = null) |
|
| 278 | |||
| 279 | /** |
||
| 280 | * {@inheritdoc} |
||
| 281 | */ |
||
| 282 | View Code Duplication | public function loadContentList(array $contentIds, array $translations = null) |
|
| 283 | { |
||
| 284 | try { |
||
| 285 | return $this->innerGateway->loadContentList($contentIds, $translations); |
||
|
|
|||
| 286 | } catch (DBALException $e) { |
||
| 287 | throw new RuntimeException('Database error', 0, $e); |
||
| 288 | } catch (PDOException $e) { |
||
| 289 | throw new RuntimeException('Database error', 0, $e); |
||
| 290 | } |
||
| 291 | } |
||
| 292 | |||
| 293 | /** |
||
| 294 | * Loads data for a content object identified by its remote ID. |
||
| 295 | * |
||
| 296 | * Returns an array with the relevant data. |
||
| 297 | * |
||
| 298 | * @param mixed $remoteId |
||
| 299 | * |
||
| 300 | * @return array |
||
| 301 | */ |
||
| 302 | View Code Duplication | public function loadContentInfoByRemoteId($remoteId) |
|
| 312 | |||
| 313 | /** |
||
| 314 | * Loads info for a content object identified by its location ID (node ID). |
||
| 315 | * |
||
| 316 | * Returns an array with the relevant data. |
||
| 317 | * |
||
| 318 | * @param int $locationId |
||
| 319 | * |
||
| 320 | * @throws \eZ\Publish\Core\Base\Exceptions\NotFoundException |
||
| 321 | * |
||
| 322 | * @return array |
||
| 323 | */ |
||
| 324 | View Code Duplication | public function loadContentInfoByLocationId($locationId) |
|
| 334 | |||
| 335 | /** |
||
| 336 | * Loads info for content identified by $contentId. |
||
| 337 | * Will basically return a hash containing all field values for ezcontentobject table plus following keys: |
||
| 338 | * - always_available => Boolean indicating if content's language mask contains alwaysAvailable bit field |
||
| 339 | * - main_language_code => Language code for main (initial) language. E.g. "eng-GB". |
||
| 340 | * |
||
| 341 | * @param int $contentId |
||
| 342 | * |
||
| 343 | * @throws \eZ\Publish\Core\Base\Exceptions\NotFoundException |
||
| 344 | * |
||
| 345 | * @return array |
||
| 346 | */ |
||
| 347 | View Code Duplication | public function loadContentInfo($contentId) |
|
| 357 | |||
| 358 | View Code Duplication | public function loadContentInfoList(array $contentIds) |
|
| 368 | |||
| 369 | /** |
||
| 370 | * Loads version info for content identified by $contentId and $versionNo. |
||
| 371 | * Will basically return a hash containing all field values from ezcontentobject_version table plus following keys: |
||
| 372 | * - names => Hash of content object names. Key is the language code, value is the name. |
||
| 373 | * - languages => Hash of language ids. Key is the language code (e.g. "eng-GB"), value is the language numeric id without the always available bit. |
||
| 374 | * - initial_language_code => Language code for initial language in this version. |
||
| 375 | * |
||
| 376 | * @param int $contentId |
||
| 377 | * @param int $versionNo |
||
| 378 | * |
||
| 379 | * @return array |
||
| 380 | */ |
||
| 381 | View Code Duplication | public function loadVersionInfo($contentId, $versionNo) |
|
| 391 | |||
| 392 | /** |
||
| 393 | * Returns data for all versions with given status created by the given $userId. |
||
| 394 | * |
||
| 395 | * @param int $userId |
||
| 396 | * @param int $status |
||
| 397 | * |
||
| 398 | * @return string[][] |
||
| 399 | */ |
||
| 400 | View Code Duplication | public function listVersionsForUser($userId, $status = VersionInfo::STATUS_DRAFT) |
|
| 410 | |||
| 411 | /** |
||
| 412 | * Returns all version data for the given $contentId. |
||
| 413 | * |
||
| 414 | * Result is returned with oldest version first (using version id as it has index and is auto increment). |
||
| 415 | * |
||
| 416 | * @param mixed $contentId |
||
| 417 | * @param mixed|null $status Optional argument to filter versions by status, like {@see VersionInfo::STATUS_ARCHIVED}. |
||
| 418 | * @param int $limit Limit for items returned, -1 means none. |
||
| 419 | * |
||
| 420 | * @return string[][] |
||
| 421 | */ |
||
| 422 | View Code Duplication | public function listVersions($contentId, $status = null, $limit = -1) |
|
| 432 | |||
| 433 | /** |
||
| 434 | * Returns all version numbers for the given $contentId. |
||
| 435 | * |
||
| 436 | * @param mixed $contentId |
||
| 437 | * |
||
| 438 | * @return int[] |
||
| 439 | */ |
||
| 440 | View Code Duplication | public function listVersionNumbers($contentId) |
|
| 450 | |||
| 451 | /** |
||
| 452 | * Returns last version number for content identified by $contentId. |
||
| 453 | * |
||
| 454 | * @param int $contentId |
||
| 455 | * |
||
| 456 | * @return int |
||
| 457 | */ |
||
| 458 | View Code Duplication | public function getLastVersionNumber($contentId) |
|
| 468 | |||
| 469 | /** |
||
| 470 | * Returns all IDs for locations that refer to $contentId. |
||
| 471 | * |
||
| 472 | * @param int $contentId |
||
| 473 | * |
||
| 474 | * @return int[] |
||
| 475 | */ |
||
| 476 | View Code Duplication | public function getAllLocationIds($contentId) |
|
| 486 | |||
| 487 | /** |
||
| 488 | * Returns all field IDs of $contentId grouped by their type. |
||
| 489 | * If $versionNo is set only field IDs for that version are returned. |
||
| 490 | * If $languageCode is set, only field IDs for that language are returned. |
||
| 491 | * |
||
| 492 | * @param int $contentId |
||
| 493 | * @param int|null $versionNo |
||
| 494 | * @param string|null $languageCode |
||
| 495 | * |
||
| 496 | * @return int[][] |
||
| 497 | */ |
||
| 498 | View Code Duplication | public function getFieldIdsByType($contentId, $versionNo = null, $languageCode = null) |
|
| 508 | |||
| 509 | /** |
||
| 510 | * Deletes relations to and from $contentId. |
||
| 511 | * If $versionNo is set only relations for that version are deleted. |
||
| 512 | * |
||
| 513 | * @param int $contentId |
||
| 514 | * @param int|null $versionNo |
||
| 515 | */ |
||
| 516 | View Code Duplication | public function deleteRelations($contentId, $versionNo = null) |
|
| 526 | |||
| 527 | /** |
||
| 528 | * Removes relations to Content with $contentId from Relation and RelationList field type fields. |
||
| 529 | * |
||
| 530 | * @param int $contentId |
||
| 531 | */ |
||
| 532 | View Code Duplication | public function removeReverseFieldRelations($contentId) |
|
| 542 | |||
| 543 | /** |
||
| 544 | * Deletes the field with the given $fieldId. |
||
| 545 | * |
||
| 546 | * @param int $fieldId |
||
| 547 | */ |
||
| 548 | View Code Duplication | public function deleteField($fieldId) |
|
| 558 | |||
| 559 | /** |
||
| 560 | * Deletes all fields of $contentId in all versions. |
||
| 561 | * If $versionNo is set only fields for that version are deleted. |
||
| 562 | * |
||
| 563 | * @param int $contentId |
||
| 564 | * @param int|null $versionNo |
||
| 565 | */ |
||
| 566 | View Code Duplication | public function deleteFields($contentId, $versionNo = null) |
|
| 576 | |||
| 577 | /** |
||
| 578 | * Deletes all versions of $contentId. |
||
| 579 | * If $versionNo is set only that version is deleted. |
||
| 580 | * |
||
| 581 | * @param int $contentId |
||
| 582 | * @param int|null $versionNo |
||
| 583 | */ |
||
| 584 | View Code Duplication | public function deleteVersions($contentId, $versionNo = null) |
|
| 594 | |||
| 595 | /** |
||
| 596 | * Deletes all names of $contentId. |
||
| 597 | * If $versionNo is set only names for that version are deleted. |
||
| 598 | * |
||
| 599 | * @param int $contentId |
||
| 600 | * @param int|null $versionNo |
||
| 601 | */ |
||
| 602 | View Code Duplication | public function deleteNames($contentId, $versionNo = null) |
|
| 612 | |||
| 613 | /** |
||
| 614 | * Sets the content object name. |
||
| 615 | * |
||
| 616 | * @param int $contentId |
||
| 617 | * @param int $version |
||
| 618 | * @param string $name |
||
| 619 | * @param string $language |
||
| 620 | */ |
||
| 621 | View Code Duplication | public function setName($contentId, $version, $name, $language) |
|
| 631 | |||
| 632 | /** |
||
| 633 | * Deletes the actual content object referred to by $contentId. |
||
| 634 | * |
||
| 635 | * @param int $contentId |
||
| 636 | */ |
||
| 637 | View Code Duplication | public function deleteContent($contentId) |
|
| 647 | |||
| 648 | /** |
||
| 649 | * Loads data of related to/from $contentId. |
||
| 650 | * |
||
| 651 | * @param int $contentId |
||
| 652 | * @param int $contentVersionNo |
||
| 653 | * @param int $relationType |
||
| 654 | * |
||
| 655 | * @return mixed[][] Content data, array structured like {@see \eZ\Publish\Core\Persistence\Legacy\Content\Gateway::load()} |
||
| 656 | */ |
||
| 657 | View Code Duplication | public function loadRelations($contentId, $contentVersionNo = null, $relationType = null) |
|
| 667 | |||
| 668 | /** |
||
| 669 | * Loads data of related to/from $contentId. |
||
| 670 | * |
||
| 671 | * @param int $contentId |
||
| 672 | * @param bool $reverse Reverse relation, default false |
||
| 673 | * @param int $contentVersionNo |
||
| 674 | * @param int $relationType |
||
| 675 | * |
||
| 676 | * @return mixed[][] Content data, array structured like {@see \eZ\Publish\Core\Persistence\Legacy\Content\Gateway::load()} |
||
| 677 | */ |
||
| 678 | View Code Duplication | public function loadReverseRelations($contentId, $relationType = null) |
|
| 688 | |||
| 689 | /** |
||
| 690 | * Deletes the relation with the given $relationId. |
||
| 691 | * |
||
| 692 | * @param int $relationId |
||
| 693 | * @param int $type {@see \eZ\Publish\API\Repository\Values\Content\Relation::COMMON, |
||
| 694 | * \eZ\Publish\API\Repository\Values\Content\Relation::EMBED, |
||
| 695 | * \eZ\Publish\API\Repository\Values\Content\Relation::LINK, |
||
| 696 | * \eZ\Publish\API\Repository\Values\Content\Relation::FIELD} |
||
| 697 | */ |
||
| 698 | View Code Duplication | public function deleteRelation($relationId, $type) |
|
| 708 | |||
| 709 | /** |
||
| 710 | * Inserts a new relation database record. |
||
| 711 | * |
||
| 712 | * @param \eZ\Publish\SPI\Persistence\Content\Relation\CreateStruct $createStruct |
||
| 713 | * |
||
| 714 | * @return int ID the inserted ID |
||
| 715 | */ |
||
| 716 | View Code Duplication | public function insertRelation(RelationCreateStruct $struct) |
|
| 726 | |||
| 727 | /** |
||
| 728 | * Returns all Content IDs for a given $contentTypeId. |
||
| 729 | * |
||
| 730 | * @param int $contentTypeId |
||
| 731 | * |
||
| 732 | * @return int[] |
||
| 733 | */ |
||
| 734 | View Code Duplication | public function getContentIdsByContentTypeId($contentTypeId) |
|
| 744 | |||
| 745 | /** |
||
| 746 | * Load name data for set of content id's and corresponding version number. |
||
| 747 | * |
||
| 748 | * @param array[] $rows array of hashes with 'id' and 'version' to load names for |
||
| 749 | * |
||
| 750 | * @return array |
||
| 751 | */ |
||
| 752 | View Code Duplication | public function loadVersionedNameData($rows) |
|
| 762 | |||
| 763 | /** |
||
| 764 | * Batch method for copying all relation meta data for copied Content object. |
||
| 765 | * |
||
| 766 | * {@inheritdoc} |
||
| 767 | * |
||
| 768 | * @param int $originalContentId |
||
| 769 | * @param int $copiedContentId |
||
| 770 | * @param int|null $versionNo If specified only copy for a given version number, otherwise all. |
||
| 771 | */ |
||
| 772 | View Code Duplication | public function copyRelations($originalContentId, $copiedContentId, $versionNo = null) |
|
| 782 | |||
| 783 | /** |
||
| 784 | * Remove the specified translation from all the Versions of a Content Object. |
||
| 785 | * |
||
| 786 | * @param int $contentId |
||
| 787 | * @param string $languageCode language code of the translation |
||
| 788 | */ |
||
| 789 | View Code Duplication | public function deleteTranslationFromContent($contentId, $languageCode) |
|
| 799 | |||
| 800 | /** |
||
| 801 | * Delete Content fields (attributes) for the given Translation. |
||
| 802 | * If $versionNo is given, fields for that Version only will be deleted. |
||
| 803 | * |
||
| 804 | * @param string $languageCode |
||
| 805 | * @param int $contentId |
||
| 806 | * @param int $versionNo (optional) filter by versionNo |
||
| 807 | */ |
||
| 808 | View Code Duplication | public function deleteTranslatedFields($languageCode, $contentId, $versionNo = null) |
|
| 818 | |||
| 819 | /** |
||
| 820 | * Delete the specified Translation from the given Version. |
||
| 821 | * |
||
| 822 | * @param int $contentId |
||
| 823 | * @param int $versionNo |
||
| 824 | * @param string $languageCode |
||
| 825 | */ |
||
| 826 | View Code Duplication | public function deleteTranslationFromVersion($contentId, $versionNo, $languageCode) |
|
| 836 | } |
||
| 837 |
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.