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 AbstractBrowserBindingService 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 AbstractBrowserBindingService, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
49 | abstract class AbstractBrowserBindingService implements LinkAccessInterface |
||
50 | { |
||
51 | /** |
||
52 | * @var BindingSessionInterface |
||
53 | */ |
||
54 | protected $session; |
||
55 | |||
56 | /** |
||
57 | * @var boolean |
||
58 | */ |
||
59 | protected $succinct; |
||
60 | |||
61 | /** |
||
62 | * @var CmisBindingsHelper |
||
63 | */ |
||
64 | protected $cmisBindingsHelper; |
||
65 | |||
66 | /** |
||
67 | * @var DateTimeFormat |
||
68 | */ |
||
69 | 168 | protected $dateTimeFormat; |
|
70 | |||
71 | 168 | /** |
|
72 | 168 | * @param BindingSessionInterface $session |
|
73 | 168 | * @param CmisBindingsHelper|null $cmisBindingsHelper |
|
74 | */ |
||
75 | public function __construct(BindingSessionInterface $session, $cmisBindingsHelper = null) |
||
80 | |||
81 | 168 | /** |
|
82 | * Set cmis binding helper property |
||
83 | 168 | * |
|
84 | 168 | * @param CmisBindingsHelper|null $cmisBindingsHelper The cmis binding helper that should be defined. |
|
85 | * If <code>null</code> is given a new instance of CmisBindingsHelper will be created. |
||
86 | */ |
||
87 | protected function setCmisBindingsHelper($cmisBindingsHelper = null) |
||
91 | |||
92 | /** |
||
93 | * Get the url for an object |
||
94 | * |
||
95 | * @param string $repositoryId |
||
96 | 2 | * @param string $objectId |
|
97 | * @param string|null $selector |
||
98 | 2 | * @throws CmisConnectionException |
|
99 | * @throws CmisObjectNotFoundException |
||
100 | 2 | * @return Url |
|
101 | 1 | */ |
|
102 | 1 | View Code Duplication | protected function getObjectUrl($repositoryId, $objectId, $selector = null) |
124 | |||
125 | 2 | /** |
|
126 | * Returns the repository URL cache or creates a new cache if it doesn't |
||
127 | 2 | * exist. |
|
128 | 2 | * |
|
129 | 1 | * @return RepositoryUrlCache |
|
130 | 1 | */ |
|
131 | 1 | protected function getRepositoryUrlCache() |
|
141 | 66 | ||
142 | /** |
||
143 | 66 | * Get current session |
|
144 | * |
||
145 | * @return BindingSessionInterface |
||
146 | */ |
||
147 | public function getSession() |
||
151 | 168 | ||
152 | /** |
||
153 | 168 | * Sets the current session. |
|
154 | 168 | * |
|
155 | 168 | * @param BindingSessionInterface $session |
|
156 | */ |
||
157 | 168 | protected function setSession(BindingSessionInterface $session) |
|
165 | |||
166 | /** |
||
167 | 8 | * Retrieves the the repository info objects. |
|
168 | * |
||
169 | 8 | * @param string|null $repositoryId |
|
170 | * @throws CmisConnectionException |
||
171 | 8 | * @return RepositoryInfo[] Returns ALL Repository Infos that are available and not just the one requested by id. |
|
172 | */ |
||
173 | 6 | protected function getRepositoriesInternal($repositoryId = null) |
|
228 | |||
229 | /** |
||
230 | * Returns the service URL of this session. |
||
231 | * |
||
232 | * @return string|null |
||
233 | */ |
||
234 | 2 | protected function getServiceUrl() |
|
238 | 1 | ||
239 | /** |
||
240 | * Wrapper to read URL response as JSON as is the general use case. |
||
241 | 1 | * |
|
242 | * @param Url $url |
||
243 | * @return mixed |
||
244 | */ |
||
245 | protected function readJson(Url $url) |
||
249 | |||
250 | /** |
||
251 | * Do a get request for the given url |
||
252 | 3 | * |
|
253 | * @param Url $url |
||
254 | * @return Response |
||
255 | * @throws CmisBaseException an more specific exception of this type could be thrown. For more details see |
||
256 | 3 | * @see AbstractBrowserBindingService::convertStatusCode() |
|
257 | 3 | */ |
|
258 | 2 | protected function read(Url $url) |
|
279 | 4 | ||
280 | /** |
||
281 | * Get a HTTP Invoker instance |
||
282 | 4 | * |
|
283 | * @return Client |
||
284 | 4 | */ |
|
285 | protected function getHttpInvoker() |
||
289 | |||
290 | /** |
||
291 | * Converts an error message or a HTTP status code into an Exception. |
||
292 | * |
||
293 | * @see http://docs.oasis-open.org/cmis/CMIS/v1.1/os/CMIS-v1.1-os.html#x1-551021r549 |
||
294 | * |
||
295 | * @param integer $code |
||
296 | * @param string $message |
||
297 | 26 | * @param null|\Exception $exception |
|
298 | * @return CmisBaseException |
||
299 | 26 | */ |
|
300 | protected function convertStatusCode($code, $message, \Exception $exception = null) |
||
353 | |||
354 | // ---- helpers ---- |
||
355 | |||
356 | /** |
||
357 | * Returns JSON Converter instance |
||
358 | 65 | * |
|
359 | * @return \Dkd\PhpCmis\Converter\JsonConverter |
||
360 | 65 | */ |
|
361 | protected function getJsonConverter() |
||
365 | |||
366 | /** |
||
367 | * Generate url for a given path of a given repository. |
||
368 | * |
||
369 | * @param string $repositoryId |
||
370 | * @param string $path |
||
371 | * @param string|null $selector |
||
372 | * @throws CmisConnectionException |
||
373 | 2 | * @throws CmisObjectNotFoundException |
|
374 | * @return Url |
||
375 | 2 | */ |
|
376 | View Code Duplication | protected function getPathUrl($repositoryId, $path, $selector = null) |
|
398 | |||
399 | // ---- URL ---- |
||
400 | |||
401 | /** |
||
402 | * Get if succinct mode is used |
||
403 | 46 | * |
|
404 | * @return boolean |
||
405 | 46 | */ |
|
406 | protected function getSuccinct() |
||
410 | |||
411 | /** |
||
412 | * Wrapper for calling post() and reading response as JSON, as is the general use case. |
||
413 | * |
||
414 | * @param Url $url |
||
415 | * @param array $content |
||
416 | * @param array $headers |
||
417 | * @return mixed |
||
418 | */ |
||
419 | 2 | protected function postJson(Url $url, $content = [], array $headers = []) |
|
423 | |||
424 | /** |
||
425 | 2 | * Performs a POST on an URL, checks the response code and returns the |
|
426 | 2 | * result. |
|
427 | 1 | * |
|
428 | 1 | * @param Url $url Request url |
|
429 | 1 | * @param resource|string|StreamInterface|array $content Entity body data or an array for POST fields and files |
|
430 | * @param array $headers Additional header options |
||
431 | 1 | * @return ResponseInterface |
|
432 | * @throws CmisBaseException an more specific exception of this type could be thrown. For more details see |
||
433 | * @see AbstractBrowserBindingService::convertStatusCode() |
||
434 | 1 | */ |
|
435 | protected function post(Url $url, $content = [], array $headers = []) |
||
453 | |||
454 | /** |
||
455 | * @param array $queryArray |
||
456 | 1 | * @param null $prefix |
|
457 | 1 | * @return array |
|
458 | */ |
||
459 | 1 | protected function convertQueryArrayToMultiPart(array $queryArray, $prefix = null) |
|
486 | 1 | ||
487 | 1 | /** |
|
488 | 1 | * Retrieves a type definition. |
|
489 | 1 | * |
|
490 | * @param string $repositoryId |
||
491 | 1 | * @param string $typeId |
|
492 | 1 | * @return TypeDefinitionInterface|null |
|
493 | * @throws CmisInvalidArgumentException if repository id or type id is <code>null</code> |
||
494 | */ |
||
495 | 1 | protected function getTypeDefinitionInternal($repositoryId, $typeId) |
|
513 | 13 | ||
514 | 13 | /** |
|
515 | * Get url for a repository |
||
516 | 13 | * |
|
517 | * @param string $repositoryId |
||
518 | 13 | * @param string|null $selector |
|
519 | 13 | * @throws CmisConnectionException |
|
520 | 13 | * @throws CmisObjectNotFoundException |
|
521 | 13 | * @return Url |
|
522 | 13 | */ |
|
523 | 13 | View Code Duplication | protected function getRepositoryUrl($repositoryId, $selector = null) |
544 | |||
545 | /** |
||
546 | * Converts a Properties list into an array that can be used for the CMIS request. |
||
547 | 13 | * |
|
548 | * @param PropertiesInterface $properties |
||
549 | 13 | * @return array Example <code> |
|
550 | * array('propertyId' => array(0 => 'myId'), 'propertyValue' => array(0 => 'valueOfMyId')) |
||
551 | 1 | * </code> |
|
552 | 13 | */ |
|
553 | protected function convertPropertiesToQueryArray(PropertiesInterface $properties) |
||
587 | 7 | ||
588 | 7 | /** |
|
589 | * Converts values to a format that can be used for the CMIS Browser binding request. |
||
590 | 7 | * |
|
591 | 7 | * @param mixed $value |
|
592 | 7 | * @return mixed |
|
593 | */ |
||
594 | 7 | protected function convertPropertyValueToSimpleType($value) |
|
606 | 10 | ||
607 | /** |
||
608 | 10 | * Converts a Access Control list into an array that can be used for the CMIS request |
|
609 | 6 | * |
|
610 | 6 | * @param AclInterface $acl |
|
611 | 10 | * @param string $principalControl one of principal ace constants |
|
612 | * CONTROL_ADD_ACE_PRINCIPAL or CONTROL_REMOVE_ACE_PRINCIPAL |
||
613 | 10 | * @param string $permissionControl one of permission ace constants |
|
614 | * CONTROL_REMOVE_ACE_PRINCIPAL or CONTROL_REMOVE_ACE_PERMISSION |
||
615 | * @return array Example <code> |
||
616 | * array('addACEPrincipal' => array(0 => 'principalId'), |
||
617 | * 'addACEPermission' => array(0 => array(0 => 'permissonValue'))) |
||
618 | * </code> |
||
619 | */ |
||
620 | protected function convertAclToQueryArray(AclInterface $acl, $principalControl, $permissionControl) |
||
643 | |||
644 | /** |
||
645 | * Converts a policies array into an array that can be used for the CMIS request |
||
646 | * |
||
647 | * @param string[] $policies A list of policy string representations |
||
648 | * @return array |
||
649 | */ |
||
650 | protected function convertPolicyIdArrayToQueryArray(array $policies) |
||
662 | |||
663 | /** |
||
664 | * Returns the date time format |
||
665 | * |
||
666 | * @return DateTimeFormat |
||
667 | */ |
||
668 | public function getDateTimeFormat() |
||
672 | |||
673 | /** |
||
674 | * Sets the date time format |
||
675 | * |
||
676 | * @param DateTimeFormat $dateTimeFormat |
||
677 | */ |
||
678 | public function setDateTimeFormat(DateTimeFormat $dateTimeFormat) |
||
682 | |||
683 | /** |
||
684 | * Appends policies parameters to url |
||
685 | * |
||
686 | * @param Url $url |
||
687 | * @param string[] $policies A list of policy IDs that must be applied to the newly created document object |
||
688 | */ |
||
689 | protected function appendPoliciesToUrl(Url $url, array $policies) |
||
695 | |||
696 | /** |
||
697 | * Appends addAces parameters to url |
||
698 | * |
||
699 | * @param Url $url |
||
700 | * @param AclInterface|null $addAces A list of ACEs |
||
701 | */ |
||
702 | View Code Duplication | protected function appendAddAcesToUrl(Url $url, AclInterface $addAces = null) |
|
714 | |||
715 | /** |
||
716 | * Appends removeAces parameters to url |
||
717 | * |
||
718 | * @param Url $url |
||
719 | * @param AclInterface|null $removeAces A list of ACEs |
||
720 | */ |
||
721 | View Code Duplication | protected function appendRemoveAcesToUrl(Url $url, AclInterface $removeAces = null) |
|
733 | |||
734 | /** |
||
735 | * Gets the content link from the cache if it is there or loads it into the |
||
736 | * cache if it is not there. |
||
737 | * |
||
738 | * @param string $repositoryId |
||
739 | * @param string $documentId |
||
740 | * @return string|null |
||
741 | */ |
||
742 | public function loadContentLink($repositoryId, $documentId) |
||
747 | |||
748 | /** |
||
749 | * Gets a rendition content link from the cache if it is there or loads it |
||
750 | * into the cache if it is not there. |
||
751 | * |
||
752 | * @param string $repositoryId |
||
753 | * @param string $documentId |
||
754 | * @param string $streamId |
||
755 | * @return string|null |
||
756 | */ |
||
757 | public function loadRenditionContentLink($repositoryId, $documentId, $streamId) |
||
766 | } |
||
767 |
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.