Commit fb7f6cc4466d1a04251a3c56836eff2a85e887bd
Merge branch 'cmisatom_delete' into edge
Showing
9 changed files
with
504 additions
and
55 deletions
lib/api/ktcmis/ktcmis.inc.php
| @@ -56,6 +56,7 @@ require_once(CMIS_DIR . '/exceptions/PermissionDeniedException.inc.php'); | @@ -56,6 +56,7 @@ require_once(CMIS_DIR . '/exceptions/PermissionDeniedException.inc.php'); | ||
| 56 | require_once(CMIS_DIR . '/services/CMISRepositoryService.inc.php'); | 56 | require_once(CMIS_DIR . '/services/CMISRepositoryService.inc.php'); |
| 57 | require_once(CMIS_DIR . '/services/CMISNavigationService.inc.php'); | 57 | require_once(CMIS_DIR . '/services/CMISNavigationService.inc.php'); |
| 58 | require_once(CMIS_DIR . '/services/CMISObjectService.inc.php'); | 58 | require_once(CMIS_DIR . '/services/CMISObjectService.inc.php'); |
| 59 | +require_once(CMIS_DIR . '/services/CMISVersioningService.inc.php'); | ||
| 59 | require_once(CMIS_DIR . '/util/CMISUtil.inc.php'); | 60 | require_once(CMIS_DIR . '/util/CMISUtil.inc.php'); |
| 60 | 61 | ||
| 61 | /** | 62 | /** |
| @@ -73,7 +74,6 @@ class KTCMISBase { | @@ -73,7 +74,6 @@ class KTCMISBase { | ||
| 73 | { | 74 | { |
| 74 | // TODO confirm KTAPI instance active??? shouldn't really be responsibility of this code | 75 | // TODO confirm KTAPI instance active??? shouldn't really be responsibility of this code |
| 75 | if (is_null($ktapi) && (!is_null($username) && !is_null($password))) { | 76 | if (is_null($ktapi) && (!is_null($username) && !is_null($password))) { |
| 76 | -// echo ":WGHWTWGWGHW"; | ||
| 77 | $this->startSession($username, $password); | 77 | $this->startSession($username, $password); |
| 78 | } | 78 | } |
| 79 | else { | 79 | else { |
| @@ -87,18 +87,15 @@ class KTCMISBase { | @@ -87,18 +87,15 @@ class KTCMISBase { | ||
| 87 | // NOTE left in to allow transport protocol to delegate auth to this level, but not actually used in any code at present | 87 | // NOTE left in to allow transport protocol to delegate auth to this level, but not actually used in any code at present |
| 88 | public function startSession($username, $password) | 88 | public function startSession($username, $password) |
| 89 | { | 89 | { |
| 90 | -// echo $username." :: ".$password."<BR>"; | ||
| 91 | // attempt to recover session if one exists | 90 | // attempt to recover session if one exists |
| 92 | if (!is_null(self::$session) && !PEAR::isError(self::$session)) | 91 | if (!is_null(self::$session) && !PEAR::isError(self::$session)) |
| 93 | { | 92 | { |
| 94 | -// echo "ATTEMPT TO RECOVER SESSION: ".print_r(self::$session, true)."<BR>\n"; | ||
| 95 | self::$session =& self::$ktapi->get_active_session(self::$session->get_sessionid()); | 93 | self::$session =& self::$ktapi->get_active_session(self::$session->get_sessionid()); |
| 96 | } | 94 | } |
| 97 | 95 | ||
| 98 | // start new session if no existing session or problem getting existing session (expired, etc...) | 96 | // start new session if no existing session or problem getting existing session (expired, etc...) |
| 99 | if (is_null(self::$session) || PEAR::isError(self::$session)) | 97 | if (is_null(self::$session) || PEAR::isError(self::$session)) |
| 100 | { | 98 | { |
| 101 | -// echo "ATTEMPT TO START NEW SESSION<BR>\n"; | ||
| 102 | self::$ktapi = new KTAPI(); | 99 | self::$ktapi = new KTAPI(); |
| 103 | self::$session =& self::$ktapi->start_session($username, $password); | 100 | self::$session =& self::$ktapi->start_session($username, $password); |
| 104 | } | 101 | } |
| @@ -109,7 +106,6 @@ class KTCMISBase { | @@ -109,7 +106,6 @@ class KTCMISBase { | ||
| 109 | throw new PermissionDeniedException('You must be authenticated to perform this action'); | 106 | throw new PermissionDeniedException('You must be authenticated to perform this action'); |
| 110 | } | 107 | } |
| 111 | 108 | ||
| 112 | -// print_r(self::$ktapi); | ||
| 113 | return self::$session; | 109 | return self::$session; |
| 114 | } | 110 | } |
| 115 | 111 | ||
| @@ -594,6 +590,54 @@ class KTObjectService extends KTCMISBase { | @@ -594,6 +590,54 @@ class KTObjectService extends KTCMISBase { | ||
| 594 | 'results' => $objectId | 590 | 'results' => $objectId |
| 595 | ); | 591 | ); |
| 596 | } | 592 | } |
| 593 | + | ||
| 594 | + /** | ||
| 595 | + * Deletes an object from the repository | ||
| 596 | + * | ||
| 597 | + * @param string $repositoryId | ||
| 598 | + * @param string $objectId | ||
| 599 | + * @param string $changeToken [optional] | ||
| 600 | + * @return array | ||
| 601 | + */ | ||
| 602 | + // NOTE Invoking this service method on an object SHALL not delete the entire version series for a Document Object. | ||
| 603 | + // To delete an entire version series, use the deleteAllVersions() service | ||
| 604 | + function deleteObject($repositoryId, $objectId, $changeToken = null) | ||
| 605 | + { | ||
| 606 | + try { | ||
| 607 | + $result = $this->ObjectService->deleteObject($repositoryId, $objectId, $changeToken); | ||
| 608 | + } | ||
| 609 | + catch (Exception $e) | ||
| 610 | + { | ||
| 611 | + return array( | ||
| 612 | + "status_code" => 1, | ||
| 613 | + "message" => $e->getMessage() | ||
| 614 | + ); | ||
| 615 | + } | ||
| 616 | + | ||
| 617 | + return array( | ||
| 618 | + 'status_code' => 0, | ||
| 619 | + 'results' => $objectId | ||
| 620 | + ); | ||
| 621 | + } | ||
| 622 | + | ||
| 623 | + public function deleteTree($repositoryId, $objectId, $changeToken = null, $unfileNonfolderObject = 'delete', $continueOnFailure = false) | ||
| 624 | + { | ||
| 625 | + try { | ||
| 626 | + $result = $this->ObjectService->deleteTree($repositoryId, $objectId, $changeToken, $unfileNonfolderObject, $continueOnFailure); | ||
| 627 | + } | ||
| 628 | + catch (Exception $e) | ||
| 629 | + { | ||
| 630 | + return array( | ||
| 631 | + "status_code" => 1, | ||
| 632 | + "message" => $e->getMessage() | ||
| 633 | + ); | ||
| 634 | + } | ||
| 635 | + | ||
| 636 | + return array( | ||
| 637 | + 'status_code' => 0, | ||
| 638 | + 'results' => $objectId | ||
| 639 | + ); | ||
| 640 | + } | ||
| 597 | 641 | ||
| 598 | /** | 642 | /** |
| 599 | * Sets the content stream data for an existing document | 643 | * Sets the content stream data for an existing document |
| @@ -614,7 +658,7 @@ class KTObjectService extends KTCMISBase { | @@ -614,7 +658,7 @@ class KTObjectService extends KTCMISBase { | ||
| 614 | function setContentStream($repositoryId, $documentId, $overwriteFlag, $contentStream, $changeToken = null) | 658 | function setContentStream($repositoryId, $documentId, $overwriteFlag, $contentStream, $changeToken = null) |
| 615 | { | 659 | { |
| 616 | try { | 660 | try { |
| 617 | - $objectId = $this->ObjectService->setContentStream($repositoryId, $documentId, $overwriteFlag, $contentStream, $changeToken); | 661 | + $documentId = $this->ObjectService->setContentStream($repositoryId, $documentId, $overwriteFlag, $contentStream, $changeToken); |
| 618 | } | 662 | } |
| 619 | catch (Exception $e) | 663 | catch (Exception $e) |
| 620 | { | 664 | { |
| @@ -632,4 +676,60 @@ class KTObjectService extends KTCMISBase { | @@ -632,4 +676,60 @@ class KTObjectService extends KTCMISBase { | ||
| 632 | 676 | ||
| 633 | } | 677 | } |
| 634 | 678 | ||
| 679 | +/** | ||
| 680 | + * Handles requests for and actions on versionable objects | ||
| 681 | + */ | ||
| 682 | +class KTVersioningService extends KTCMISBase { | ||
| 683 | + | ||
| 684 | + protected $VersioningService; | ||
| 685 | + | ||
| 686 | + public function __construct(&$ktapi = null, $username = null, $password = null) | ||
| 687 | + { | ||
| 688 | + parent::__construct($ktapi, $username, $password); | ||
| 689 | + // instantiate underlying CMIS service | ||
| 690 | + $this->VersioningService = new CMISVersioningService(); | ||
| 691 | + $this->setInterface(); | ||
| 692 | + } | ||
| 693 | + | ||
| 694 | + public function startSession($username, $password) | ||
| 695 | + { | ||
| 696 | + parent::startSession($username, $password); | ||
| 697 | + $this->setInterface(); | ||
| 698 | + return self::$session; | ||
| 699 | + } | ||
| 700 | + | ||
| 701 | + public function setInterface(&$ktapi = null) | ||
| 702 | + { | ||
| 703 | + parent::setInterface($ktapi); | ||
| 704 | + $this->VersioningService->setInterface(self::$ktapi); | ||
| 705 | + } | ||
| 706 | + | ||
| 707 | + /** | ||
| 708 | + * Deletes all Document Objects in the specified Version Series, including the Private Working Copy | ||
| 709 | + * | ||
| 710 | + * @param string $repositoryId | ||
| 711 | + * @param string $versionSeriesId | ||
| 712 | + * @return boolean true if successful | ||
| 713 | + */ | ||
| 714 | + public function deleteAllVersions($repositoryId, $versionSeriesId) | ||
| 715 | + { | ||
| 716 | + try { | ||
| 717 | + $result = $this->VersioningService->deleteAllVersions($repositoryId, $versionSeriesId); | ||
| 718 | + } | ||
| 719 | + catch (Exception $e) | ||
| 720 | + { | ||
| 721 | + return array( | ||
| 722 | + "status_code" => 1, | ||
| 723 | + "message" => $e->getMessage() | ||
| 724 | + ); | ||
| 725 | + } | ||
| 726 | + | ||
| 727 | + return array( | ||
| 728 | + 'status_code' => 0, | ||
| 729 | + 'results' => $result | ||
| 730 | + ); | ||
| 731 | + } | ||
| 732 | + | ||
| 733 | +} | ||
| 734 | + | ||
| 635 | ?> | 735 | ?> |
lib/api/ktcmis/objecttypes/CMISDocumentObject.inc.php
| @@ -144,8 +144,9 @@ class CMISDocumentObject extends CMISBaseObject { | @@ -144,8 +144,9 @@ class CMISDocumentObject extends CMISBaseObject { | ||
| 144 | // NOTE see ktapi::is_latest_version | 144 | // NOTE see ktapi::is_latest_version |
| 145 | $this->_setPropertyInternal('IsLatestMajorVersion', true); | 145 | $this->_setPropertyInternal('IsLatestMajorVersion', true); |
| 146 | $this->_setPropertyInternal('VersionLabel', $objectProperties['version']); | 146 | $this->_setPropertyInternal('VersionLabel', $objectProperties['version']); |
| 147 | - // TODO what determines this, do we have anything? | ||
| 148 | - $this->_setPropertyInternal('VersionSeriesId', null); | 147 | + // VersionSeriesId should be the id of the latest version |
| 148 | + // NOTE this may change in the future but is easiest for the current implementation | ||
| 149 | + $this->_setPropertyInternal('VersionSeriesId', $objectProperties['version']); | ||
| 149 | if ($objectProperties['checked_out_by'] != 'n/a') | 150 | if ($objectProperties['checked_out_by'] != 'n/a') |
| 150 | { | 151 | { |
| 151 | $checkedOut = true; | 152 | $checkedOut = true; |
lib/api/ktcmis/services/CMISNavigationService.inc.php
| @@ -48,7 +48,7 @@ class CMISNavigationService { | @@ -48,7 +48,7 @@ class CMISNavigationService { | ||
| 48 | protected $ktapi; | 48 | protected $ktapi; |
| 49 | 49 | ||
| 50 | /** | 50 | /** |
| 51 | - * Sets the interface to be used to query the repository | 51 | + * Sets the interface to be used to interact with the repository |
| 52 | * | 52 | * |
| 53 | * @param object $ktapi The KnowledgeTree API interface | 53 | * @param object $ktapi The KnowledgeTree API interface |
| 54 | */ | 54 | */ |
lib/api/ktcmis/services/CMISObjectService.inc.php
| @@ -21,11 +21,11 @@ class CMISObjectService { | @@ -21,11 +21,11 @@ class CMISObjectService { | ||
| 21 | protected $ktapi; | 21 | protected $ktapi; |
| 22 | 22 | ||
| 23 | /** | 23 | /** |
| 24 | - * Sets the interface to be used to query the repository | 24 | + * Sets the interface to be used to interact with the repository |
| 25 | * | 25 | * |
| 26 | * @param object $ktapi The KnowledgeTree API interface | 26 | * @param object $ktapi The KnowledgeTree API interface |
| 27 | */ | 27 | */ |
| 28 | - function setInterface(&$ktapi) | 28 | + public function setInterface(&$ktapi) |
| 29 | { | 29 | { |
| 30 | $this->ktapi = $ktapi; | 30 | $this->ktapi = $ktapi; |
| 31 | } | 31 | } |
| @@ -43,8 +43,8 @@ class CMISObjectService { | @@ -43,8 +43,8 @@ class CMISObjectService { | ||
| 43 | */ | 43 | */ |
| 44 | // TODO optional parameter support | 44 | // TODO optional parameter support |
| 45 | // TODO FilterNotValidException: The Repository SHALL throw this exception if this property filter input parameter is not valid | 45 | // TODO FilterNotValidException: The Repository SHALL throw this exception if this property filter input parameter is not valid |
| 46 | - function getProperties($repositoryId, $objectId, $includeAllowableActions, $includeRelationships, | ||
| 47 | - $returnVersion = false, $filter = '') | 46 | + public function getProperties($repositoryId, $objectId, $includeAllowableActions, $includeRelationships, |
| 47 | + $returnVersion = false, $filter = '') | ||
| 48 | { | 48 | { |
| 49 | $repository = new CMISRepository($repositoryId); | 49 | $repository = new CMISRepository($repositoryId); |
| 50 | 50 | ||
| @@ -87,8 +87,8 @@ class CMISObjectService { | @@ -87,8 +87,8 @@ class CMISObjectService { | ||
| 87 | // TODO throw ConstraintViolationException if: | 87 | // TODO throw ConstraintViolationException if: |
| 88 | // value of any of the properties violates the min/max/required/length constraints | 88 | // value of any of the properties violates the min/max/required/length constraints |
| 89 | // specified in the property definition in the Object-Type. | 89 | // specified in the property definition in the Object-Type. |
| 90 | - function createDocument($repositoryId, $typeId, $properties, $folderId = null, | ||
| 91 | - $contentStream = null, $versioningState = null) | 90 | + public function createDocument($repositoryId, $typeId, $properties, $folderId = null, |
| 91 | + $contentStream = null, $versioningState = null) | ||
| 92 | { | 92 | { |
| 93 | $objectId = null; | 93 | $objectId = null; |
| 94 | 94 | ||
| @@ -344,7 +344,7 @@ class CMISObjectService { | @@ -344,7 +344,7 @@ class CMISObjectService { | ||
| 344 | // TODO throw ConstraintViolationException if: | 344 | // TODO throw ConstraintViolationException if: |
| 345 | // value of any of the properties violates the min/max/required/length constraints | 345 | // value of any of the properties violates the min/max/required/length constraints |
| 346 | // specified in the property definition in the Object-Type. | 346 | // specified in the property definition in the Object-Type. |
| 347 | - function createFolder($repositoryId, $typeId, $properties, $folderId) | 347 | + public function createFolder($repositoryId, $typeId, $properties, $folderId) |
| 348 | { | 348 | { |
| 349 | $objectId = null; | 349 | $objectId = null; |
| 350 | 350 | ||
| @@ -399,6 +399,148 @@ class CMISObjectService { | @@ -399,6 +399,148 @@ class CMISObjectService { | ||
| 399 | 399 | ||
| 400 | return $objectId; | 400 | return $objectId; |
| 401 | } | 401 | } |
| 402 | + | ||
| 403 | + /** | ||
| 404 | + * Deletes an object from the repository | ||
| 405 | + * | ||
| 406 | + * @param string $repositoryId | ||
| 407 | + * @param string $objectId | ||
| 408 | + * @param string $changeToken [optional] | ||
| 409 | + * @return boolean true on success (exception should be thrown otherwise) | ||
| 410 | + */ | ||
| 411 | + // NOTE Invoking this service method on an object SHALL not delete the entire version series for a Document Object. | ||
| 412 | + // To delete an entire version series, use the deleteAllVersions() service | ||
| 413 | + public function deleteObject($repositoryId, $objectId, $changeToken = null) | ||
| 414 | + { | ||
| 415 | + // determine object type and internal id | ||
| 416 | + $objectId = CMISUtil::decodeObjectId($objectId, $typeId); | ||
| 417 | + | ||
| 418 | + // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository). | ||
| 419 | + $exists = true; | ||
| 420 | + if ($typeId == 'Folder') { | ||
| 421 | + $object = $this->ktapi->get_folder_by_id($objectId); | ||
| 422 | + if (PEAR::isError($object)) { | ||
| 423 | + $exists = false; | ||
| 424 | + } | ||
| 425 | + } | ||
| 426 | + else if ($typeId == 'Document') { | ||
| 427 | + $object = $this->ktapi->get_document_by_id($objectId); | ||
| 428 | + if (PEAR::isError($object)) { | ||
| 429 | + $exists = false; | ||
| 430 | + } | ||
| 431 | + } | ||
| 432 | + else { | ||
| 433 | + $exists = false; | ||
| 434 | + } | ||
| 435 | + | ||
| 436 | + if (!$exists) { | ||
| 437 | + throw new updateConflictException('Unable to delete the object as it cannot be found.'); | ||
| 438 | + } | ||
| 439 | + | ||
| 440 | + // throw ConstraintViolationException if method is invoked on a Folder object that contains one or more objects | ||
| 441 | + if ($typeId == 'Folder') | ||
| 442 | + { | ||
| 443 | + $folderContent = $object->get_listing(); | ||
| 444 | + if (!PEAR::isError($folderContent)) | ||
| 445 | + { | ||
| 446 | + if (count($folderContent) > 0) { | ||
| 447 | + throw new ConstraintViolationException('Unable to delete a folder with content. Use deleteTree instead.'); | ||
| 448 | + } | ||
| 449 | + } | ||
| 450 | + | ||
| 451 | + // now try the delete and throw an exception if there is an error | ||
| 452 | + // TODO add a default reason | ||
| 453 | + // TODO add the electronic signature capability | ||
| 454 | + $result = $this->ktapi->delete_folder($objectId, $reason, $sig_username, $sig_password); | ||
| 455 | + } | ||
| 456 | + else if ($typeId == 'Document') | ||
| 457 | + { | ||
| 458 | + // since we do not allow deleting of only the latest version we must throw an exception when this function is called on any document | ||
| 459 | + // which has more than one version. Okay to delete if there is only the one version. | ||
| 460 | + $versions = $object->get_version_history(); | ||
| 461 | + if (count($versions) > 1) | ||
| 462 | + { | ||
| 463 | + // NOTE possibly may want to just throw a RuntimeException rather than this CMIS specific exception. | ||
| 464 | + throw new ConstraintViolationException('This function may not be used to delete an object which has multiple versions. ' | ||
| 465 | + . 'Since the repository does not allow deleting of only the latest version, nothing can be deleted.'); | ||
| 466 | + } | ||
| 467 | + | ||
| 468 | + // do not allow deletion of a checked out document - this is actually handled by the ktapi code, | ||
| 469 | + // but is possibly slightly more efficient to check before trying to delete | ||
| 470 | + if ($object->is_checked_out()) { | ||
| 471 | + throw new RuntimeException('The object cannot be deleted as it is currently checked out'); | ||
| 472 | + } | ||
| 473 | + | ||
| 474 | + // now try the delete and throw an exception if there is an error | ||
| 475 | + // TODO add a default reason | ||
| 476 | + // TODO add the electronic signature capability | ||
| 477 | + $auth_sig = true; | ||
| 478 | + $result = $this->ktapi->delete_document($objectId, $reason, $auth_sig, $sig_username, $sig_password); | ||
| 479 | + } | ||
| 480 | + | ||
| 481 | + // if there was an error performing the delete, throw exception | ||
| 482 | + if ($result['status_code'] == 1) { | ||
| 483 | + throw new RuntimeException('There was an error deleting the object: ' . $result['message']); | ||
| 484 | + } | ||
| 485 | + | ||
| 486 | + return true; | ||
| 487 | + } | ||
| 488 | + | ||
| 489 | + /** | ||
| 490 | + * Deletes an entire tree including all subfolders and other filed objects | ||
| 491 | + * | ||
| 492 | + * @param string $repositoryId | ||
| 493 | + * @param string $objectId | ||
| 494 | + * @param string $changeToken [optional] | ||
| 495 | + * @param boolean $unfileNonfolderObject [optional] - note that since KnowledgeTree does not allow unfiling this will be ignored | ||
| 496 | + * @param boolean $continueOnFailure [optional] - note that since KnowledgeTree does not allow continue on failure this will be ignored | ||
| 497 | + * @return array $failedToDelete A list of identifiers of objects in the folder tree that were not deleted. | ||
| 498 | + */ | ||
| 499 | + // NOTE • A Repository MAY attempt to delete child- and descendant-objects of the specified folder in any order. | ||
| 500 | + // • Any child- or descendant-object that the Repository cannot delete SHALL persist in a valid state in the CMIS domain model. | ||
| 501 | + // • This is not transactional. | ||
| 502 | + // • However, if DeleteSingleFiled is chosen and some objects fail to delete, then single-filed objects are either deleted or kept, | ||
| 503 | + // never just unfiled. This is so that a user can call this command again to recover from the error by using the same tree. | ||
| 504 | + public function deleteTree($repositoryId, $objectId, $changeToken = null, $unfileNonfolderObject = 'delete', $continueOnFailure = false) | ||
| 505 | + { | ||
| 506 | + // NOTE since we do not currently allow partial deletes this will always be empty | ||
| 507 | + // (unless there is a failure at the requested folder level - what do we do then? exception or array of all objects?) | ||
| 508 | + $failedToDelete = array(); | ||
| 509 | + | ||
| 510 | + // determine object type and internal id | ||
| 511 | + $objectId = CMISUtil::decodeObjectId($objectId, $typeId); | ||
| 512 | + | ||
| 513 | + // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository). | ||
| 514 | + $exists = true; | ||
| 515 | + if ($typeId == 'Folder') { | ||
| 516 | + $object = $this->ktapi->get_folder_by_id($objectId); | ||
| 517 | + if (PEAR::isError($object)) { | ||
| 518 | + $exists = false; | ||
| 519 | + } | ||
| 520 | + } | ||
| 521 | + // if not of type folder then we have a general problem, throw exception | ||
| 522 | + else { | ||
| 523 | + throw new RuntimeException('Cannot call deleteTree on a non-folder object.'); | ||
| 524 | + } | ||
| 525 | + | ||
| 526 | + if (!$exists) { | ||
| 527 | + throw new updateConflictException('Unable to delete the object as it cannot be found.'); | ||
| 528 | + } | ||
| 529 | + | ||
| 530 | + // attempt to delete tree, throw RuntimeException if failed | ||
| 531 | + // TODO add a default reason | ||
| 532 | + // TODO add the electronic signature capability | ||
| 533 | + $result = $this->ktapi->delete_folder($objectId, $reason, $sig_username, $sig_password); | ||
| 534 | + // if there was an error performing the delete, throw exception | ||
| 535 | + // TODO list of objects which failed in $failedToDelete array; | ||
| 536 | + // since we do not delete the folder or any contents if anything cannot be deleted, this will contain the entire tree listing | ||
| 537 | + // NOTE once we do this we will need to deal with it externally as well, since we can no longer just catch an exception. | ||
| 538 | + if ($result['status_code'] == 1) { | ||
| 539 | + throw new RuntimeException('There was an error deleting the object: ' . $result['message']); | ||
| 540 | + } | ||
| 541 | + | ||
| 542 | + return $failedToDelete; | ||
| 543 | + } | ||
| 402 | 544 | ||
| 403 | // NOTE this function is presently incomplete and untested. Completion deferred to implementation of Checkout/Checkin | 545 | // NOTE this function is presently incomplete and untested. Completion deferred to implementation of Checkout/Checkin |
| 404 | // functionality | 546 | // functionality |
| @@ -428,7 +570,7 @@ class CMISObjectService { | @@ -428,7 +570,7 @@ class CMISObjectService { | ||
| 428 | // updateConflictException: The operation is attempting to update an object that is no longer current | 570 | // updateConflictException: The operation is attempting to update an object that is no longer current |
| 429 | // (as determined by the repository). | 571 | // (as determined by the repository). |
| 430 | // versioningException: The repository MAY throw this exception if the object is a non-current Document Version. | 572 | // versioningException: The repository MAY throw this exception if the object is a non-current Document Version. |
| 431 | - function setContentStream($repositoryId, $documentId, $overwriteFlag, $contentStream, $changeToken = null) | 573 | + public function setContentStream($repositoryId, $documentId, $overwriteFlag, $contentStream, $changeToken = null) |
| 432 | { | 574 | { |
| 433 | // if no document id was supplied, we are going to create the underlying physical document | 575 | // if no document id was supplied, we are going to create the underlying physical document |
| 434 | // NOTE while it might have been nice to keep this out of here, KTAPI has no method for creating a document without | 576 | // NOTE while it might have been nice to keep this out of here, KTAPI has no method for creating a document without |
lib/api/ktcmis/services/CMISVersioningService.inc.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +require_once(KT_DIR . '/ktapi/ktapi.inc.php'); | ||
| 4 | +//require_once(CMIS_DIR . '/exceptions/ConstraintViolationException.inc.php'); | ||
| 5 | +//require_once(CMIS_DIR . '/exceptions/ContentAlreadyExistsException.inc.php'); | ||
| 6 | +//require_once(CMIS_DIR . '/exceptions/ObjectNotFoundException.inc.php'); | ||
| 7 | +//require_once(CMIS_DIR . '/exceptions/StorageException.inc.php'); | ||
| 8 | +//require_once(CMIS_DIR . '/exceptions/StreamNotSupportedException.inc.php'); | ||
| 9 | +//require_once(CMIS_DIR . '/exceptions/UpdateConflictException.inc.php'); | ||
| 10 | +//require_once(CMIS_DIR . '/exceptions/VersioningException.inc.php'); | ||
| 11 | +//require_once(CMIS_DIR . '/services/CMISRepositoryService.inc.php'); | ||
| 12 | +//require_once(CMIS_DIR . '/objecttypes/CMISDocumentObject.inc.php'); | ||
| 13 | +//require_once(CMIS_DIR . '/objecttypes/CMISFolderObject.inc.php'); | ||
| 14 | +//require_once(CMIS_DIR . '/classes/CMISRepository.inc.php'); | ||
| 15 | +//require_once(CMIS_DIR . '/util/CMISUtil.inc.php'); | ||
| 16 | + | ||
| 17 | +class CMISVersioningService { | ||
| 18 | + | ||
| 19 | + protected $ktapi; | ||
| 20 | + | ||
| 21 | + /** | ||
| 22 | + * Sets the interface to be used to interact with the repository | ||
| 23 | + * | ||
| 24 | + * @param object $ktapi The KnowledgeTree API interface | ||
| 25 | + */ | ||
| 26 | + public function setInterface(&$ktapi) | ||
| 27 | + { | ||
| 28 | + $this->ktapi = $ktapi; | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + /** | ||
| 32 | + * Deletes all Document Objects in the specified Version Series, including the Private Working Copy | ||
| 33 | + * | ||
| 34 | + * @param string $repositoryId | ||
| 35 | + * @param string $versionSeriesId | ||
| 36 | + * @return boolean true if successful | ||
| 37 | + */ | ||
| 38 | + // NOTE For KnowledgeTree the $versionSeriesId should be the latest version, if not it will be taken as implied. | ||
| 39 | + // Should we decide to implement the ability to delete individual versions, | ||
| 40 | + // then an exception may be thrown under certain circumstances (to be determined) | ||
| 41 | + // NOTE I am not really sure how this is going to be handled by CMIS clients. | ||
| 42 | + // Testing with CMISSpaces we have it sending the actual document id, not a version series id. | ||
| 43 | + // This may be due to the data sent back from our code, or it may just be how CMISSpaces does it. | ||
| 44 | + // There is a note in their source code about this. | ||
| 45 | + // Meantime we will try based on document id and adjust as needed later | ||
| 46 | + public function deleteAllVersions($repositoryId, $versionSeriesId) | ||
| 47 | + { | ||
| 48 | + // attempt to delete based on versionSeriesId as document/object id | ||
| 49 | + // determine object type and internal id | ||
| 50 | + $objectId = CMISUtil::decodeObjectId($versionSeriesId, $typeId); | ||
| 51 | + | ||
| 52 | + // if not a versionable object, throw exception | ||
| 53 | + // NOTE that we are assuming only documents are versionable at the moment | ||
| 54 | + if ($typeId != 'Document') { | ||
| 55 | + throw new RuntimeException('The object type is not versionable and cannot be deleted using deleteAllVersions.'); | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + // try to delete | ||
| 59 | + // TODO add a default reason | ||
| 60 | + // TODO add the electronic signature capability | ||
| 61 | + $auth_sig = true; | ||
| 62 | + $result = $this->ktapi->delete_document($objectId, $reason, $auth_sig, $sig_username, $sig_password); | ||
| 63 | + | ||
| 64 | + // if there was an error performing the delete, throw exception | ||
| 65 | + if ($result['status_code'] == 1) { | ||
| 66 | + throw new RuntimeException('There was an error deleting the object: ' . $result['message']); | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + return true; | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | +} | ||
| 73 | + | ||
| 74 | +?> |
webservice/atompub/cmis/KT_cmis_atom_server.services.inc.php
| @@ -33,18 +33,20 @@ When POSTing an Atom Document, the atom fields take precedence over the CMIS pro | @@ -33,18 +33,20 @@ When POSTing an Atom Document, the atom fields take precedence over the CMIS pro | ||
| 33 | include_once CMIS_ATOM_LIB_FOLDER . 'RepositoryService.inc.php'; | 33 | include_once CMIS_ATOM_LIB_FOLDER . 'RepositoryService.inc.php'; |
| 34 | include_once CMIS_ATOM_LIB_FOLDER . 'NavigationService.inc.php'; | 34 | include_once CMIS_ATOM_LIB_FOLDER . 'NavigationService.inc.php'; |
| 35 | include_once CMIS_ATOM_LIB_FOLDER . 'ObjectService.inc.php'; | 35 | include_once CMIS_ATOM_LIB_FOLDER . 'ObjectService.inc.php'; |
| 36 | +include_once CMIS_ATOM_LIB_FOLDER . 'VersioningService.inc.php'; | ||
| 36 | include_once 'KT_cmis_atom_service_helper.inc.php'; | 37 | include_once 'KT_cmis_atom_service_helper.inc.php'; |
| 37 | 38 | ||
| 38 | // TODO auth failed response requires WWW-Authenticate: Basic realm="KnowledgeTree DMS" header | 39 | // TODO auth failed response requires WWW-Authenticate: Basic realm="KnowledgeTree DMS" header |
| 39 | 40 | ||
| 40 | /** | 41 | /** |
| 41 | * AtomPub Service: folder | 42 | * AtomPub Service: folder |
| 42 | - * | ||
| 43 | - * Returns children, descendants (up to arbitrary depth) or detail for a particular folder | ||
| 44 | - * | ||
| 45 | */ | 43 | */ |
| 46 | class KT_cmis_atom_service_folder extends KT_atom_service { | 44 | class KT_cmis_atom_service_folder extends KT_atom_service { |
| 47 | 45 | ||
| 46 | + /** | ||
| 47 | + * Deals with GET actions for folders. | ||
| 48 | + * This includes children and tree/descendant listings as well as individual folder retrieval | ||
| 49 | + */ | ||
| 48 | public function GET_action() | 50 | public function GET_action() |
| 49 | { | 51 | { |
| 50 | $RepositoryService = new RepositoryService(); | 52 | $RepositoryService = new RepositoryService(); |
| @@ -88,6 +90,10 @@ class KT_cmis_atom_service_folder extends KT_atom_service { | @@ -88,6 +90,10 @@ class KT_cmis_atom_service_folder extends KT_atom_service { | ||
| 88 | $this->responseFeed = $feed; | 90 | $this->responseFeed = $feed; |
| 89 | } | 91 | } |
| 90 | 92 | ||
| 93 | + /** | ||
| 94 | + * Deals with folder service POST actions. | ||
| 95 | + * This includes creation of both folders and documents. | ||
| 96 | + */ | ||
| 91 | public function POST_action() | 97 | public function POST_action() |
| 92 | { | 98 | { |
| 93 | $RepositoryService = new RepositoryService(); | 99 | $RepositoryService = new RepositoryService(); |
| @@ -131,23 +137,50 @@ class KT_cmis_atom_service_folder extends KT_atom_service { | @@ -131,23 +137,50 @@ class KT_cmis_atom_service_folder extends KT_atom_service { | ||
| 131 | 137 | ||
| 132 | if ($typeId != 'Unknown') | 138 | if ($typeId != 'Unknown') |
| 133 | { | 139 | { |
| 134 | - /*$f = fopen('c:\kt-stuff\here.txt', 'w'); | ||
| 135 | - fwrite($f, 'fgfgfgfg'); | ||
| 136 | - fclose($f);*/ | ||
| 137 | $this->setStatus(self::STATUS_CREATED); | 140 | $this->setStatus(self::STATUS_CREATED); |
| 138 | $feed = KT_cmis_atom_service_helper::getObjectFeed($ObjectService, $repositoryId, $newObjectId, 'POST'); | 141 | $feed = KT_cmis_atom_service_helper::getObjectFeed($ObjectService, $repositoryId, $newObjectId, 'POST'); |
| 139 | } | 142 | } |
| 140 | - else | ||
| 141 | - { | ||
| 142 | - /*$f = fopen('c:\kt-stuff\failed.txt', 'w'); | ||
| 143 | - fwrite($f, 'fgfgfgfg'); | ||
| 144 | - fclose($f);*/ | 143 | + else { |
| 145 | $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, $newObjectId['message']); | 144 | $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, $newObjectId['message']); |
| 146 | } | 145 | } |
| 147 | 146 | ||
| 148 | //Expose the responseFeed | 147 | //Expose the responseFeed |
| 149 | $this->responseFeed = $feed; | 148 | $this->responseFeed = $feed; |
| 150 | } | 149 | } |
| 150 | + | ||
| 151 | + /** | ||
| 152 | + * Deals with DELETE actions for folders. | ||
| 153 | + * This includes deleting a single folder (with no content) and deleting an entire folder tree | ||
| 154 | + * | ||
| 155 | + * @return 204 on success, 500 on error | ||
| 156 | + */ | ||
| 157 | + public function DELETE_action() | ||
| 158 | + { | ||
| 159 | + // NOTE due to the way KnowledgeTree works with folders this is always going to call deleteTree. | ||
| 160 | + // we COULD call deleteObject but when we delete a folder we expect to be trying to delete | ||
| 161 | + // the folder and all content. | ||
| 162 | + | ||
| 163 | + $RepositoryService = new RepositoryService(); | ||
| 164 | + $ObjectService = new ObjectService(KT_cmis_atom_service_helper::getKt()); | ||
| 165 | + | ||
| 166 | + $repositories = $RepositoryService->getRepositories(); | ||
| 167 | + $repositoryId = $repositories[0]['repositoryId']; | ||
| 168 | + | ||
| 169 | + // attempt delete | ||
| 170 | + $result = $ObjectService->deleteTree($repositoryId, $this->params[0]); | ||
| 171 | + | ||
| 172 | + // error? | ||
| 173 | + if (PEAR::isError($result)) | ||
| 174 | + { | ||
| 175 | + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, $result->getMessage()); | ||
| 176 | + //Expose the responseFeed | ||
| 177 | + $this->responseFeed = $feed; | ||
| 178 | + return null; | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + // success | ||
| 182 | + $this->setStatus(self::STATUS_NO_CONTENT); | ||
| 183 | + } | ||
| 151 | 184 | ||
| 152 | /** | 185 | /** |
| 153 | * Retrieves children/descendants of the specified folder | 186 | * Retrieves children/descendants of the specified folder |
| @@ -217,9 +250,6 @@ class KT_cmis_atom_service_folder extends KT_atom_service { | @@ -217,9 +250,6 @@ class KT_cmis_atom_service_folder extends KT_atom_service { | ||
| 217 | 250 | ||
| 218 | /** | 251 | /** |
| 219 | * AtomPub Service: types | 252 | * AtomPub Service: types |
| 220 | - * | ||
| 221 | - * Returns a list of supported object types | ||
| 222 | - * | ||
| 223 | */ | 253 | */ |
| 224 | class KT_cmis_atom_service_types extends KT_atom_service { | 254 | class KT_cmis_atom_service_types extends KT_atom_service { |
| 225 | 255 | ||
| @@ -241,9 +271,6 @@ class KT_cmis_atom_service_types extends KT_atom_service { | @@ -241,9 +271,6 @@ class KT_cmis_atom_service_types extends KT_atom_service { | ||
| 241 | 271 | ||
| 242 | /** | 272 | /** |
| 243 | * AtomPub Service: type | 273 | * AtomPub Service: type |
| 244 | - * | ||
| 245 | - * Returns the type defintion for the selected type | ||
| 246 | - * | ||
| 247 | */ | 274 | */ |
| 248 | class KT_cmis_atom_service_type extends KT_atom_service { | 275 | class KT_cmis_atom_service_type extends KT_atom_service { |
| 249 | 276 | ||
| @@ -318,13 +345,13 @@ class KT_cmis_atom_service_type extends KT_atom_service { | @@ -318,13 +345,13 @@ class KT_cmis_atom_service_type extends KT_atom_service { | ||
| 318 | 345 | ||
| 319 | /** | 346 | /** |
| 320 | * AtomPub Service: checkedout | 347 | * AtomPub Service: checkedout |
| 321 | - * | ||
| 322 | - * Returns a list of checked out documents for the logged in user | ||
| 323 | - * | ||
| 324 | */ | 348 | */ |
| 325 | // NOTE this is always an empty document, underlying API code still to be implemented | 349 | // NOTE this is always an empty document, underlying API code still to be implemented |
| 326 | class KT_cmis_atom_service_checkedout extends KT_atom_service { | 350 | class KT_cmis_atom_service_checkedout extends KT_atom_service { |
| 327 | - | 351 | + |
| 352 | + /** | ||
| 353 | + * Deals with GET actions for checkedout documents. | ||
| 354 | + */ | ||
| 328 | public function GET_action() | 355 | public function GET_action() |
| 329 | { | 356 | { |
| 330 | $RepositoryService = new RepositoryService(); | 357 | $RepositoryService = new RepositoryService(); |
| @@ -350,7 +377,6 @@ class KT_cmis_atom_service_checkedout extends KT_atom_service { | @@ -350,7 +377,6 @@ class KT_cmis_atom_service_checkedout extends KT_atom_service { | ||
| 350 | // TODO get actual most recent update time, only use current if no other available | 377 | // TODO get actual most recent update time, only use current if no other available |
| 351 | $feed->appendChild($feed->newElement('updated', KT_cmis_atom_service_helper::formatDatestamp())); | 378 | $feed->appendChild($feed->newElement('updated', KT_cmis_atom_service_helper::formatDatestamp())); |
| 352 | 379 | ||
| 353 | -//'urn:uuid:checkedout' | ||
| 354 | foreach($checkedout as $document) | 380 | foreach($checkedout as $document) |
| 355 | { | 381 | { |
| 356 | $entry = $feed->newEntry(); | 382 | $entry = $feed->newEntry(); |
| @@ -380,12 +406,13 @@ class KT_cmis_atom_service_checkedout extends KT_atom_service { | @@ -380,12 +406,13 @@ class KT_cmis_atom_service_checkedout extends KT_atom_service { | ||
| 380 | 406 | ||
| 381 | /** | 407 | /** |
| 382 | * AtomPub Service: document | 408 | * AtomPub Service: document |
| 383 | - * | ||
| 384 | - * Returns detail on a particular document | ||
| 385 | - * | ||
| 386 | */ | 409 | */ |
| 387 | class KT_cmis_atom_service_document extends KT_atom_service { | 410 | class KT_cmis_atom_service_document extends KT_atom_service { |
| 388 | 411 | ||
| 412 | + /** | ||
| 413 | + * Deals with GET actions for documents. | ||
| 414 | + * This includes individual document retrieval | ||
| 415 | + */ | ||
| 389 | public function GET_action() | 416 | public function GET_action() |
| 390 | { | 417 | { |
| 391 | $RepositoryService = new RepositoryService(); | 418 | $RepositoryService = new RepositoryService(); |
| @@ -400,16 +427,48 @@ class KT_cmis_atom_service_document extends KT_atom_service { | @@ -400,16 +427,48 @@ class KT_cmis_atom_service_document extends KT_atom_service { | ||
| 400 | $feed = new KT_cmis_atom_responseFeed_GET(CMIS_APP_BASE_URI); | 427 | $feed = new KT_cmis_atom_responseFeed_GET(CMIS_APP_BASE_URI); |
| 401 | 428 | ||
| 402 | $feed->newField('title', $cmisEntry['properties']['ObjectTypeId']['value'], $feed); | 429 | $feed->newField('title', $cmisEntry['properties']['ObjectTypeId']['value'], $feed); |
| 403 | - $feed->newField('id', 'urn:uuid:' . $cmisEntry['properties']['ObjectId']['value'], $feed); ; | 430 | + $feed->newField('id', 'urn:uuid:' . $cmisEntry['properties']['ObjectId']['value'], $feed); |
| 404 | 431 | ||
| 405 | KT_cmis_atom_service_helper::createObjectEntry($feed, $cmisEntry, $cmisEntry['properties']['ParentId']['value']); | 432 | KT_cmis_atom_service_helper::createObjectEntry($feed, $cmisEntry, $cmisEntry['properties']['ParentId']['value']); |
| 406 | 433 | ||
| 407 | - // <cmis:hasMoreItems>false</cmis:hasMoreItems> | ||
| 408 | - | ||
| 409 | //Expose the responseFeed | 434 | //Expose the responseFeed |
| 410 | $this->responseFeed=$feed; | 435 | $this->responseFeed=$feed; |
| 411 | } | 436 | } |
| 412 | 437 | ||
| 438 | + /** | ||
| 439 | + * Deals with DELETE actions for documents. | ||
| 440 | + * This includes deletion of a specific version of a document (latest version) via deleteObject | ||
| 441 | + * as well as deleteAllVersions | ||
| 442 | + * | ||
| 443 | + * @return 204 on success, 500 on error | ||
| 444 | + */ | ||
| 445 | + public function DELETE_action() | ||
| 446 | + { | ||
| 447 | + // NOTE due to the way KnowledgeTree works with documents this is always going to call deleteAllVersions. | ||
| 448 | + // we do not have support for deleting only specific versions (this may be added in the future.) | ||
| 449 | + | ||
| 450 | + $RepositoryService = new RepositoryService(); | ||
| 451 | + $VersioningService = new VersioningService(KT_cmis_atom_service_helper::getKt()); | ||
| 452 | + | ||
| 453 | + $repositories = $RepositoryService->getRepositories(); | ||
| 454 | + $repositoryId = $repositories[0]['repositoryId']; | ||
| 455 | + | ||
| 456 | + // attempt delete | ||
| 457 | + $result = $VersioningService->deleteAllVersions($repositoryId, $this->params[0]); | ||
| 458 | + | ||
| 459 | + // error? | ||
| 460 | + if (PEAR::isError($result)) | ||
| 461 | + { | ||
| 462 | + $feed = KT_cmis_atom_service_helper::getErrorFeed($this, self::STATUS_SERVER_ERROR, $result->getMessage()); | ||
| 463 | + //Expose the responseFeed | ||
| 464 | + $this->responseFeed = $feed; | ||
| 465 | + return null; | ||
| 466 | + } | ||
| 467 | + | ||
| 468 | + // success | ||
| 469 | + $this->setStatus(self::STATUS_NO_CONTENT); | ||
| 470 | + } | ||
| 471 | + | ||
| 413 | } | 472 | } |
| 414 | 473 | ||
| 415 | ?> | 474 | ?> |
| 416 | \ No newline at end of file | 475 | \ No newline at end of file |
webservice/classes/atompub/KT_atom_service.inc.php
| @@ -2,6 +2,7 @@ | @@ -2,6 +2,7 @@ | ||
| 2 | class KT_atom_service{ | 2 | class KT_atom_service{ |
| 3 | const STATUS_OK = '200 OK'; | 3 | const STATUS_OK = '200 OK'; |
| 4 | const STATUS_NOT_FOUND = '204 No Content'; | 4 | const STATUS_NOT_FOUND = '204 No Content'; |
| 5 | + const STATUS_NO_CONTENT = '204 No Content'; | ||
| 5 | const STATUS_NOT_ALLOWED = '204 Not Allowed'; | 6 | const STATUS_NOT_ALLOWED = '204 Not Allowed'; |
| 6 | const STATUS_CREATED = '201 Created'; | 7 | const STATUS_CREATED = '201 Created'; |
| 7 | const STATUS_UPDATED = '200 Updated'; | 8 | const STATUS_UPDATED = '200 Updated'; |
webservice/classes/atompub/cmis/ObjectService.inc.php
| @@ -26,8 +26,7 @@ class ObjectService extends KTObjectService { | @@ -26,8 +26,7 @@ class ObjectService extends KTObjectService { | ||
| 26 | $result = parent::getProperties($repositoryId, $objectId, $includeAllowableActions, | 26 | $result = parent::getProperties($repositoryId, $objectId, $includeAllowableActions, |
| 27 | $returnVersion, $filter); | 27 | $returnVersion, $filter); |
| 28 | 28 | ||
| 29 | - if ($result['status_code'] == 0) | ||
| 30 | - { | 29 | + if ($result['status_code'] == 0) { |
| 31 | return $result['results']; | 30 | return $result['results']; |
| 32 | } | 31 | } |
| 33 | } | 32 | } |
| @@ -45,12 +44,10 @@ class ObjectService extends KTObjectService { | @@ -45,12 +44,10 @@ class ObjectService extends KTObjectService { | ||
| 45 | { | 44 | { |
| 46 | $result = parent::createFolder($repositoryId, $typeId, $properties, $folderId); | 45 | $result = parent::createFolder($repositoryId, $typeId, $properties, $folderId); |
| 47 | 46 | ||
| 48 | - if ($result['status_code'] == 0) | ||
| 49 | - { | 47 | + if ($result['status_code'] == 0) { |
| 50 | return $result['results']; | 48 | return $result['results']; |
| 51 | } | 49 | } |
| 52 | - else | ||
| 53 | - { | 50 | + else { |
| 54 | return $result; | 51 | return $result; |
| 55 | } | 52 | } |
| 56 | } | 53 | } |
| @@ -75,15 +72,57 @@ class ObjectService extends KTObjectService { | @@ -75,15 +72,57 @@ class ObjectService extends KTObjectService { | ||
| 75 | { | 72 | { |
| 76 | $result = parent::createDocument($repositoryId, $typeId, $properties, $folderId, $contentStream, $versioningState); | 73 | $result = parent::createDocument($repositoryId, $typeId, $properties, $folderId, $contentStream, $versioningState); |
| 77 | 74 | ||
| 78 | - if ($result['status_code'] == 0) | ||
| 79 | - { | 75 | + if ($result['status_code'] == 0) { |
| 80 | return $result['results']; | 76 | return $result['results']; |
| 81 | } | 77 | } |
| 82 | - else | ||
| 83 | - { | 78 | + else { |
| 84 | return $result; | 79 | return $result; |
| 85 | } | 80 | } |
| 86 | } | 81 | } |
| 82 | + | ||
| 83 | + /** | ||
| 84 | + * Deletes an object from the repository | ||
| 85 | + * | ||
| 86 | + * @param string $repositoryId | ||
| 87 | + * @param string $objectId | ||
| 88 | + * @param string $changeToken [optional] | ||
| 89 | + * @return boolean true on success, false on failure | ||
| 90 | + */ | ||
| 91 | + // NOTE Invoking this service method on an object SHALL not delete the entire version series for a Document Object. | ||
| 92 | + // To delete an entire version series, use the deleteAllVersions() service | ||
| 93 | + function deleteObject($repositoryId, $objectId, $changeToken = null) | ||
| 94 | + { | ||
| 95 | + $result = parent::deleteObject($repositoryId, $objectId, $changeToken); | ||
| 96 | + | ||
| 97 | + if ($result['status_code'] == 0) { | ||
| 98 | + return $result['results']; | ||
| 99 | + } | ||
| 100 | + else { | ||
| 101 | + return new PEAR_Error($result['message']); | ||
| 102 | + } | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + /** | ||
| 106 | + * Deletes an entire tree including all subfolders and other filed objects | ||
| 107 | + * | ||
| 108 | + * @param string $repositoryId | ||
| 109 | + * @param string $objectId | ||
| 110 | + * @param string $changeToken [optional] | ||
| 111 | + * @param boolean $unfileNonfolderObject [optional] - note that since KnowledgeTree does not allow unfiling this will be ignored | ||
| 112 | + * @param boolean $continueOnFailure [optional] - note that since KnowledgeTree does not allow continue on failure this will be ignored | ||
| 113 | + * @return array $failedToDelete A list of identifiers of objects in the folder tree that were not deleted. | ||
| 114 | + */ | ||
| 115 | + public function deleteTree($repositoryId, $objectId, $changeToken = null, $unfileNonfolderObject = 'delete', $continueOnFailure = false) | ||
| 116 | + { | ||
| 117 | + $result = parent::deleteTree($repositoryId, $objectId, $changeToken, $unfileNonfolderObject, $continueOnFailure); | ||
| 118 | + | ||
| 119 | + if ($result['status_code'] == 0) { | ||
| 120 | + return $result['results']; | ||
| 121 | + } | ||
| 122 | + else { | ||
| 123 | + return new PEAR_Error($result['message']); | ||
| 124 | + } | ||
| 125 | + } | ||
| 87 | 126 | ||
| 88 | } | 127 | } |
| 89 | 128 |
webservice/classes/atompub/cmis/VersioningService.inc.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +require_once KT_LIB_DIR . '/api/ktcmis/ktcmis.inc.php'; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * CMIS Service class which hooks into the KnowledgeTree interface | ||
| 7 | + * for processing of CMIS queries and responses via atompub/webservices | ||
| 8 | + */ | ||
| 9 | + | ||
| 10 | +class VersioningService extends KTVersioningService { | ||
| 11 | + | ||
| 12 | + /** | ||
| 13 | + * Deletes all Document Objects in the specified Version Series, including the Private Working Copy | ||
| 14 | + * | ||
| 15 | + * @param string $repositoryId | ||
| 16 | + * @param string $versionSeriesId | ||
| 17 | + * @return boolean true if successful | ||
| 18 | + */ | ||
| 19 | + public function deleteAllVersions($repositoryId, $versionSeriesId) | ||
| 20 | + { | ||
| 21 | + $result = parent::deleteAllVersions($repositoryId, $versionSeriesId); | ||
| 22 | + | ||
| 23 | + if ($result['status_code'] == 0) { | ||
| 24 | + return $result['results']; | ||
| 25 | + } | ||
| 26 | + else { | ||
| 27 | + return new PEAR_Error($result['message']); | ||
| 28 | + } | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | +} | ||
| 32 | + | ||
| 33 | +?> |