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 |
||
| 33 | class Document extends AbstractFileableCmisObject implements DocumentInterface |
||
| 34 | { |
||
| 35 | /** |
||
| 36 | * Appends a content stream to the content stream of the document and refreshes this object afterwards. |
||
| 37 | * If the repository created a new version, this new document is returned. |
||
| 38 | * Otherwise the current document is returned. |
||
| 39 | * The stream in contentStream is consumed but not closed by this method. |
||
| 40 | * |
||
| 41 | * @param StreamInterface $contentStream the content stream |
||
| 42 | * @param boolean $isLastChunk indicates if this stream is the last chunk of the content |
||
| 43 | * @param boolean $refresh if this parameter is set to <code>true</code>, this object will be refreshed after the |
||
| 44 | * content stream has been appended |
||
| 45 | * @return ObjectIdInterface|null the updated object ID, or <code>null</code> if the repository did not return |
||
| 46 | * an object ID |
||
| 47 | * @throws CmisNotSupportedException |
||
| 48 | */ |
||
| 49 | public function appendContentStream(StreamInterface $contentStream, $isLastChunk, $refresh = true) |
||
| 76 | |||
| 77 | /** |
||
| 78 | * If this is a PWC (private working copy) the check out will be reversed. |
||
| 79 | */ |
||
| 80 | public function cancelCheckOut() |
||
| 86 | |||
| 87 | /** |
||
| 88 | * If this is a PWC (private working copy) it performs a check in. |
||
| 89 | * If this is not a PWC an exception will be thrown. |
||
| 90 | * The stream in contentStream is consumed but not closed by this method. |
||
| 91 | * |
||
| 92 | * @param boolean $major <code>true</code> if the checked-in document object MUST be a major version. |
||
| 93 | * <code>false</code> if the checked-in document object MUST NOT be a major version but a minor version. |
||
| 94 | * @param array $properties The property values that MUST be applied to the checked-in document object. |
||
| 95 | * @param StreamInterface $contentStream The content stream that MUST be stored for the checked-in document object. |
||
| 96 | * The method of passing the contentStream to the server and the encoding mechanism will be specified by each |
||
| 97 | * specific binding. MUST be required if the type requires it. |
||
| 98 | * @param string $checkinComment Textual comment associated with the given version. MAY be "not set". |
||
| 99 | * @param PolicyInterface[] $policies A list of policy ids that MUST be applied to the newly-created document |
||
| 100 | * object |
||
| 101 | * @param AceInterface[] $addAces A list of ACEs that MUST be added to the newly-created document object. |
||
| 102 | * @param AceInterface[] $removeAces A list of ACEs that MUST be removed from the newly-created document object. |
||
| 103 | * @return ObjectIdInterface|null The id of the checked-in document. <code>null</code> if repository has not |
||
| 104 | * returned the new object id which could happen in case of a repository error |
||
| 105 | */ |
||
| 106 | public function checkIn( |
||
| 149 | |||
| 150 | /** |
||
| 151 | * Checks out the document and returns the object ID of the PWC (private working copy). |
||
| 152 | * |
||
| 153 | * @return ObjectIdInterface|null PWC object ID |
||
| 154 | */ |
||
| 155 | public function checkOut() |
||
| 167 | |||
| 168 | /** |
||
| 169 | * Creates a copy of this document, including content. |
||
| 170 | * |
||
| 171 | * @param ObjectIdInterface|null $targetFolderId the ID of the target folder, <code>null</code> to create an unfiled |
||
| 172 | * document |
||
| 173 | * @param array $properties The property values that MUST be applied to the object. This list of properties SHOULD |
||
| 174 | * only contain properties whose values differ from the source document. The array key is the property name |
||
| 175 | * the value is the property value. |
||
| 176 | * @param VersioningState|null $versioningState An enumeration specifying what the versioning state of the |
||
| 177 | * newly-created object MUST be. Valid values are: |
||
| 178 | * <code>none</code> |
||
| 179 | * (default, if the object-type is not versionable) The document MUST be created as a non-versionable |
||
| 180 | * document. |
||
| 181 | * <code>checkedout</code> |
||
| 182 | * The document MUST be created in the checked-out state. The checked-out document MAY be |
||
| 183 | * visible to other users. |
||
| 184 | * <code>major</code> |
||
| 185 | * (default, if the object-type is versionable) The document MUST be created as a major version. |
||
| 186 | * <code>minor</code> |
||
| 187 | * The document MUST be created as a minor version. |
||
| 188 | * @param PolicyInterface[] $policies A list of policy ids that MUST be applied to the newly-created document |
||
| 189 | * object. |
||
| 190 | * @param AceInterface[] $addAces A list of ACEs that MUST be added to the newly-created document object, either |
||
| 191 | * using the ACL from folderId if specified, or being applied if no folderId is specified. |
||
| 192 | * @param AceInterface[] $removeAces A list of ACEs that MUST be removed from the newly-created document object, |
||
| 193 | * either using the ACL from folderId if specified, or being ignored if no folderId is specified. |
||
| 194 | * @param OperationContextInterface|null $context |
||
| 195 | * @return DocumentInterface the new document object or <code>null</code> if the parameter <code>context</code> was |
||
| 196 | * set to <code>null</code> |
||
| 197 | * @throws CmisRuntimeException Exception is thrown if the created object is not a document |
||
| 198 | */ |
||
| 199 | public function copy( |
||
| 239 | |||
| 240 | /** |
||
| 241 | * Copies the document manually. The content is streamed from the repository and back. |
||
| 242 | * |
||
| 243 | * @param ObjectIdInterface|null $targetFolderId the ID of the target folder, <code>null</code> to create an unfiled |
||
| 244 | * document |
||
| 245 | * @param array $properties The property values that MUST be applied to the object. This list of properties SHOULD |
||
| 246 | * only contain properties whose values differ from the source document. The array key is the property name |
||
| 247 | * the value is the property value. |
||
| 248 | * @param VersioningState|null $versioningState An enumeration specifying what the versioning state of the |
||
| 249 | * newly-created object MUST be. Valid values are: |
||
| 250 | * <code>none</code> |
||
| 251 | * (default, if the object-type is not versionable) The document MUST be created as a non-versionable |
||
| 252 | * document. |
||
| 253 | * <code>checkedout</code> |
||
| 254 | * The document MUST be created in the checked-out state. The checked-out document MAY be |
||
| 255 | * visible to other users. |
||
| 256 | * <code>major</code> |
||
| 257 | * (default, if the object-type is versionable) The document MUST be created as a major version. |
||
| 258 | * <code>minor</code> |
||
| 259 | * The document MUST be created as a minor version. |
||
| 260 | * @param PolicyInterface[] $policies A list of policy ids that MUST be applied to the newly-created document |
||
| 261 | * object. |
||
| 262 | * @param AceInterface[] $addAces A list of ACEs that MUST be added to the newly-created document object, either |
||
| 263 | * using the ACL from folderId if specified, or being applied if no folderId is specified. |
||
| 264 | * @param AceInterface[] $removeAces A list of ACEs that MUST be removed from the newly-created document object, |
||
| 265 | * either using the ACL from folderId if specified, or being ignored if no folderId is specified. |
||
| 266 | * @return ObjectIdInterface The id of the newly-created document. |
||
| 267 | * @throws CmisRuntimeException |
||
| 268 | */ |
||
| 269 | protected function copyViaClient( |
||
| 315 | |||
| 316 | /** |
||
| 317 | * Deletes this document and all its versions. |
||
| 318 | */ |
||
| 319 | public function deleteAllVersions() |
||
| 323 | |||
| 324 | /** |
||
| 325 | * Removes the current content stream from the document and refreshes this object afterwards. |
||
| 326 | * |
||
| 327 | * @param boolean $refresh if this parameter is set to <code>true</code>, this object will be refreshed after the |
||
| 328 | * content stream has been deleted |
||
| 329 | * @return DocumentInterface|null the updated document, or <code>null</code> if the repository did not return |
||
| 330 | * an object ID |
||
| 331 | */ |
||
| 332 | View Code Duplication | public function deleteContentStream($refresh = true) |
|
| 356 | |||
| 357 | /** |
||
| 358 | * Fetches all versions of this document using the given OperationContext. |
||
| 359 | * The behavior of this method is undefined if the document is not versionable |
||
| 360 | * and can be different for each repository. |
||
| 361 | * |
||
| 362 | * @param OperationContextInterface|null $context |
||
| 363 | * @return DocumentInterface[] |
||
| 364 | */ |
||
| 365 | public function getAllVersions(OperationContextInterface $context = null) |
||
| 391 | |||
| 392 | /** |
||
| 393 | * Returns the content URL of the document or a rendition if the binding |
||
| 394 | * supports content URLs. |
||
| 395 | * |
||
| 396 | * Depending on the repository and the binding, the server might not return |
||
| 397 | * the content but an error message. Authentication data is not attached. |
||
| 398 | * That is, a user may have to re-authenticate to get the content. |
||
| 399 | * |
||
| 400 | * @param string|null $streamId the ID of the rendition or <code>null</code> for the document |
||
| 401 | * |
||
| 402 | * @return string|null the content URL of the document or rendition or <code>null</code> if |
||
| 403 | * the binding does not support content URLs |
||
| 404 | */ |
||
| 405 | public function getContentUrl($streamId = null) |
||
| 418 | |||
| 419 | /** |
||
| 420 | * Retrieves the content stream that is associated with the given stream ID. |
||
| 421 | * This is usually a rendition of the document. |
||
| 422 | * |
||
| 423 | * @param string|null $streamId the stream ID |
||
| 424 | * @param integer|null $offset the offset of the stream or <code>null</code> to read the stream from the beginning |
||
| 425 | * @param integer|null $length the maximum length of the stream or <code>null</code> to read to the end of the |
||
| 426 | * stream |
||
| 427 | * @return StreamInterface|null the content stream, or <code>null</code> if no content is associated with this |
||
| 428 | * stream ID |
||
| 429 | */ |
||
| 430 | public function getContentStream($streamId = null, $offset = null, $length = null) |
||
| 434 | |||
| 435 | /** |
||
| 436 | * Fetches the latest major or minor version of this document using the given OperationContext. |
||
| 437 | * |
||
| 438 | * @param boolean $major if <code>true</code> the latest major version will be returned, |
||
| 439 | * otherwise the very last version will be returned |
||
| 440 | * @param OperationContextInterface|null $context |
||
| 441 | * @return DocumentInterface the latest document object |
||
| 442 | */ |
||
| 443 | public function getObjectOfLatestVersion($major, OperationContextInterface $context = null) |
||
| 449 | |||
| 450 | /** |
||
| 451 | * Sets a new content stream for the document. If the repository created a new version, |
||
| 452 | * the object ID of this new version is returned. Otherwise the object ID of the current document is returned. |
||
| 453 | * The stream in contentStream is consumed but not closed by this method. |
||
| 454 | * |
||
| 455 | * @param StreamInterface $contentStream the content stream |
||
| 456 | * @param boolean $overwrite if this parameter is set to <code>false</code> and the document already has content, |
||
| 457 | * the repository throws a CmisContentAlreadyExistsException |
||
| 458 | * @param boolean $refresh if this parameter is set to <code>true</code>, this object will be refreshed |
||
| 459 | * after the new content has been set |
||
| 460 | * @return ObjectIdInterface|null the updated object ID, or <code>null</code> if the repository did not return |
||
| 461 | * an object ID |
||
| 462 | */ |
||
| 463 | View Code Duplication | public function setContentStream(StreamInterface $contentStream, $overwrite, $refresh = true) |
|
| 486 | |||
| 487 | /** |
||
| 488 | * Returns the checkin comment (CMIS property cmis:checkinComment). |
||
| 489 | * |
||
| 490 | * @return string|null the checkin comment of this version or <code>null</code> if the property hasn't |
||
| 491 | * been requested, hasn't been provided by the repository, or the property value isn't set |
||
| 492 | */ |
||
| 493 | public function getCheckinComment() |
||
| 497 | |||
| 498 | /** |
||
| 499 | * Returns the content stream filename or <code>null</code> if the document has no content |
||
| 500 | * (CMIS property cmis:contentStreamFileName). |
||
| 501 | * |
||
| 502 | * @return string|null the content stream filename of this document or <code>null</code> if the property hasn't |
||
| 503 | * been requested, hasn't been provided by the repository, or the document has no content |
||
| 504 | */ |
||
| 505 | public function getContentStreamFileName() |
||
| 509 | |||
| 510 | /** |
||
| 511 | * Returns the content hashes or <code>null</code> if the document has no content |
||
| 512 | * (CMIS property cmis:contentStreamHash). |
||
| 513 | * |
||
| 514 | * @return ContentStreamHashInterface[]|null the list of content hashes or <code>null</code> if the property |
||
| 515 | * hasn't been requested, hasn't been provided by the repository, or the document has no content |
||
| 516 | */ |
||
| 517 | public function getContentStreamHashes() |
||
| 523 | |||
| 524 | /** |
||
| 525 | * Returns the content stream ID or <code>null</code> if the document has no content |
||
| 526 | * (CMIS property cmis:contentStreamId). |
||
| 527 | * |
||
| 528 | * @return string|null the content stream ID of this document or <code>null</code> if the property hasn't |
||
| 529 | * been requested, hasn't been provided by the repository, or the document has no content |
||
| 530 | */ |
||
| 531 | public function getContentStreamId() |
||
| 535 | |||
| 536 | /** |
||
| 537 | * Returns the content stream length or <code>null</code> if the document has no content (CMIS property |
||
| 538 | * cmis:contentStreamLength). |
||
| 539 | * |
||
| 540 | * @return integer the content stream length of this document or <code>null</code> if the property hasn't been |
||
| 541 | * requested, hasn't been provided by the repository, or the document has no content |
||
| 542 | */ |
||
| 543 | public function getContentStreamLength() |
||
| 547 | |||
| 548 | /** |
||
| 549 | * Returns the content stream MIME type or <code>null</code> if the document has no content |
||
| 550 | * (CMIS property cmis:contentStreamMimeType). |
||
| 551 | * |
||
| 552 | * @return string|null the content stream MIME type of this document or <code>null</code> if the property hasn't |
||
| 553 | * been requested, hasn't been provided by the repository, or the document has no content |
||
| 554 | */ |
||
| 555 | public function getContentStreamMimeType() |
||
| 559 | |||
| 560 | /** |
||
| 561 | * Returns the version label (CMIS property cmis:versionLabel). |
||
| 562 | * |
||
| 563 | * @return string|null the version label of the document or <code>null</code> if the property hasn't been requested, |
||
| 564 | * hasn't been provided by the repository, or the property value isn't set |
||
| 565 | */ |
||
| 566 | public function getVersionLabel() |
||
| 570 | |||
| 571 | /** |
||
| 572 | * Returns the user who checked out this version series (CMIS property cmis:versionSeriesCheckedOutBy). |
||
| 573 | * |
||
| 574 | * @return string|null the user who checked out this version series or <code>null</code> if the property hasn't |
||
| 575 | * been requested, hasn't been provided by the repository, or the property value isn't set |
||
| 576 | */ |
||
| 577 | public function getVersionSeriesCheckedOutBy() |
||
| 581 | |||
| 582 | /** |
||
| 583 | * Returns the PWC ID of this version series (CMIS property cmis:versionSeriesCheckedOutId). |
||
| 584 | * Some repositories provided this value only to the user who checked out the version series. |
||
| 585 | * |
||
| 586 | * @return string|null the PWC ID of this version series or <code>null</code> if the property hasn't been requested, |
||
| 587 | * hasn't been provided by the repository, or the property value isn't set |
||
| 588 | */ |
||
| 589 | public function getVersionSeriesCheckedOutId() |
||
| 593 | |||
| 594 | /** |
||
| 595 | * Returns the version series ID (CMIS property cmis:versionSeriesId). |
||
| 596 | * |
||
| 597 | * @return string|null the version series ID of the document or <code>null</code> if the property hasn't |
||
| 598 | * been requested, hasn't been provided by the repository, or the property value isn't set |
||
| 599 | */ |
||
| 600 | public function getVersionSeriesId() |
||
| 604 | |||
| 605 | /** |
||
| 606 | * Returns <code>true</code> if this document is immutable (CMIS property cmis:isImmutable). |
||
| 607 | * |
||
| 608 | * @return boolean|null the immutable flag of the document or <code>null</code> if the property hasn't |
||
| 609 | * been requested, hasn't been provided by the repository, or the property value isn't set |
||
| 610 | */ |
||
| 611 | public function isImmutable() |
||
| 615 | |||
| 616 | /** |
||
| 617 | * Returns <code>true</code> if this document is the latest version (CMIS property cmis:isLatestVersion). |
||
| 618 | * |
||
| 619 | * @return boolean|null the latest version flag of the document or <code>null</code> if the property hasn't |
||
| 620 | * been requested, hasn't been provided by the repository, or the property value isn't set |
||
| 621 | */ |
||
| 622 | public function isLatestMajorVersion() |
||
| 626 | |||
| 627 | /** |
||
| 628 | * Returns <code>true</code> if this document is the latest version (CMIS property cmis:isLatestVersion). |
||
| 629 | * |
||
| 630 | * @return boolean|null the latest version flag of the document or <code>null</code> if the property hasn't |
||
| 631 | * been requested, hasn't been provided by the repository, or the property value isn't set |
||
| 632 | */ |
||
| 633 | public function isLatestVersion() |
||
| 637 | |||
| 638 | /** |
||
| 639 | * Returns <code>true</code> if this document is a major version (CMIS property cmis:isMajorVersion). |
||
| 640 | * |
||
| 641 | * @return boolean|null the major version flag of the document or <code>null</code> if the property hasn't |
||
| 642 | * been requested, hasn't been provided by the repository, or the property value isn't set |
||
| 643 | */ |
||
| 644 | public function isMajorVersion() |
||
| 648 | |||
| 649 | /** |
||
| 650 | * Returns <code>true</code> if this document is the PWC (CMIS property cmis:isPrivateWorkingCopy). |
||
| 651 | * |
||
| 652 | * @return boolean|null the PWC flag of the document or <code>null</code> if the property hasn't been requested, |
||
| 653 | * hasn't been provided by the repository, or the property value isn't set |
||
| 654 | */ |
||
| 655 | public function isPrivateWorkingCopy() |
||
| 659 | |||
| 660 | /** |
||
| 661 | * Returns <code>true</code> if this version series is checked out (CMIS property cmis:isVersionSeriesCheckedOut). |
||
| 662 | * |
||
| 663 | * @return boolean|null the version series checked out flag of the document or <code>null</code> if the property |
||
| 664 | * hasn't been requested, hasn't been provided by the repository, or the property value isn't set |
||
| 665 | */ |
||
| 666 | public function isVersionSeriesCheckedOut() |
||
| 670 | } |
||
| 671 |