ktapi = $ktapi; } /** * Deletes all Document Objects in the specified Version Series, including the Private Working Copy if it exists * * @param string $repositoryId * @param string $versionSeriesId * @return boolean true if successful */ // NOTE For KnowledgeTree the $versionSeriesId should be the latest version, if not it will be taken as implied. // Should we decide to implement the ability to delete individual versions, // then an exception may be thrown under certain circumstances (to be determined) // NOTE I am not really sure how this is going to be handled by CMIS clients. // Testing with CMISSpaces we have it sending the actual document id, not a version series id. // This may be due to the data sent back from our code, or it may just be how CMISSpaces does it. // There is a note in their source code about this. // Meantime we will try based on document id and adjust as needed later public function deleteAllVersions($repositoryId, $versionSeriesId) { // attempt to delete based on versionSeriesId as document/object id // determine object type and internal id $objectId = CMISUtil::decodeObjectId($versionSeriesId, $typeId); // if not a versionable object, throw exception // NOTE that we are assuming only documents are versionable at the moment if ($typeId != 'Document') { throw new RuntimeException('The object type is not versionable and cannot be deleted using deleteAllVersions.'); } // try to delete // TODO add a default reason // TODO add the electronic signature capability $auth_sig = true; $result = $this->ktapi->delete_document($objectId, $reason, $auth_sig, $sig_username, $sig_password); // TODO delete any PWC which may exist (NOTE added 24 August 2009 - we did not have any PWC functionality when this function was originally created) // if there was an error performing the delete, throw exception if ($result['status_code'] == 1) { throw new RuntimeException('There was an error deleting the object: ' . $result['message']); } return true; } /** * Checks out a document and creates the PWC (Private Working Copy) which will represent the checked out document * * @param string $repositoryId * @param string $objectId * @return string $objectId The id of the PWC object * @return boolean $contentCopied TRUE if contentStream is a copy of the document content stream, FALSE if contentStream not set */ // NOTE since we need to return two values, we return one via argument by reference // since $objectId already exists in the argument list, that was chosen as the "return by reference" value // TODO set up delivery of content stream? or is that up to the CMIS client? public function checkOut($repositoryId, &$objectId) { $contentCopied = false; $objectId = CMISUtil::decodeObjectId($objectId, $typeId); // NOTE We are not planning on persisting the PWC beyond the current session, it will be re-created on access of the checked out document // TODO consider persisting in the database? How will this relate to JSR if we are switching to that? // NOTE within the current system it is assumed if a new document metadata version is created that this is the latest version of the document // TODO see if there is an easy way to modify this, else we may not have an easy way to persist PWC objects // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository). try { $pwc = new CMISDocumentObject($objectId, $this->ktapi); } catch (exception $e) { throw new UpdateConflictException($e->getMessage()); } // throw exception if the object is not versionable if (!$pwc->getAttribute('versionable')) { throw new ConstraintViolationException('This document is not versionable and may not be checked out'); } // check that this is the latest version if ($pwc->getProperty('isLatestVersion') != true) { throw new VersioningException('The document is not the latest version and cannot be checked out'); } // NOTE KTAPI as currently implemented does not give a direct response which indicates if the document is already checked out, // as long as the same user is calling the checkout again, so should we add a check here specifically? // run checkout process - set $download = false (third function argument) as we want to return the document content via the contentStream $response = $this->ktapi->checkout_document($objectId, 'CMIS Checkout Action', false, $sig_username, $sig_password); // if there was an error, throw an exception if ($response['status_code'] == 1) { throw new StorageException($response['message']); } // if successful, set $contentCopied = true; unless contentStream is not set if ($pwc->getProperty('contentStreamFilename') != '') { $contentCopied = true; } $objectId = CMISUtil::encodeObjectId(DOCUMENT, $objectId); // mark document object as checked out $pwc->setProperty('isVersionSeriesCheckedOut', true); $userName = ''; $user = $this->ktapi->get_user(); if (!PEAR::isError($user)) { $userName = $user->getName(); } $pwc->setProperty('versionSeriesCheckedOutBy', $userName); $pwc->setProperty('versionSeriesCheckedOutId', $objectId); return $contentCopied; } /** * Reverses the effect of a checkout: I.E. deletes the PWC (Private Working Copy) and re-sets the status of the document to "not checked out" * * @param string $repositoryId * @param string $objectId */ // TODO exceptions: // • versioningException - The repository MAY throw this exception if the object is a non-current Document Version. public function cancelCheckOut($repositoryId, $objectId) { $objectId = CMISUtil::decodeObjectId($objectId, $typeId); /* re-generate PWC object */ // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository). try { $pwc = new CMISDocumentObject($objectId, $this->ktapi); } catch (exception $e) { throw new UpdateConflictException($e->getMessage()); } // throw exception if the object is not versionable if (!$pwc->getAttribute('versionable')) { throw new ConstraintViolationException('This document is not versionable and may not be checked out'); } // check that this is the latest version if ($pwc->getProperty('isLatestVersion') != true) { throw new VersioningException('The document is not the latest version'); } // TODO delete PWC - since we are not persisting the PWC this is not necessary at the moment // cancel checkout $response = $this->ktapi->undo_document_checkout($objectId, 'CMIS Cancel Checkout Action', $sig_username, $sig_password); // if there was any error in cancelling the checkout if ($response['status_code'] == 1) { throw new RuntimeException('There was an error cancelling the checkout: ' . $response['message']); } } /** * Checks in a checked out document * * @param string $repositoryId * @param string $objectId * @param boolean $major [optional] defaults to true * @param array $properties [optional] * @param contentStream $contentStream [optional] * @param string $checkinComment [optional] * @param array $policies * @param array $addACEs * @param array $removeACEs * @return string $objectId */ // NOTE For repositories that do NOT support the optional “capabilityPWCUpdatable” capability, the properties // and contentStream input parameters MUST be provided on the checkIn method for updates to happen as part // of checkIn. // NOTE Only those properties whose values are different than the original value of the object need to be submitted. // NOTE we are not actually doing anything with the properties at this time, only the content stream // TODO filename changes and anything else supported in web interface, possibly additional supported by CMIS clients public function checkIn($repositoryId, $objectId, $major = true, $properties = array(), $contentStream = null, $checkinComment = '', $policies = array(), $addACEs = array(), $removeACEs = array()) { $objectId = CMISUtil::decodeObjectId($objectId, $typeId); // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository). try { $pwc = new CMISDocumentObject($objectId, $this->ktapi); } catch (exception $e) { throw new UpdateConflictException($e->getMessage()); } // throw exception if the object is not versionable if (!$pwc->getAttribute('versionable')) { throw new ConstraintViolationException('This document is not versionable and may not be checked in'); } $RepositoryService = new CMISRepositoryService(); try { $typeDefinition = $RepositoryService->getTypeDefinition($repositoryId, $typeId); } catch (exception $e) { // if we can't get the type definition, then we can't store the content throw new StorageException($e->getMessage()); } // if content stream is required (capabilityPWCUpdatability == false) and no content stream is supplied, // throw a ConstraintViolationException if (($typeDefinition['attributes']['contentStreamAllowed'] == 'required') && is_null($contentStream)) { throw new RuntimeException('This repository requires a content stream for document update on checkin. ' . 'Refusing to checkin an empty document'); } else if (($typeDefinition['attributes']['contentStreamAllowed'] == 'notAllowed') && !empty($contentStream)) { throw new StreamNotSupportedException('Content Streams are not supported'); } // check that this is the latest version if ($pwc->getProperty('isLatestVersion') != true) { throw new VersioningException('The document is not the latest version and cannot be checked in'); } // now do the checkin $tempfilename = CMISUtil::createTemporaryFile($contentStream); $reason = 'CMIS object checkin'; $response = $this->ktapi->checkin_document($objectId, $pwc->getProperty('contentStreamFilename'), $reason, $tempfilename, $major, $sig_username, $sig_password); // if there was any error checking in if ($response['status_code'] == 1) { throw new RuntimeException('There was an error checking in the document: ' . $response['message']); } return CMISUtil::encodeObjectId(DOCUMENT, $objectId); } } ?>