public function moveObject($repositoryId, $objectId, $changeToken = '', $targetFolderId, $sourceFolderId = null) { // The $sourceFolderId parameter SHALL be specified if the Repository supports the optional 'unfiling' capability if (is_null($sourceFolderId)) { $RepositoryService = new CMISRepositoryService(); $info = $RepositoryService->getRepositoryInfo($repositoryId); $capabilities = $info->getCapabilities(); // check for unfiling capability // NOTE this is only required once/if KnowledgeTree allows the source folder id to be optional, // but it is required for CMIS specification compliance. if ($capabilities->hasCapabilityUnfiling() === 'true') { throw new RuntimeException('The source folder id MUST be supplied when unfiling is supported.'); } } // Attempt to decode $objectId, use as is if not detected as encoded $tmpObjectId = $objectId; $tmpObjectId = CMISUtil::decodeObjectId($tmpObjectId, $typeId); if ($tmpTypeId != 'Unknown') { $objectId = $tmpObjectId; } $targetFolderId = CMISUtil::decodeObjectId($targetFolderId); // check type id of object against allowed child types for destination folder $CMISFolder = new CMISFolderObject($targetFolderId, $this->ktapi); $allowed = $CMISFolder->getProperty('AllowedChildObjectTypeIds'); if (!is_array($allowed) || !in_array($typeId, $allowed)) { throw new ConstraintViolationException('Parent folder may not hold objects of this type (' . $typeId . ')'); } // throw updateConflictException if the operation is attempting to update an object that is no longer current (as determined by the repository). $exists = CMISUtil::contentExists($typeId, $objectId, $this->ktapi); if (!$exists) { throw new updateConflictException('Unable to move the object as it cannot be found.'); } // TODO add reasons and sig data // attempt to move object if ($typeId == 'Folder') { $response = $this->ktapi->move_folder($objectId, $targetFolderId, $reason, $sig_username, $sig_password); } else { if ($typeId == 'Document') { $response = $this->ktapi->move_document($objectId, $targetFolderId, $reason, null, null, $sig_username, $sig_password); } else { $response['status_code'] = 1; $response['message'] = 'The object type could not be determined.'; } } // if failed, throw StorageException if ($response['status_code'] != 0) { throw new StorageException('The repository was unable to move the object: ' . $response['message']); } }
/** * Decodes the identifier created by encodeObjectId to return an object type * and a system useable ID * * The decoded object ID is returned by reference via the argument list * * @param string $objectId * @param string &$typeId * @return string $objectId */ public static function decodeObjectId($objectId, &$typeId = null) { if (!is_string($objectId)) { $typeId = 'Unknown'; return null; } $typeId = null; // NOTE Not sure whether this really belongs here, but probably this is the safest and most reliable place // If we find that the folderId is in fact the name of the repository root folder, we will not be able to // decode it, but we still need to return a valid id :). This is because the root folder name is returned // by the repository configuration rather than the actual CMIS folder id. // TODO consider just setting F1 as the root in the config? Originally didn't based on Alfresco, but... $RepositoryService = new CMISRepositoryService(); $repositories = $RepositoryService->getRepositories(); $repositoryInfo = $repositories[0]->getRepositoryInfo(); // the string replace is a hack for the drupal module, yay... if ($repositoryInfo->getRootFolderId() == urldecode(str_replace('%2520', '%20', $objectId))) { // NOTE that we may want to check the KnowledgeTree (not CMIS) repository for the root folder id. // This will be vital if we ever implement a way for people to have multiple roots depending // on who is logged in or what they select. Obviously the CMIS API in general will need a // method of doing this. // meantime this minor hack will get things working for the existing system structure, as the root // folder should always be id 1. $typeId = 'Folder'; return '1'; } preg_match('/(\\D)(\\d*)/', $objectId, $matches); $type = $matches[1]; $objectId = $matches[2]; switch ($type) { case 'D': $typeId = 'Document'; break; case 'F': $typeId = 'Folder'; break; default: $typeId = 'Unknown'; break; } return $objectId; }
public function checkIn($repositoryId, $documentId, $major, $contentStream = null, $changeToken = '', $properties = array(), $checkinComment = '') { $documentId = CMISUtil::decodeObjectId($documentId, $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($documentId, $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 ($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); $response = $this->ktapi->checkin_document($documentId, $pwc->getProperty('ContentStreamFilename'), $reason, $tempfilename, $major, $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 checking in the document: ' . $response['message']); } return CMISUtil::encodeObjectId(DOCUMENT, $documentId); }