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 Document 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 Document, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 34 | class Document extends AbstractFileableCmisObject implements DocumentInterface |
||
| 35 | { |
||
| 36 | /** |
||
| 37 | * Appends a content stream to the content stream of the document and refreshes this object afterwards. |
||
| 38 | * If the repository created a new version, this new document is returned. |
||
| 39 | * Otherwise the current document is returned. |
||
| 40 | * The stream in contentStream is consumed but not closed by this method. |
||
| 41 | * |
||
| 42 | * @param StreamInterface $contentStream the content stream |
||
| 43 | * @param boolean $isLastChunk indicates if this stream is the last chunk of the content |
||
| 44 | * @param boolean $refresh if this parameter is set to <code>true</code>, this object will be refreshed after the |
||
| 45 | * content stream has been appended |
||
| 46 | * @return ObjectIdInterface|null the updated object ID, or <code>null</code> if the repository did not return |
||
| 47 | * an object ID |
||
| 48 | * @throws CmisNotSupportedException |
||
| 49 | */ |
||
| 50 | public function appendContentStream(StreamInterface $contentStream, $isLastChunk, $refresh = true) |
||
| 77 | |||
| 78 | /** |
||
| 79 | * If this is a PWC (private working copy) the check out will be reversed. |
||
| 80 | */ |
||
| 81 | public function cancelCheckOut() |
||
| 87 | |||
| 88 | /** |
||
| 89 | * If this is a PWC (private working copy) it performs a check in. |
||
| 90 | * If this is not a PWC an exception will be thrown. |
||
| 91 | * The stream in contentStream is consumed but not closed by this method. |
||
| 92 | * |
||
| 93 | * @param boolean $major <code>true</code> if the checked-in document object MUST be a major version. |
||
| 94 | * <code>false</code> if the checked-in document object MUST NOT be a major version but a minor version. |
||
| 95 | * @param array $properties The property values that MUST be applied to the checked-in document object. |
||
| 96 | * @param StreamInterface $contentStream The content stream that MUST be stored for the checked-in document object. |
||
| 97 | * The method of passing the contentStream to the server and the encoding mechanism will be specified by each |
||
| 98 | * specific binding. MUST be required if the type requires it. |
||
| 99 | * @param string $checkinComment Textual comment associated with the given version. MAY be "not set". |
||
| 100 | * @param PolicyInterface[] $policies A list of policy ids that MUST be applied to the newly-created document |
||
| 101 | * object |
||
| 102 | * @param AceInterface[] $addAces A list of ACEs that MUST be added to the newly-created document object. |
||
| 103 | * @param AceInterface[] $removeAces A list of ACEs that MUST be removed from the newly-created document object. |
||
| 104 | * @return ObjectIdInterface|null The id of the checked-in document. <code>null</code> if repository has not |
||
| 105 | * returned the new object id which could happen in case of a repository error |
||
| 106 | */ |
||
| 107 | public function checkIn( |
||
| 150 | |||
| 151 | /** |
||
| 152 | * Checks out the document and returns the object ID of the PWC (private working copy). |
||
| 153 | * |
||
| 154 | * @return ObjectIdInterface|null PWC object ID |
||
| 155 | */ |
||
| 156 | public function checkOut() |
||
| 168 | |||
| 169 | /** |
||
| 170 | * Creates a copy of this document, including content. |
||
| 171 | * |
||
| 172 | * @param ObjectIdInterface|null $targetFolderId the ID of the target folder, <code>null</code> to create an unfiled |
||
| 173 | * document |
||
| 174 | * @param array $properties The property values that MUST be applied to the object. This list of properties SHOULD |
||
| 175 | * only contain properties whose values differ from the source document. The array key is the property name |
||
| 176 | * the value is the property value. |
||
| 177 | * @param VersioningState|null $versioningState An enumeration specifying what the versioning state of the |
||
| 178 | * newly-created object MUST be. Valid values are: |
||
| 179 | * <code>none</code> |
||
| 180 | * (default, if the object-type is not versionable) The document MUST be created as a non-versionable |
||
| 181 | * document. |
||
| 182 | * <code>checkedout</code> |
||
| 183 | * The document MUST be created in the checked-out state. The checked-out document MAY be |
||
| 184 | * visible to other users. |
||
| 185 | * <code>major</code> |
||
| 186 | * (default, if the object-type is versionable) The document MUST be created as a major version. |
||
| 187 | * <code>minor</code> |
||
| 188 | * The document MUST be created as a minor version. |
||
| 189 | * @param PolicyInterface[] $policies A list of policy ids that MUST be applied to the newly-created document |
||
| 190 | * object. |
||
| 191 | * @param AceInterface[] $addAces A list of ACEs that MUST be added to the newly-created document object, either |
||
| 192 | * using the ACL from folderId if specified, or being applied if no folderId is specified. |
||
| 193 | * @param AceInterface[] $removeAces A list of ACEs that MUST be removed from the newly-created document object, |
||
| 194 | * either using the ACL from folderId if specified, or being ignored if no folderId is specified. |
||
| 195 | * @param OperationContextInterface|null $context |
||
| 196 | * @return DocumentInterface the new document object or <code>null</code> if the parameter <code>context</code> was |
||
| 197 | * set to <code>null</code> |
||
| 198 | * @throws CmisRuntimeException Exception is thrown if the created object is not a document |
||
| 199 | */ |
||
| 200 | public function copy( |
||
| 240 | |||
| 241 | /** |
||
| 242 | * Copies the document manually. The content is streamed from the repository and back. |
||
| 243 | * |
||
| 244 | * @param ObjectIdInterface|null $targetFolderId the ID of the target folder, <code>null</code> to create an unfiled |
||
| 245 | * document |
||
| 246 | * @param array $properties The property values that MUST be applied to the object. This list of properties SHOULD |
||
| 247 | * only contain properties whose values differ from the source document. The array key is the property name |
||
| 248 | * the value is the property value. |
||
| 249 | * @param VersioningState|null $versioningState An enumeration specifying what the versioning state of the |
||
| 250 | * newly-created object MUST be. Valid values are: |
||
| 251 | * <code>none</code> |
||
| 252 | * (default, if the object-type is not versionable) The document MUST be created as a non-versionable |
||
| 253 | * document. |
||
| 254 | * <code>checkedout</code> |
||
| 255 | * The document MUST be created in the checked-out state. The checked-out document MAY be |
||
| 256 | * visible to other users. |
||
| 257 | * <code>major</code> |
||
| 258 | * (default, if the object-type is versionable) The document MUST be created as a major version. |
||
| 259 | * <code>minor</code> |
||
| 260 | * The document MUST be created as a minor version. |
||
| 261 | * @param PolicyInterface[] $policies A list of policy ids that MUST be applied to the newly-created document |
||
| 262 | * object. |
||
| 263 | * @param AceInterface[] $addAces A list of ACEs that MUST be added to the newly-created document object, either |
||
| 264 | * using the ACL from folderId if specified, or being applied if no folderId is specified. |
||
| 265 | * @param AceInterface[] $removeAces A list of ACEs that MUST be removed from the newly-created document object, |
||
| 266 | * either using the ACL from folderId if specified, or being ignored if no folderId is specified. |
||
| 267 | * @return ObjectIdInterface The id of the newly-created document. |
||
| 268 | * @throws CmisRuntimeException |
||
| 269 | */ |
||
| 270 | protected function copyViaClient( |
||
| 316 | |||
| 317 | /** |
||
| 318 | * Deletes this document and all its versions. |
||
| 319 | */ |
||
| 320 | public function deleteAllVersions() |
||
| 324 | |||
| 325 | /** |
||
| 326 | * Removes the current content stream from the document and refreshes this object afterwards. |
||
| 327 | * |
||
| 328 | * @param boolean $refresh if this parameter is set to <code>true</code>, this object will be refreshed after the |
||
| 329 | * content stream has been deleted |
||
| 330 | * @return DocumentInterface|null the updated document, or <code>null</code> if the repository did not return |
||
| 331 | * an object ID |
||
| 332 | */ |
||
| 333 | View Code Duplication | public function deleteContentStream($refresh = true) |
|
| 357 | |||
| 358 | /** |
||
| 359 | * Fetches all versions of this document using the given OperationContext. |
||
| 360 | * The behavior of this method is undefined if the document is not versionable |
||
| 361 | * and can be different for each repository. |
||
| 362 | * |
||
| 363 | * @param OperationContextInterface|null $context |
||
| 364 | * @return DocumentInterface[] |
||
| 365 | */ |
||
| 366 | public function getAllVersions(OperationContextInterface $context = null) |
||
| 397 | |||
| 398 | /** |
||
| 399 | * Returns the content URL of the document or a rendition if the binding |
||
| 400 | * supports content URLs. |
||
| 401 | * |
||
| 402 | * Depending on the repository and the binding, the server might not return |
||
| 403 | * the content but an error message. Authentication data is not attached. |
||
| 404 | * That is, a user may have to re-authenticate to get the content. |
||
| 405 | * |
||
| 406 | * @param string|null $streamId the ID of the rendition or <code>null</code> for the document |
||
| 407 | * |
||
| 408 | * @return string|null the content URL of the document or rendition or <code>null</code> if |
||
| 409 | * the binding does not support content URLs |
||
| 410 | */ |
||
| 411 | public function getContentUrl($streamId = null) |
||
| 424 | |||
| 425 | /** |
||
| 426 | * Retrieves the content stream that is associated with the given stream ID. |
||
| 427 | * This is usually a rendition of the document. |
||
| 428 | * |
||
| 429 | * @param string|null $streamId the stream ID |
||
| 430 | * @param integer|null $offset the offset of the stream or <code>null</code> to read the stream from the beginning |
||
| 431 | * @param integer|null $length the maximum length of the stream or <code>null</code> to read to the end of the |
||
| 432 | * stream |
||
| 433 | * @return StreamInterface|null the content stream, or <code>null</code> if no content is associated with this |
||
| 434 | * stream ID |
||
| 435 | */ |
||
| 436 | public function getContentStream($streamId = null, $offset = null, $length = null) |
||
| 440 | |||
| 441 | /** |
||
| 442 | * Fetches the latest major or minor version of this document using the given OperationContext. |
||
| 443 | * |
||
| 444 | * @param boolean $major if <code>true</code> the latest major version will be returned, |
||
| 445 | * otherwise the very last version will be returned |
||
| 446 | * @param OperationContextInterface|null $context |
||
| 447 | * @return DocumentInterface the latest document object |
||
| 448 | */ |
||
| 449 | public function getObjectOfLatestVersion($major, OperationContextInterface $context = null) |
||
| 455 | |||
| 456 | /** |
||
| 457 | * Sets a new content stream for the document. If the repository created a new version, |
||
| 458 | * the object ID of this new version is returned. Otherwise the object ID of the current document is returned. |
||
| 459 | * The stream in contentStream is consumed but not closed by this method. |
||
| 460 | * |
||
| 461 | * @param StreamInterface $contentStream the content stream |
||
| 462 | * @param boolean $overwrite if this parameter is set to <code>false</code> and the document already has content, |
||
| 463 | * the repository throws a CmisContentAlreadyExistsException |
||
| 464 | * @param boolean $refresh if this parameter is set to <code>true</code>, this object will be refreshed |
||
| 465 | * after the new content has been set |
||
| 466 | * @return ObjectIdInterface|null the updated object ID, or <code>null</code> if the repository did not return |
||
| 467 | * an object ID |
||
| 468 | */ |
||
| 469 | View Code Duplication | public function setContentStream(StreamInterface $contentStream, $overwrite, $refresh = true) |
|
| 492 | |||
| 493 | /** |
||
| 494 | * Returns the checkin comment (CMIS property cmis:checkinComment). |
||
| 495 | * |
||
| 496 | * @return string|null the checkin comment of this version or <code>null</code> if the property hasn't |
||
| 497 | * been requested, hasn't been provided by the repository, or the property value isn't set |
||
| 498 | */ |
||
| 499 | public function getCheckinComment() |
||
| 503 | |||
| 504 | /** |
||
| 505 | * Returns the content stream filename or <code>null</code> if the document has no content |
||
| 506 | * (CMIS property cmis:contentStreamFileName). |
||
| 507 | * |
||
| 508 | * @return string|null the content stream filename of this document or <code>null</code> if the property hasn't |
||
| 509 | * been requested, hasn't been provided by the repository, or the document has no content |
||
| 510 | */ |
||
| 511 | public function getContentStreamFileName() |
||
| 515 | |||
| 516 | /** |
||
| 517 | * Returns the content hashes or <code>null</code> if the document has no content |
||
| 518 | * (CMIS property cmis:contentStreamHash). |
||
| 519 | * |
||
| 520 | * @return ContentStreamHashInterface[]|null the list of content hashes or <code>null</code> if the property |
||
| 521 | * hasn't been requested, hasn't been provided by the repository, or the document has no content |
||
| 522 | */ |
||
| 523 | public function getContentStreamHashes() |
||
| 529 | |||
| 530 | /** |
||
| 531 | * Returns the content stream ID or <code>null</code> if the document has no content |
||
| 532 | * (CMIS property cmis:contentStreamId). |
||
| 533 | * |
||
| 534 | * @return string|null the content stream ID of this document or <code>null</code> if the property hasn't |
||
| 535 | * been requested, hasn't been provided by the repository, or the document has no content |
||
| 536 | */ |
||
| 537 | public function getContentStreamId() |
||
| 541 | |||
| 542 | /** |
||
| 543 | * Returns the content stream length or <code>null</code> if the document has no content (CMIS property |
||
| 544 | * cmis:contentStreamLength). |
||
| 545 | * |
||
| 546 | * @return integer the content stream length of this document or <code>null</code> if the property hasn't been |
||
| 547 | * requested, hasn't been provided by the repository, or the document has no content |
||
| 548 | */ |
||
| 549 | public function getContentStreamLength() |
||
| 553 | |||
| 554 | /** |
||
| 555 | * Returns the content stream MIME type or <code>null</code> if the document has no content |
||
| 556 | * (CMIS property cmis:contentStreamMimeType). |
||
| 557 | * |
||
| 558 | * @return string|null the content stream MIME type of this document or <code>null</code> if the property hasn't |
||
| 559 | * been requested, hasn't been provided by the repository, or the document has no content |
||
| 560 | */ |
||
| 561 | public function getContentStreamMimeType() |
||
| 565 | |||
| 566 | /** |
||
| 567 | * Returns the version label (CMIS property cmis:versionLabel). |
||
| 568 | * |
||
| 569 | * @return string|null the version label of the document or <code>null</code> if the property hasn't been requested, |
||
| 570 | * hasn't been provided by the repository, or the property value isn't set |
||
| 571 | */ |
||
| 572 | public function getVersionLabel() |
||
| 576 | |||
| 577 | /** |
||
| 578 | * Returns the user who checked out this version series (CMIS property cmis:versionSeriesCheckedOutBy). |
||
| 579 | * |
||
| 580 | * @return string|null the user who checked out this version series or <code>null</code> if the property hasn't |
||
| 581 | * been requested, hasn't been provided by the repository, or the property value isn't set |
||
| 582 | */ |
||
| 583 | public function getVersionSeriesCheckedOutBy() |
||
| 587 | |||
| 588 | /** |
||
| 589 | * Returns the PWC ID of this version series (CMIS property cmis:versionSeriesCheckedOutId). |
||
| 590 | * Some repositories provided this value only to the user who checked out the version series. |
||
| 591 | * |
||
| 592 | * @return string|null the PWC ID of this version series or <code>null</code> if the property hasn't been requested, |
||
| 593 | * hasn't been provided by the repository, or the property value isn't set |
||
| 594 | */ |
||
| 595 | public function getVersionSeriesCheckedOutId() |
||
| 599 | |||
| 600 | /** |
||
| 601 | * Returns the version series ID (CMIS property cmis:versionSeriesId). |
||
| 602 | * |
||
| 603 | * @return string|null the version series ID of the document or <code>null</code> if the property hasn't |
||
| 604 | * been requested, hasn't been provided by the repository, or the property value isn't set |
||
| 605 | */ |
||
| 606 | public function getVersionSeriesId() |
||
| 610 | |||
| 611 | /** |
||
| 612 | * Returns <code>true</code> if this document is immutable (CMIS property cmis:isImmutable). |
||
| 613 | * |
||
| 614 | * @return boolean|null the immutable flag of the document or <code>null</code> if the property hasn't |
||
| 615 | * been requested, hasn't been provided by the repository, or the property value isn't set |
||
| 616 | */ |
||
| 617 | public function isImmutable() |
||
| 621 | |||
| 622 | /** |
||
| 623 | * Returns <code>true</code> if this document is the latest version (CMIS property cmis:isLatestVersion). |
||
| 624 | * |
||
| 625 | * @return boolean|null the latest version flag of the document or <code>null</code> if the property hasn't |
||
| 626 | * been requested, hasn't been provided by the repository, or the property value isn't set |
||
| 627 | */ |
||
| 628 | public function isLatestMajorVersion() |
||
| 632 | |||
| 633 | /** |
||
| 634 | * Returns <code>true</code> if this document is the latest version (CMIS property cmis:isLatestVersion). |
||
| 635 | * |
||
| 636 | * @return boolean|null the latest version flag of the document or <code>null</code> if the property hasn't |
||
| 637 | * been requested, hasn't been provided by the repository, or the property value isn't set |
||
| 638 | */ |
||
| 639 | public function isLatestVersion() |
||
| 643 | |||
| 644 | /** |
||
| 645 | * Returns <code>true</code> if this document is a major version (CMIS property cmis:isMajorVersion). |
||
| 646 | * |
||
| 647 | * @return boolean|null the major version flag of the document or <code>null</code> if the property hasn't |
||
| 648 | * been requested, hasn't been provided by the repository, or the property value isn't set |
||
| 649 | */ |
||
| 650 | public function isMajorVersion() |
||
| 654 | |||
| 655 | /** |
||
| 656 | * Returns <code>true</code> if this document is the PWC (CMIS property cmis:isPrivateWorkingCopy). |
||
| 657 | * |
||
| 658 | * @return boolean|null the PWC flag of the document or <code>null</code> if the property hasn't been requested, |
||
| 659 | * hasn't been provided by the repository, or the property value isn't set |
||
| 660 | */ |
||
| 661 | public function isPrivateWorkingCopy() |
||
| 665 | |||
| 666 | /** |
||
| 667 | * Returns <code>true</code> if this version series is checked out (CMIS property cmis:isVersionSeriesCheckedOut). |
||
| 668 | * |
||
| 669 | * @return boolean|null the version series checked out flag of the document or <code>null</code> if the property |
||
| 670 | * hasn't been requested, hasn't been provided by the repository, or the property value isn't set |
||
| 671 | */ |
||
| 672 | public function isVersionSeriesCheckedOut() |
||
| 676 | } |
||
| 677 |