git-svn-id: https://192.168.0.254/svn/Proyectos.Incam_SGD/tags/3.7.0.2_original@1 eb19766c-00d9-a042-a3a0-45cb8ec72764
651 lines
29 KiB
PHP
651 lines
29 KiB
PHP
<?php
|
|
|
|
// initialise ktapi instance
|
|
KT_cmis_atom_service_helper::$ktapi = KT_cmis_atom_service_helper::getKt();
|
|
|
|
class KT_cmis_atom_service_helper {
|
|
|
|
public static $ktapi = null;
|
|
public static $repositoryId = null;
|
|
|
|
/**
|
|
* Helper function to set internal repository id
|
|
*
|
|
* @param object $RepositoryService
|
|
*/
|
|
static public function setRepositoryId(&$RepositoryService = null)
|
|
{
|
|
if (is_null($RepositoryService)) {
|
|
$RepositoryService = new RepositoryService();
|
|
}
|
|
|
|
$repositories = $RepositoryService->getRepositories();
|
|
|
|
// TODO handle multiple repositories
|
|
self::$repositoryId = $repositories[0]['repositoryId'];
|
|
}
|
|
|
|
/**
|
|
* Helper function to fetch internal repository id
|
|
*
|
|
* Calls set function automatically, use $set = false to prevent this and return the current setting, if any
|
|
*
|
|
* NOTE the function will automatically call the setRepositoryId function if no previous repository id was set
|
|
*
|
|
* @param object $RepositoryService
|
|
* @param boolean $RepositoryService
|
|
* @return string
|
|
*/
|
|
static public function getRepositoryId(&$RepositoryService = null, $set = true)
|
|
{
|
|
if (empty(self::$repositoryId) || $set) {
|
|
self::setRepositoryId($RepositoryService);
|
|
}
|
|
|
|
return self::$repositoryId;
|
|
}
|
|
|
|
/**
|
|
* Retrieves data about a specific folder OR document within a folder
|
|
*
|
|
* @param object $ObjectService The CMIS service
|
|
* @param string $repositoryId
|
|
* @param string $folderId
|
|
* @return string CMIS AtomPub feed
|
|
*/
|
|
static public function getObjectFeed(&$service, $ObjectService, $repositoryId, $objectId, $method = 'GET')
|
|
{
|
|
self::$repositoryId = $repositoryId;
|
|
|
|
$serviceType = $service->getServiceType();
|
|
$response = $ObjectService->getProperties($repositoryId, $objectId, false, false);
|
|
|
|
if (PEAR::isError($response)) {
|
|
return KT_cmis_atom_service_helper::getErrorFeed($service, KT_cmis_atom_service::STATUS_SERVER_ERROR, $response->getMessage());
|
|
}
|
|
|
|
$cmisEntry = $response;
|
|
$response = null;
|
|
|
|
// POST/PWC responses only send back an entry, not a feed
|
|
if (($serviceType == 'PWC') || ($method == 'POST')) {
|
|
if ($method == 'POST') {
|
|
$response = new KT_cmis_atom_response_POST(CMIS_APP_BASE_URI);
|
|
}
|
|
else {
|
|
$response = new KT_cmis_atom_response_GET(CMIS_APP_BASE_URI);
|
|
}
|
|
}
|
|
else if ($method == 'GET') {
|
|
$response = new KT_cmis_atom_responseFeed_GET(CMIS_APP_BASE_URI);
|
|
$response->newField('title', $cmisEntry['properties']['ObjectTypeId']['value'], $response);
|
|
$response->newField('id', 'urn:uuid:' . $cmisEntry['properties']['ObjectId']['value'], $response);
|
|
}
|
|
|
|
if ($serviceType == 'PWC') $pwc = true; else $pwc = false;
|
|
KT_cmis_atom_service_helper::createObjectEntry($response, $cmisEntry, $cmisEntry['properties']['ParentId']['value'], $pwc, $method);
|
|
|
|
// Don't think this should be here...only one item so why would we need to say there are no more?
|
|
/*if ($method == 'GET') {
|
|
$response->newField('cmis:hasMoreItems', 'false', $response);
|
|
}*/
|
|
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* Creates an AtomPub entry for a CMIS entry and adds it to the supplied feed
|
|
*
|
|
* @param object $feed The feed to which we add the entry
|
|
* @param array $cmisEntry The entry data
|
|
* @param string $parent The parent folder
|
|
*/
|
|
static public function createObjectEntry(&$response, $cmisEntry, $parent, $pwc = false, $method = 'GET')
|
|
{
|
|
$workspace = $response->getWorkspace();
|
|
$type = strtolower($cmisEntry['properties']['ObjectTypeId']['value']);
|
|
|
|
// create entry
|
|
$entry = $response->newEntry();
|
|
|
|
// FIXME this maybe belongs in the response feed class only how?
|
|
if (($method == 'POST') || $pwc)
|
|
{
|
|
// append attributes
|
|
$entry->appendChild($response->newAttr('xmlns', 'http://www.w3.org/2005/Atom'));
|
|
$entry->appendChild($response->newAttr('xmlns:app', 'http://www.w3.org/2007/app'));
|
|
$entry->appendChild($response->newAttr('xmlns:cmis', 'http://docs.oasis-open.org/ns/cmis/core/200901'));
|
|
}
|
|
|
|
// TODO dynamic actual creator name
|
|
$responseElement = $response->newField('author');
|
|
$element = $response->newField('name', 'admin', $responseElement);
|
|
$entry->appendChild($responseElement);
|
|
|
|
if (!empty($cmisEntry['properties']['ContentStreamLength']['value']))
|
|
{
|
|
$field = $response->newElement('content');
|
|
$field->appendChild($response->newAttr('type', $cmisEntry['properties']['ContentStreamMimeType']['value']));
|
|
$field->appendChild($response->newAttr('src', CMIS_APP_BASE_URI . $workspace . '/' . $type
|
|
. '/' . $cmisEntry['properties']['ObjectId']['value']
|
|
. '/' . $cmisEntry['properties']['ContentStreamFilename']['value']));
|
|
$entry->appendChild($field);
|
|
}
|
|
|
|
// content & id tags
|
|
$id = $cmisEntry['properties']['ObjectId']['value'];
|
|
|
|
$response->newField('id', 'urn:uuid:' . $id, $entry);
|
|
|
|
// links
|
|
$link = $response->newElement('link');
|
|
$link->appendChild($response->newAttr('rel', 'self'));
|
|
$link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . (!$pwc ? $type : 'pwc') . '/'
|
|
. $cmisEntry['properties']['ObjectId']['value']));
|
|
$entry->appendChild($link);
|
|
|
|
$link = $response->newElement('link');
|
|
$link->appendChild($response->newAttr('rel', 'edit'));
|
|
$link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type
|
|
. '/' . $cmisEntry['properties']['ObjectId']['value']));
|
|
$entry->appendChild($link);
|
|
|
|
if ((strtolower($cmisEntry['properties']['ObjectTypeId']['value']) == 'document')
|
|
&& (!empty($cmisEntry['properties']['ContentStreamLength']['value'])))
|
|
{
|
|
$link = $response->newElement('link');
|
|
$link->appendChild($response->newAttr('rel', 'edit-media'));
|
|
$link->appendChild($response->newAttr('type', $cmisEntry['properties']['ContentStreamMimeType']['value']));
|
|
$link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type
|
|
. '/' . $cmisEntry['properties']['ObjectId']['value']
|
|
. '/' . $cmisEntry['properties']['ContentStreamFilename']['value']));
|
|
$entry->appendChild($link);
|
|
|
|
$link = $response->newElement('link');
|
|
$link->appendChild($response->newAttr('rel', 'enclosure'));
|
|
$link->appendChild($response->newAttr('type', $cmisEntry['properties']['ContentStreamMimeType']['value']));
|
|
$link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type
|
|
. '/' . $cmisEntry['properties']['ObjectId']['value']
|
|
. '/' . $cmisEntry['properties']['ContentStreamFilename']['value']));
|
|
$entry->appendChild($link);
|
|
}
|
|
|
|
// according to spec this MUST be present, but spec says that links for function which are not supported
|
|
// do not need to be present, so unsure for the moment
|
|
$link = $response->newElement('link');
|
|
$link->appendChild($response->newAttr('rel', 'allowableactions'));
|
|
$link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/'
|
|
. $cmisEntry['properties']['ObjectId']['value'] . '/permissions'));
|
|
$entry->appendChild($link);
|
|
|
|
// according to spec this MUST be present, but spec says that links for function which are not supported
|
|
// do not need to be present, so unsure for the moment
|
|
$link = $response->newElement('link');
|
|
$link->appendChild($response->newAttr('rel', 'relationships'));
|
|
$link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/'
|
|
. $cmisEntry['properties']['ObjectId']['value'] . '/rels'));
|
|
$entry->appendChild($link);
|
|
|
|
// if there is no parent or parent is 0, do not add the parent link
|
|
// also if this is specifically the root folder, do not add the parent link
|
|
// if (!empty($cmisEntry['properties']['ParentId']['value']) && !CMISUtil::isRootFolder(self::$repositoryId, $cmisEntry['properties']['ObjectId']['value']))
|
|
|
|
if (!CMISUtil::isRootFolder(self::$repositoryId, $cmisEntry['properties']['ObjectId']['value'], self::$ktapi))
|
|
{
|
|
// TODO check parent link is correct, fix if needed
|
|
$link = $response->newElement('link');
|
|
$link->appendChild($response->newAttr('rel', 'parents'));
|
|
$link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/folder/'
|
|
. $cmisEntry['properties']['ObjectId']['value'] . '/parent'));
|
|
$entry->appendChild($link);
|
|
}
|
|
|
|
// Folder/Document specific links
|
|
if (strtolower($cmisEntry['properties']['ObjectTypeId']['value']) == 'folder')
|
|
{
|
|
$link = $response->newElement('link');
|
|
$link->appendChild($response->newAttr('rel', 'children'));
|
|
$link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/'
|
|
. $type
|
|
. '/' . $cmisEntry['properties']['ObjectId']['value']
|
|
. '/children'));
|
|
$entry->appendChild($link);
|
|
$link = $response->newElement('link');
|
|
$link->appendChild($response->newAttr('rel', 'descendants'));
|
|
$link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/'
|
|
. $type
|
|
. '/' . $cmisEntry['properties']['ObjectId']['value']
|
|
. '/descendants'));
|
|
$entry->appendChild($link);
|
|
}
|
|
else if (strtolower($cmisEntry['properties']['ObjectTypeId']['value']) == 'document')
|
|
{
|
|
// according to spec this MUST be present, but spec says that links for function which are not supported
|
|
// do not need to be present, so unsure for the moment
|
|
// $link = $response->newElement('link');
|
|
// $link->appendChild($response->newAttr('rel', 'allversions'));
|
|
// $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/' . $cmisEntry['properties']['ParentId']['value']));
|
|
// $entry->appendChild($link);
|
|
|
|
// according to spec this MUST be present, but spec says that links for function which are not supported
|
|
// do not need to be present, so unsure for the moment
|
|
// $link = $response->newElement('link');
|
|
// $link->appendChild($response->newAttr('rel', 'latestversion'));
|
|
// $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/' . $cmisEntry['properties']['ParentId']['value']));
|
|
// $entry->appendChild($link);
|
|
|
|
// if there is a content stream, this link MUST be present
|
|
// not sure yet where it must point...
|
|
if (!empty($cmisEntry['properties']['ContentStreamLength']['value']))
|
|
{
|
|
$link = $response->newElement('link');
|
|
$link->appendChild($response->newAttr('rel', 'stream'));
|
|
$link->appendChild($response->newAttr('type', $cmisEntry['properties']['ContentStreamMimeType']['value']));
|
|
$link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type
|
|
. '/' . $cmisEntry['properties']['ObjectId']['value']
|
|
. '/' . $cmisEntry['properties']['ContentStreamFilename']['value']));
|
|
$entry->appendChild($link);
|
|
}
|
|
|
|
// if the document is checked out and this is NOT the PWC, this link MUST be present
|
|
// NOTE at the moment the document and the PWC are the same object, so we always show it for a checked out document
|
|
// TODO separated code for PWC and actual document object
|
|
if (!empty($cmisEntry['properties']['VersionSeriesCheckedOutId']['value']))
|
|
{
|
|
$link = $response->newElement('link');
|
|
$link->appendChild($response->newAttr('rel', 'pwc'));
|
|
$link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type
|
|
. '/' . $cmisEntry['properties']['ObjectId']['value']
|
|
. '/' . $cmisEntry['properties']['ContentStreamFilename']['value']));
|
|
$entry->appendChild($link);
|
|
$link = $response->newElement('link');
|
|
$link->appendChild($response->newAttr('rel', 'source'));
|
|
$link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type
|
|
. '/' . $cmisEntry['properties']['ObjectId']['value']
|
|
. '/' . $cmisEntry['properties']['ContentStreamFilename']['value']));
|
|
$entry->appendChild($link);
|
|
}
|
|
|
|
// $link = $response->newElement('link');
|
|
// $link->appendChild($response->newAttr('rel', 'stream'));
|
|
// $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type
|
|
// . '/' . $cmisEntry['properties']['ObjectId']['value']
|
|
// . '/' . $cmisEntry['properties']['ContentStreamFilename']['value']));
|
|
}
|
|
|
|
$link = $response->newElement('link');
|
|
$link->appendChild($response->newAttr('rel', 'type'));
|
|
$link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/type/' . $type));
|
|
$entry->appendChild($link);
|
|
|
|
$link = $response->newElement('link');
|
|
$link->appendChild($response->newAttr('rel', 'repository'));
|
|
$link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . '/servicedocument'));
|
|
$entry->appendChild($link);
|
|
|
|
// according to spec this MUST be present, but spec says that links for function which are not supported
|
|
// do not need to be present, so unsure for the moment - policies are being abandoned, or so I thought...
|
|
// $link = $response->newElement('link');
|
|
// $link->appendChild($response->newAttr('rel', 'policies'));
|
|
// $link->appendChild($response->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/' . $type . '/' . $cmisEntry['properties']['ParentId']['value']));
|
|
// $entry->appendChild($link);
|
|
// end links
|
|
|
|
// TODO proper date
|
|
$entry->appendChild($response->newField('published', self::formatDatestamp()));
|
|
$entry->appendChild($response->newElement('summary', $cmisEntry['properties']['Name']['value']));
|
|
$entry->appendChild($response->newElement('title', $cmisEntry['properties']['Name']['value']));
|
|
$entry->appendChild($response->newField('updated', self::formatDatestamp()));
|
|
|
|
// main CMIS entry
|
|
$objectElement = $response->newElement('cmis:object');
|
|
$propertiesElement = $response->newElement('cmis:properties');
|
|
|
|
foreach($cmisEntry['properties'] as $propertyName => $property)
|
|
{
|
|
$propElement = $response->newElement('cmis:' . $property['type']);
|
|
$propElement->appendChild($response->newAttr('cmis:name', $propertyName));
|
|
if (!empty($property['value']))
|
|
{
|
|
if ($propertyName == 'ContentStreamUri') {
|
|
$property['value'] = CMIS_APP_BASE_URI . $workspace . '/' . $type . '/' .$property['value'];
|
|
}
|
|
$response->newField('cmis:value', CMISUtil::boolToString($property['value']), $propElement);
|
|
}
|
|
$propertiesElement->appendChild($propElement);
|
|
}
|
|
|
|
$objectElement->appendChild($propertiesElement);
|
|
$entry->appendChild($objectElement);
|
|
|
|
// after every entry, append a cmis:terminator tag
|
|
$entry->appendChild($response->newElement('cmis:terminator'));
|
|
|
|
// TODO check determination of when to add app:edited tag
|
|
// if ($method == 'POST') {
|
|
$entry->appendChild($response->newElement('app:edited', self::formatDatestamp()));
|
|
// }
|
|
}
|
|
|
|
/**
|
|
* Retrieves the list of types|type definition as a CMIS AtomPub feed
|
|
*
|
|
* @param string $typeDef Type requested - 'All Types' indicates a listing, else only a specific type
|
|
* @param array $types The types found
|
|
* @return string CMIS AtomPub feed
|
|
*/
|
|
static public function getTypeFeed($typeDef, $types)
|
|
{
|
|
$typesString = '';
|
|
$typesHeading = '';
|
|
switch($typeDef)
|
|
{
|
|
case 'all':
|
|
case 'children':
|
|
case 'descendants':
|
|
$typesString = 'types-' . $typeDef;
|
|
$typesHeading = 'All Types';
|
|
break;
|
|
default:
|
|
$typesString = 'type-' . $typeDef;
|
|
$typesHeading = $typeDef;
|
|
break;
|
|
}
|
|
|
|
//Create a new response feed
|
|
$feed = new KT_cmis_atom_responseFeed_GET(CMIS_APP_BASE_URI);
|
|
$workspace = $feed->getWorkspace();
|
|
|
|
$feed->newField('title', $typesHeading, $feed);
|
|
$feed->newField('id', 'urn:uuid:' . $typesString, $feed);
|
|
|
|
// TODO set page number correctly - to be done when we support paging the the API
|
|
|
|
// author
|
|
// TODO generate this dynamically (based on???)\
|
|
$feedElement = $feed->newField('author');
|
|
$element = $feed->newField('name', 'admin', $feedElement);
|
|
$feed->appendChild($feedElement);
|
|
|
|
// NOTE spec says this link MUST be present but is vague on where it points
|
|
// as of 0.61c:
|
|
// "The source link relation points to the underlying CMIS Type Definition as Atom Entry"
|
|
// so what is the underlying CMIS Type Definition for a collection of base types?
|
|
// suspect that it only applies when not listing all types, i.e. a base type is asked for
|
|
/*
|
|
$link = $feed->newElement('link');
|
|
$link->appendChild($feed->newAttr('rel','source'));
|
|
$link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/type/' . strtolower($type['typeId'])));
|
|
$feed->appendChild($link);
|
|
*/
|
|
|
|
// current time: format = 2009-07-13T14:49:27.659+02:00
|
|
$feed->appendChild($feed->newElement('updated', self::formatDatestamp()));
|
|
|
|
foreach($types as $type)
|
|
{
|
|
$entry = $feed->newEntry();
|
|
|
|
$feedElement = $feed->newField('author');
|
|
$element = $feed->newField('name', 'admin', $feedElement);
|
|
$entry->appendChild($feedElement);
|
|
$feedElement = $feed->newField('content', $type['typeId']);
|
|
$entry->appendChild($feedElement);
|
|
|
|
$feed->newField('id', 'urn:uuid:type-' . $type['typeId'], $feed);
|
|
|
|
// TODO add parents link when not selecting a base type.
|
|
// TODO add children link when type has children
|
|
// TODO add descendants link when type has children
|
|
// NOTE KnowledgeTree currently only supports base types so these are not important at the present time.
|
|
|
|
// links
|
|
$link = $feed->newElement('link');
|
|
$link->appendChild($feed->newAttr('rel','self'));
|
|
$link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/type/' . strtolower($type['typeId'])));
|
|
$entry->appendChild($link);
|
|
// TODO type link MUST point to base type
|
|
// KnowledgeTree currently only supports base types so this is not important
|
|
// at the present time as it will always point at the base type.
|
|
$link = $feed->newElement('link');
|
|
$link->appendChild($feed->newAttr('rel','type'));
|
|
$link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . $workspace . '/type/' . strtolower($type['typeId'])));
|
|
$entry->appendChild($link);
|
|
$link = $feed->newElement('link');
|
|
$link->appendChild($feed->newAttr('rel','repository'));
|
|
$link->appendChild($feed->newAttr('href', CMIS_APP_BASE_URI . '/servicedocument'));
|
|
$entry->appendChild($link);
|
|
|
|
$entry->appendChild($feed->newElement('summary', $type['typeId'] . ' Type'));
|
|
$entry->appendChild($feed->newElement('title', $type['typeId']));
|
|
$entry->appendChild($feed->newElement('updated', self::formatDatestamp()));
|
|
|
|
// main CMIS entry
|
|
$feedElement = $feed->newElement('cmis:' . strtolower($type['typeId']) . 'Type');
|
|
foreach($type as $property => $value)
|
|
{
|
|
$feed->newField('cmis:' . $property, CMISUtil::boolToString($value), $feedElement);
|
|
}
|
|
|
|
$entry->appendChild($feedElement);
|
|
|
|
// after every entry, append a cmis:terminator tag
|
|
$entry->appendChild($feed->newElement('cmis:terminator'));
|
|
}
|
|
|
|
return $feed;
|
|
}
|
|
|
|
static public function getErrorFeed(&$service, $status, $message)
|
|
{
|
|
$service->setStatus($status);
|
|
$feed = new KT_cmis_atom_responseFeed_GET(CMIS_APP_BASE_URI);
|
|
|
|
$feed->newField('title', 'Error: ' . $status, $feed);
|
|
$entry = $feed->newEntry();
|
|
$feed->newField('error', $message, $entry);
|
|
|
|
return $feed;
|
|
}
|
|
|
|
/**
|
|
* Fetches the CMIS objectId based on the path
|
|
*
|
|
* @param array $path
|
|
* @param object $ktapi KTAPI instance
|
|
*/
|
|
// TODO make this much more efficient than this method
|
|
static public function getFolderId($path, &$ktapi)
|
|
{
|
|
// lose first item
|
|
array_shift($path);
|
|
|
|
$numQ = count($path);
|
|
$numFolders = $numQ;
|
|
$folderId = 1;
|
|
|
|
$start = 0;
|
|
while($start < $numFolders)
|
|
{
|
|
$name = $path[$numQ-$numFolders+$start];
|
|
// fix for possible url encoding issue
|
|
$name = str_replace('%2520', '%20', $name);
|
|
|
|
$folderName = urldecode($name);
|
|
$folder = $ktapi->get_folder_by_name($folderName, $folderId);
|
|
$folderId = $folder->get_folderid();
|
|
++$start;
|
|
}
|
|
|
|
return CMISUtil::encodeObjectId('Folder', $folderId);
|
|
}
|
|
|
|
static public function getCmisProperties($xmlArray)
|
|
{
|
|
$properties = array();
|
|
|
|
// find cmis:object tag
|
|
$baseCmisObject = KT_cmis_atom_service_helper::findTag('cmis:object', $xmlArray, null, false);
|
|
if(count($baseCmisObject) <= 0)
|
|
{
|
|
$entryObject = KT_cmis_atom_service_helper::findTag('entry', $xmlArray, null, false);
|
|
$baseCmisObject = KT_cmis_atom_service_helper::findTag('cmis:object', $entryObject['@children'], null, true);
|
|
}
|
|
|
|
if(count($baseCmisObject)>0)
|
|
{
|
|
foreach($baseCmisObject['@children'] as $key => $childElement)
|
|
{
|
|
if ($key == 'cmis:properties')
|
|
{
|
|
foreach($childElement[0]['@children'] as $cmisPropertyDefinition)
|
|
{
|
|
foreach($cmisPropertyDefinition as $propertyType => $propertyDefinition)
|
|
{
|
|
$properties[$propertyDefinition['@attributes']['cmis:name']] = $propertyDefinition['@children']['cmis:value'][0]['@value'];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $properties;
|
|
}
|
|
|
|
static public function getAtomValues($xmlArray, $tag)
|
|
{
|
|
if (!is_null($xmlArray['atom:'.$tag]))
|
|
return $xmlArray['atom:'.$tag][0]['@value'];
|
|
else if (!is_null($xmlArray[$tag]))
|
|
return $xmlArray[$tag][0]['@value'];
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Get the KT singleton instance
|
|
*
|
|
* @return object
|
|
*/
|
|
public static function getKt()
|
|
{
|
|
if(!isset(self::$ktapi))
|
|
{
|
|
self::$ktapi = new KTAPI();
|
|
$active = self::$ktapi->get_active_session(session_id());
|
|
|
|
if (PEAR::isError($active))
|
|
{
|
|
// invoke auth code, session must be restarted
|
|
if(!KT_atom_HTTPauth::isLoggedIn()) {
|
|
KT_atom_HTTPauth::login('KnowledgeTree DMS', 'You must authenticate to enter this realm');
|
|
}
|
|
}
|
|
}
|
|
return self::$ktapi;
|
|
}
|
|
|
|
// TODO adjust for time zones?
|
|
static public function formatDatestamp($time = null)
|
|
{
|
|
if (is_null($time)) $time = time();
|
|
return date('Y-m-d H:i:s', $time);
|
|
}
|
|
|
|
/**
|
|
* Fetches the document content stream for internal use
|
|
*
|
|
* @param object $ObjectService
|
|
* @param string $repositoryId
|
|
* @return null | string $contentStream
|
|
*/
|
|
static public function getContentStream(&$service, &$ObjectService, $repositoryId)
|
|
{
|
|
$response = $ObjectService->getProperties($repositoryId, $service->params[0], false, false);
|
|
if (PEAR::isError($response)) {
|
|
return null;
|
|
}
|
|
|
|
$contentStream = $ObjectService->getContentStream($repositoryId, $service->params[0]);
|
|
|
|
return $contentStream;
|
|
}
|
|
/**
|
|
* Fetches and prepares the document content stream for download/viewing
|
|
*
|
|
* @param object $ObjectService
|
|
* @param string $repositoryId
|
|
* @return null | nothing
|
|
*/
|
|
static public function downloadContentStream(&$service, &$ObjectService, $repositoryId)
|
|
{
|
|
$response = $ObjectService->getProperties($repositoryId, $service->params[0], false, false);
|
|
if (PEAR::isError($response)) {
|
|
$feed = KT_cmis_atom_service_helper::getErrorFeed($service, KT_cmis_atom_service::STATUS_SERVER_ERROR, $response->getMessage());
|
|
$service->responseFeed = $feed;
|
|
return null;
|
|
}
|
|
|
|
// TODO also check If-Modified-Since?
|
|
// $service->headers['If-Modified-Since'] => 2009-07-24 17:16:54
|
|
|
|
$service->setContentDownload(true);
|
|
$eTag = md5($response['properties']['LastModificationDate']['value'] . $response['properties']['ContentStreamLength']['value']);
|
|
|
|
if ($service->headers['If-None-Match'] == $eTag)
|
|
{
|
|
$service->setStatus(KT_cmis_atom_service::STATUS_NOT_MODIFIED);
|
|
$service->setContentDownload(false);
|
|
return null;
|
|
}
|
|
|
|
$contentStream = $ObjectService->getContentStream($repositoryId, $service->params[0]);
|
|
|
|
// headers specific to output
|
|
$service->setEtag($eTag);
|
|
$service->setHeader('Last-Modified', $response['properties']['LastModificationDate']['value']);
|
|
|
|
if (!empty($response['properties']['ContentStreamMimeType']['value'])) {
|
|
$service->setHeader('Content-type', $response['properties']['ContentStreamMimeType']['value'] . ';charset=utf-8');
|
|
}
|
|
else {
|
|
$service->setHeader('Content-type', 'text/plain;charset=utf-8');
|
|
}
|
|
|
|
$service->setHeader('Content-Disposition', 'attachment;filename="' . $response['properties']['ContentStreamFilename']['value'] . '"');
|
|
$service->setHeader('Content-Length', $response['properties']['ContentStreamLength']['value']);
|
|
$service->setOutput($contentStream);
|
|
}
|
|
|
|
//TODO: Add key information to be able to find the same tag in the original struct (MarkH)
|
|
static public function findTag($tagName=NULL,$xml=array(),$tagArray=NULL,$deep=false){
|
|
$tagArray=is_array($tagArray)?$tagArray:array();
|
|
foreach($xml as $xmlTag=>$content){
|
|
if($xmlTag===$tagName){
|
|
$tagArray[]=$content;
|
|
}
|
|
if($deep){
|
|
foreach($content as $contentTags){
|
|
if(is_array($contentTags['@children'])) {
|
|
if(count($contentTags['@children'])>0) $tagArray=self::findTag($tagName,$contentTags['@children'],$tagArray);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//TODO: this is very ugly. Change it. (MarkH)
|
|
return self::rebaseArray($tagArray);
|
|
}
|
|
|
|
static public function rebaseArray($arr=array()){
|
|
//Force Array
|
|
$arr=is_array($arr)?$arr:array();
|
|
|
|
//Rebase recursively
|
|
if(count($arr)===1)$arr=self::rebaseArray($arr[0]);
|
|
return $arr;
|
|
}
|
|
|
|
}
|
|
|
|
?>
|