Reputation: 13
I'm using the Apache Chemistry CMIS PHP client to upload documents from a local folder to Alfresco Community Edition 5.1 via ATOM. Here's the script I'm using to do so:
require_once ('cmis_repository_wrapper.php');
require_once ('cmis_service.php');
$repo_url = "http://127.0.0.1:8080/alfresco/api/-default-/public/cmis/versions/1.1/atom";
$repo_username = "user";
$repo_password = "pass";
$client = new CMISService($repo_url, $repo_username, $repo_password);
$repo_folder = "/alfrescoFolder";
$source_folder = "localFolder/";
$source_files = array_diff(scandir("$source_folder", 1), array('..', '.'));
$myfolder = $client->getObjectByPath($repo_folder);
foreach($source_files as $file)
{
try
{
$upload = $client->createDocumentFromSource($myfolder->id, $file, "$source_folder/$file");
}
catch(Exception $e)
{
echo "Some error here.";
}
}
This script works fine and documents are uploaded without problem, provided that the document doesn't already exist in the Alfresco repository. For example, let's say I have a document in my Alfresco repository named example.txt
, and so, if I try to upload a document from my local folder with the same name, I get a CMIS constraint exception. I dont't know how I can upload a new version of an existing document.
This is what I've tried so far, but it doesn't work:
$objs = $client->getChildren($myfolder->id);
foreach($source_files as $file)
{
foreach($objs->objectList as $obj)
{
if($obj->properties['cmis:name'] == $file)
{
try
{
$checkedout = $client->checkOut($obj->id);
$client->checkIn($checkedout->id);
}
catch(Exception $e)
{
echo "Some error here.";
}
}
else
{
try
{
$upload = $client->createDocumentFromSource($myfolder->id, $file, "$source_folder/$file", array('cmis:objectTypeId'=>'D:ex:document'));
}
catch(Exception $e)
{
echo "Some error here";
}
}
}
}
I get this error:
DEBUG: postEntry: myURL = http://127.0.0.1:8080/alfresco/api/-default-/public/cmis/versions/1.1/atom/checkedoutDEBUG: postEntry: entry_template = {title} {SUMMARY} {CONTENT} {PROPERTIES} DEBUG: postEntry: properties_xml = b549c715-9a9d-427c-bd4b-c6ea29d222cb;1.0 DEBUG: postEntry: hash_values = Array ( [PROPERTIES] => b549c715-9a9d-427c-bd4b-c6ea29d222cb;1.0 [SUMMARY] => {summary} ) DEBUG: postEntry: post_value = b549c715-9a9d-427c-bd4b-c6ea29d222cb;1.0
What's funny is that the document is in fact locked for editing, so I don't really know what's going on. I also don't know if checking out and then checking in a document is how I'm supposed to version a document.
TL;DR
I want to be able to specify that the document I'm uploading is a new version of an existing document. Does anyone know how I can do that?
Upvotes: 0
Views: 1590
Reputation: 13
I've recently found out about an alternative CMIS PHP library that implements versioning services, including example usage. I've used it to successfully solve the problem I posted in my question.
Edit: additional information added.
So, to get versioning working, I used the example code provided in the library. The script I used can be used to create new documents and to update and version existing documents. So, here it is:
<?php
require_once(__DIR__ . '/../vendor/autoload.php');
if (!is_file(__DIR__ . '/conf/Configuration.php')) {
die("Please add your connection credentials to the file \"" . __DIR__ . "/conf/Configuration.php\".\n");
} else {
require_once(__DIR__ . '/conf/Configuration.php');
}
$major = (boolean) isset($argv[1]) ? $argv[1] : false;
$httpInvoker = new \GuzzleHttp\Client(
array(
'defaults' => array(
'auth' => array(
CMIS_BROWSER_USER,
CMIS_BROWSER_PASSWORD
)
)
)
);
$parameters = array(
\Dkd\PhpCmis\SessionParameter::BINDING_TYPE => \Dkd\PhpCmis\Enum\BindingType::BROWSER,
\Dkd\PhpCmis\SessionParameter::BROWSER_URL => CMIS_BROWSER_URL,
\Dkd\PhpCmis\SessionParameter::BROWSER_SUCCINCT => false,
\Dkd\PhpCmis\SessionParameter::HTTP_INVOKER_OBJECT => $httpInvoker,
);
$sessionFactory = new \Dkd\PhpCmis\SessionFactory();
// If no repository id is defined use the first repository
if (CMIS_REPOSITORY_ID === null) {
$repositories = $sessionFactory->getRepositories($parameters);
$repositoryId = $repositories[0]->getId();
} else {
$repositoryId = CMIS_REPOSITORY_ID;
}
$parameters[\Dkd\PhpCmis\SessionParameter::REPOSITORY_ID] = $repositoryId;
$session = $sessionFactory->createSession($parameters);
$rootFolder = $session->getObject($session->createObjectId($session->getRootFolder()->getId()));
try {
$document = null;
$stream = \GuzzleHttp\Stream\Stream::factory(fopen($filePath, 'r'));
foreach ($rootFolder->getChildren() as $child) {
if ($child->getName() === $fileName) {
$document = $child;
break;
}
}
if (!$document) {
$properties = array(
\Dkd\PhpCmis\PropertyIds::OBJECT_TYPE_ID => 'cmis:document',
\Dkd\PhpCmis\PropertyIds::NAME => $fileName
);
$document = $session->createDocument($properties, $rootFolder, $stream);
$document = $session->getObject($document);
}
$checkedOutDocumentId = $document->getVersionSeriesCheckedOutId();
if ($checkedOutDocumentId) {
$checkedOutDocumentId = $session->createObjectId($checkedOutDocumentId);
} else {
$checkedOutDocumentId = $document->checkOut();
}
$checkedInDocumentId = $session->getObject($checkedOutDocumentId)->checkIn(
$major,
array(
\Dkd\PhpCmis\PropertyIds::DESCRIPTION => 'New description'
),
$stream,
'Comments'
);
} catch (\Dkd\PhpCmis\Exception\CmisVersioningException $e) {
echo "********* ERROR **********\n";
echo $e->getMessage() . "\n";
echo "**************************\n";
exit();
}
Upvotes: 1
Reputation: 10538
The function coverage page on the Apache Chemistry web site lists what the CMIS PHP client can and cannot do. Check out, check in, and cancel checkout are all unsupported at the present time. I know they would welcome contributions.
The underlying CMIS specification supports it, of course, so you can either update the library to support checkout/checkin or use the raw binding.
Upvotes: 1
Reputation: 1845
I'm not an expert on CMIS, but I think that this forum post answers the question. See the answer from "jevon" that provides an example and a link to this page (see the "Updating a document" section)
Upvotes: 1