'RepositoryService?wsdl', 'DiscoveryService' => 'DiscoveryService?wsdl', 'MultiFilingService' => 'MultiFilingService?wsdl', 'NavigationService' => 'NavigationService?wsdl', 'ObjectService' => 'ObjectService?wsdl', 'PolicyService' => 'PolicyService?wsdl', 'RelationshipService' => 'RelationshipService?wsdl', 'VersioningService' => 'VersioningService?wsdl', 'ACLService' => 'ACLService?wsdl', ); $maxItems = 15; // max number of documents on a page $useQuery = true; // get document list with query, or with getChildren // Initialize variables and session $html = new PccHTML(); $errorMesssage = ''; session_start(); // Get session parameters for current folder and page, if set $currentFolderId = (isset($_SESSION['cmisSession']['currentFolder'])) ? $_SESSION['cmisSession']['currentFolder'] : ''; $currentPage = (isset($_SESSION['cmisSession']['currentPage'])) ? (int)$_SESSION['cmisSession']['currentPage'] : 1; // Get URL parameters, handle login if ($_SERVER['REQUEST_METHOD'] == 'GET') { if (isset($_GET['folderid']) && ($_GET['folderid'] != '')) { $newFolderId = urldecode($_GET['folderid']); if ($newFolderId != $currentFolderId) { // reset page if folder changed $currentPage = 1; } $currentFolderId = $newFolderId; } if (isset($_GET['page']) && ($_GET['page'] != '')) { $currentPage = (int)$_GET['page']; } $currentDocId = (isset($_GET['objectid'])) ? urldecode($_GET['objectid']) : ''; $action = (isset($_GET['action'])) ? $_GET['action'] : ''; if ($action == 'login') { // display login form echo $html->applyTemplate('loginForm'); exit; } } if ($_SERVER['REQUEST_METHOD'] == 'POST') { if (isset($_POST['folderid']) && ($_POST['folderid'] != '')) { $newFolderId = urldecode($_POST['folderid']); if ($newFolderId != $currentFolderId) { // reset page if folder changed $currentPage = 1; } $currentFolderId = $newFolderId; } if (isset($_POST['page']) && ($_POST['page'] != '')) { $currentPage = (int)$_POST['page']; } $currentDocId = (isset($_POST['objectid'])) ? urldecode($_POST['objectid']) : ''; $action = (isset($_POST['action'])) ? $_POST['action'] : ''; if ($action == 'login') { // process login information $_SESSION['cmisSession']['username'] = $_POST['username']; $_SESSION['cmisSession']['password'] = $_POST['password']; } } // Forward to login page if credentials are not set if (!isset($_SESSION['cmisSession']['username']) || !isset($_SESSION['cmisSession']['password'])) { $path = 'index.php?action=login'; header("Location: $path"); exit; } // Open a SOAP session to the CMIS repository $cmisSessionOptions = array( 'CMISSoapClient' => $soapClient, // class name for custom SoapClient 'CMISServices' => $cmisServices, // service endpoints 'user_name' => $_SESSION['cmisSession']['username'], 'password' => $_SESSION['cmisSession']['password'] ); try { $ecmClient = new CMISWebService($url, $cmisSessionOptions, 'errorMessage'); } catch (Exception $e) { error_message($e); } // credentials can be set after SOAP initialization, if not provided through options array // $ecmClient->setCredentials($ecmSession['username'], $ecmSession['password']); // Get basic information about repository $repositories = $ecmClient->getRepositories(); $repositoryName = $repositories[0]->repositoryName; // Using first repository only $repositoryId = $repositories[0]->repositoryId; $repositoryInfo = $ecmClient->getRepositoryInfo($repositoryId); $rootFolderId = $repositoryInfo->rootFolderId; if ($currentFolderId == '') { $currentFolderId = $rootFolderId; } $currentFolderName = (string) $currentFolderObject->properties['cmis:name']; $downloadFrame = ''; // Save current folder and page in session for subsequent page requests $_SESSION['cmisSession']['currentFolder'] = $currentFolderId; $_SESSION['cmisSession']['currentPage'] = $currentPage; /* * Part 2: handle different actions */ $pccLeft = ''; $pccRight = ''; switch ($action) { case 'logout': $ecmClient->clearCredentials(); unset($_SESSION['cmisSession']['username']); unset($_SESSION['cmisSession']['password']); $path = 'index.php?action=login'; header("Location: $path"); return; break; case 'createdocument': createDocumentAction($ecmClient, $repositoryId, $_FILES['filename'], $_POST['createfilename'], $currentFolderId); break; case 'createfolder': createFolderAction($ecmClient, $repositoryId, $_GET['createfoldername'], $currentFolderId); break; case 'checkin': checkinAction($ecmClient, $repositoryId, $_FILES['filename'], $currentDocId); break; case 'upload': uploadAction($ecmClient, $repositoryId, $_FILES['filename'], $currentDocId); break; case 'download': downloadAction($ecmClient, $repositoryId, $currentDocId); return; // do not continue to display new page break; case 'checkout': $pwcId = urlencode(checkoutAction($ecmClient, $repositoryId, $currentDocId)); $downloadFrame = $html->applyTemplate('downloadFrame', $pwcId); // start download after page refresh break; case 'cancelco': cancelcoAction($ecmClient, $repositoryId, $currentDocId); break; case 'delete': deleteAction($ecmClient, $repositoryId, $currentDocId); break; case 'details': $pccRight = documentDetails(); break; default: break; } // Generate output, if not done under action yet if ($pccLeft == '') { $pccLeft = folderList($html, $ecmClient, $repositoryId, $currentFolderId, $rootFolderId, $useQuery); } if ($pccRight == '') { $pccRight = documentList($html, $ecmClient, $repositoryId, $currentFolderId, $currentPage, $maxItems, $useQuery); } /* * Part 3: Display page with folder list and document list or details */ /* Build page to display */ echo $html->applyTemplate('htmlHeader'); // all dialogs are included into the main page, to avoid page reloads for dialogs createModalDialog($html, 'checkin', 'Checkin'); createModalDialog($html, 'checkout', 'Checkout'); createModalDialog($html, 'cancelCO', 'Cancel Checkout'); createModalDialog($html, 'uploadFile', 'Upload File'); createModalDialog($html, 'delete', 'Confirm Delete'); createModalDialog($html, 'createFolder', 'Create Folder'); createModalDialog($html, 'createDocument', 'Create Document'); echo $downloadFrame; // frame used for file download // Display header with path and buttons $pccPath = pccPath($html, $ecmClient, $repositoryId, $currentFolderId, $rootFolderId); $pccButtons = $html->applyTemplate('createFolderBtn', $currentFolderName) . $html->applyTemplate('createDocumentBtn', $currentFolderName); echo $html->applyTemplate('pageHeader', $errorMessage, $pccPath, $pccButtons); // Display main page left and right echo $pccLeft; echo $pccRight; return; /* * End of main program */ function pccPath($html, $ecmClient, $repositoryId, $currentFolderId, $rootFolderId) { // Get current folder object and name $currentFolderObject = $ecmClient->getObject($repositoryId, $currentFolderId, 'cmis:name'); // Build navigation path $path = ''; $folderId = $currentFolderId; while (true) { // loop upwards until root is reached $folderObject = $ecmClient->getObject($repositoryId, $folderId, 'cmis:objectId, cmis:name, cmis:parentId'); $folderUrl = urlencode($folderObject->properties['cmis:objectId']); $path = $html->applyTemplate('folderUrl', $folderUrl, $folderObject->properties['cmis:name']) . $path; if ($folderId == $rootFolderId) { break; } $path = ' > ' . $path; $folderId = (string) $folderObject->properties['cmis:parentId']; if (! $folderId) break; // avoid endless loop in case of error } return $path; } function folderList($html, $ecmClient, $repositoryId, $currentFolderId, $rootFolderId, $useQuery) { // Get parent of current folder, set 'UP' for folder list $folderList = "\n"; if ($currentFolderId !== $rootFolderId) { $parentFolder = $ecmClient->getFolderParent($repositoryId, $currentFolderId); $folderList .= $html->applyTemplate('folderListEntry', urlencode($parentFolder->properties['cmis:objectId']), '../' . $parentFolder->properties['cmis:name']); } // This code implements two versions to select all folder in the current folder // 1) Using a query call. This may not work well with asynchronous search engines like Alfresco solr // 2) Using getFolderTree. if ($useQuery) { $folderObjects = $ecmClient->query($repositoryId, "select * from cmis:folder where cmis:parentId = '$currentFolderId' order by cmis:name"); // Display all folder objects in folder list if (count($folderObjects->objects) > 0) { foreach ($folderObjects->objects as $object) { // display each folder entry $folderList .= $html->applyTemplate('folderListEntry', urlencode($object->properties['cmis:objectId']), $object->properties['cmis:name']); } } } else { $folders = $ecmClient->getFolderTree($repositoryId, $currentFolderId, 1, '*'); $numFolders = count($folders); if ($numFolders > 0) { $myFolders = array(); foreach ($folders as $folderContainer) { // put into array for sorting $object = $folderContainer->objectInFolder->object; $myFolders[(string)$object->properties['cmis:name']] = $object; } ksort($myFolders); // sort array, getFolderTree does not support sorting foreach ($myFolders as $name => $object) { // display each folder entry $folderList .= $html->applyTemplate('folderListEntry', urlencode($object->properties['cmis:objectId']), $name); } } } return $html->applyTemplate('folderList', $folderList); } function documentList($html, $ecmClient, $repositoryId, $currentFolderId, $currentPage, $maxItems, $useQuery) { // This code implements two versions to select all documents in the current folder // 1) Using a query call. This may not work well with asynchronous search engines like Alfresco solr // 2) Using getChildren. if ($useQuery) { $documentObjects = $ecmClient->query($repositoryId, "select * from cmis:document where in_folder('$currentFolderId') order by cmis:name", FALSE, TRUE, enumIncludeRelationships::none, 'cmis:none', $maxItems, ($currentPage - 1) * $maxItems); } else { $children = $ecmClient->getChildren($repositoryId, $currentFolderId, '*', 'cmis:baseTypeId, cmis:name', true, enumIncludeRelationships::none); // create $documentObjects result as it would be returned by query $documentObjects = new cmisObjectListType(); // Transform getChildren response into the query return type $documentObjects->hasMoreItems = FALSE; foreach ($children->objects as $child) { if ((string) $child->object->properties['cmis:baseTypeId'] == 'cmis:document') { $documentObjects->objects[] = $child->object; } } } // Display document list or empty message if (count($documentObjects->objects) == 0) { $documentHead = $html->applyTemplate('docListEmpty'); } else { $documentHead = $html->applyTemplate('docListHead'); $documentList = "\n"; // Loop over all documents foreach ($documentObjects->objects as $object) { // build list of actions with links for each object $actionList = ''; // actions with links $objectId = $object->properties['cmis:objectId']->single(); $objectUrl = urlencode($objectId); $objectName = $object->properties['cmis:name']->single(); if ($object->properties['cmis:isVersionSeriesCheckedOut']->single()) { // object is checked out if ($object->allowableActions->canCheckIn) { // allowed to upload and check in $actionList .= $html->applyTemplate('uploadAction', $objectName, $objectUrl); $actionList .= $html->applyTemplate('checkinAction', $objectName, $objectUrl); } if ($object->allowableActions->canCancelCheckOut) { $actionList .= $html->applyTemplate('cancelCOAction', $objectName, $objectUrl); } } else { // object is not checked out if ($object->allowableActions->canCheckOut) { $actionList .= $html->applyTemplate('checkoutAction', $objectName, $objectUrl); } } if ($object->allowableActions->canDeleteObject) { $actionList .= $html->applyTemplate('deleteAction', $objectName, $objectUrl); } $actionList .= $html->applyTemplate('detailsAction', $objectUrl); // Display row with name, date and action links for object $documentList .= $html->applyTemplate('docListEntry', $objectUrl, $objectName, dateString($object->properties['cmis:lastModificationDate']), $actionList) . "\n"; } } // Display paging links if more than one page $paging = ''; if ($documentObjects->hasMoreItems || $currentPage > 1) { // display page information // if numItems ist set, maxPage can be calculated, otherwise use current or next page $maxPage = (isset($documentObjects->numItems)) ? ceil($documentObjects->numItems / $maxItems) : ($documentObjects->hasMoreItems ? $currentPage + 1 : $currentPage); // display page numbers for ($i = 1; $i <= $maxPage; $i++) { if (($currentPage) == $i) { $paging .= $html->applyTemplate('pageCurrent', $i); } else { $paging .= $html->applyTemplate('pageLink', urlencode($currentFolderId), $i); } } $paging = $html->applyTemplate('pageList', $paging); } return $html->applyTemplate('documentList', $documentHead, $documentList, $paging); } function documentDetails() { // TODO: display detail page for individual object $documentList = "
Document Details not yet implemented.
\n"; return $documentList; } function dateString($d) { $d = date_create($d); $d = date_format($d, "d. M Y H:i"); return $d; } // Various actions function checkoutAction($ecmClient, $repositoryId, $objectId) { $response = $ecmClient->checkOut($repositoryId, $objectId); return $response->objectId; } function cancelcoAction($ecmClient, $repositoryId, $objectId) { $object = $ecmClient->getObject($repositoryId, $objectId, '*'); if (isset($object->properties['cmis:versionSeriesCheckedOutId'])) { $response = $ecmClient->cancelCheckOut($repositoryId, $object->properties['cmis:versionSeriesCheckedOutId']); } } function deleteAction($ecmClient, $repositoryId, $objectId) { $ecmClient->deleteObject($repositoryId, $objectId, TRUE); } function downloadAction($ecmClient, $repositoryId, $objectId) { $object = $ecmClient->getObject($repositoryId, $objectId, '*'); $streamLength = $object->properties['cmis:contentStreamLength']->single(); $bufferLength = 0; // define buffer size, or 0 to disable buffering if ($bufferLength == 0) { // don't use buffering, not implemented in OpenCMIS < 0.8 ! $stream = $ecmClient->getContentStream($repositoryId, $objectId, ''); header('Content-Type: ' . $stream->mimeType); header('Content-Disposition: attachment; filename=' . $stream->filename); header('Content-Length; ' . $streamLength); echo $stream->stream; flush(); } else { // Send first content chunk, up to bufferLength $stream = $ecmClient->getContentStream($repositoryId, $objectId, '', 0, $bufferLength); header('Content-Type: ' . $stream->mimeType); header('Content-Disposition: attachment; filename=' . $stream->filename); header('Content-Length; ' . $streamLength); echo $stream->stream; flush(); // Send additional chunks if required $offset = $bufferLength; while ($offset < $streamLength) { $stream = $ecmClient->getContentStream($repositoryId, $objectId, NULL, $offset, $bufferLength); echo $stream->stream; flush(); $offset += $bufferLength; } } } function checkinAction($ecmClient, $repositoryId, $file, $objectId) { $stream = NULL; $major = false; $comment = NULL; if (is_array($file) && $file['error'] == 0) { $stream = new cmisContentStreamType(); $stream->length = $file['size']; $stream->mimeType = $file['type']; $stream->filename = $file['name']; $stream->stream = file_get_contents($file['tmp_name']); } $object = $ecmClient->getObject($repositoryId, $objectId, '*'); if (isset($object->properties['cmis:versionSeriesCheckedOutId'])) { $response = $ecmClient->checkIn($repositoryId, $object->properties['cmis:versionSeriesCheckedOutId'], $major, NULL, $stream, $comment); } } function uploadAction($ecmClient, $repositoryId, $file, $objectId) { $stream = new cmisContentStreamType(); $stream->length = $file['size']; $stream->mimeType = $file['type']; $stream->filename = $file['name']; $stream->stream = file_get_contents($file['tmp_name']); $ecmClient->setContentStream($repositoryId, $objectId, NULL, NULL, $stream); } function createFolderAction($ecmClient, $repositoryId, $createName, $folderId) { $properties['cmis:name'] = new cmisPropertyString($createName); $properties['cmis:objectTypeId'] = new cmisPropertyId('cmis:folder'); $response = $ecmClient->createFolder($repositoryId, $properties, $folderId); } function createDocumentAction($ecmClient, $repositoryId, $file, $createName, $folderId) { $properties['cmis:name'] = new cmisPropertyString($createName); $properties['cmis:objectTypeId'] = new cmisPropertyId('cmis:document'); $stream = new cmisContentStreamType(); if (is_array($file) && $file['error'] == 0) { $stream->length = $file['size']; $stream->mimeType = $file['type']; $stream->filename = $file['name']; $stream->stream = file_get_contents($file['tmp_name']); } $response = $ecmClient->createDocument($repositoryId, $properties, $folderId, $stream); } // Modal dialog function createModalDialog($html, $name, $title) { echo $html->applyTemplate('modalDialog', $name, $title, $html->applyTemplate($name . 'Dialog', $name)); } function errorMessage($sf) { global $errorMessage; // Display Soap Fault error message on page, if any $errorMessage .= "
SOAP Error:
\n" . $sf->getMessage() . "
\n"; } ?>