* @copyright Copyright (C) 2002-2005 Markus Westphal, * 2006-2008 Malcolm Cowe, 2010 Matteo Lucarelli, * 2010-2012 Uwe Steinmann * @version Release: @package_version@ */ /** * Include parent class */ //require_once("class.Bootstrap.php"); /** * Class which outputs the html page for ViewDocument view * * @category DMS * @package SeedDMS * @author Markus Westphal, Malcolm Cowe, Uwe Steinmann * @copyright Copyright (C) 2002-2005 Markus Westphal, * 2006-2008 Malcolm Cowe, 2010 Matteo Lucarelli, * 2010-2012 Uwe Steinmann * @version Release: @package_version@ */ class SeedDMS_View_ViewDocument extends SeedDMS_Theme_Style { protected function getAccessModeText($defMode) { /* {{{ */ switch($defMode) { case M_NONE: return getMLText("access_mode_none"); break; case M_READ: return getMLText("access_mode_read"); break; case M_READWRITE: return getMLText("access_mode_readwrite"); break; case M_ALL: return getMLText("access_mode_all"); break; } } /* }}} */ protected function printAccessList($obj) { /* {{{ */ $accessList = $obj->getAccessList(); if (count($accessList["users"]) == 0 && count($accessList["groups"]) == 0) return; $content = ''; for ($i = 0; $i < count($accessList["groups"]); $i++) { $group = $accessList["groups"][$i]->getGroup(); $accesstext = $this->getAccessModeText($accessList["groups"][$i]->getMode()); $content .= $accesstext.": ".htmlspecialchars($group->getName()); if ($i+1 < count($accessList["groups"]) || count($accessList["users"]) > 0) $content .= "
"; } for ($i = 0; $i < count($accessList["users"]); $i++) { $user = $accessList["users"][$i]->getUser(); $accesstext = $this->getAccessModeText($accessList["users"][$i]->getMode()); $content .= $accesstext.": ".htmlspecialchars($user->getFullName()); if ($i+1 < count($accessList["users"])) $content .= "
"; } if(count($accessList["groups"]) + count($accessList["users"]) > 3) { $this->printPopupBox(getMLText('list_access_rights'), $content); } else { echo $content; } } /* }}} */ /** * Output a single attribute in the document info section * * @param object $attribute attribute */ protected function printAttribute($attribute) { /* {{{ */ $attrdef = $attribute->getAttributeDefinition(); ?> getName()); ?>: getAttributeValue($attribute); ?> getAttributes(); if($attributes) { foreach($attributes as $attribute) { $arr = $this->callHook('showDocumentContentAttribute', $version, $attribute); if(is_array($arr)) { print "
  • ".$arr[0].": ".$arr[1]."
  • \n"; } else { $attrdef = $attribute->getAttributeDefinition(); print "
  • ".htmlspecialchars($attrdef->getName()).": "; $this->printAttributeValue($attribute); echo "
  • \n"; } } } $arrarr = $this->callHook('additionalDocumentContentInfo', $version); if(is_array($arrarr)) { foreach($arrarr as $arr) { print "
  • ".$arr[0].": ".$arr[1]."
  • \n"; } } elseif(is_string($arrarr)) { echo $arrarr; } } /* }}} */ function documentListItem() { /* {{{ */ $dms = $this->params['dms']; $user = $this->params['user']; $previewwidth = $this->params['previewWidthList']; $cachedir = $this->params['cachedir']; $conversionmgr = $this->params['conversionmgr']; $previewconverters = $this->params['previewConverters']; $previewwidthlist = $this->params['previewWidthList']; $previewwidthdetail = $this->params['previewWidthDetail']; $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; $document = $this->params['document']; if($document) { if ($document->getAccessMode($user) >= M_READ) { $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidth, $timeout, $xsendfile); if($conversionmgr) $previewer->setConversionMgr($conversionmgr); else $previewer->setConverters($previewconverters); $txt = $this->callHook('documentListItem', $document, $previewer, false, 'viewitem'); if(is_string($txt)) $content = $txt; else $content = $this->documentListRow($document, $previewer, true); echo $content; } } } /* }}} */ function timelinedata() { /* {{{ */ $dms = $this->params['dms']; $user = $this->params['user']; $document = $this->params['document']; $jsondata = array(); if($user->isAdmin()) { $data = $document->getTimeline(); foreach($data as $i=>$item) { switch($item['type']) { case 'add_version': $msg = getMLText('timeline_'.$item['type'], array('document'=>htmlspecialchars($item['document']->getName()), 'version'=> $item['version'])); break; case 'add_file': $msg = getMLText('timeline_'.$item['type'], array('document'=>htmlspecialchars($item['document']->getName()))); break; case 'status_change': $msg = getMLText('timeline_'.$item['type'], array('document'=>htmlspecialchars($item['document']->getName()), 'version'=> $item['version'], 'status'=> getOverallStatusText($item['status']))); break; default: $msg = '???'; } $data[$i]['msg'] = $msg; } foreach($data as $item) { if($item['type'] == 'status_change') $classname = $item['type']."_".$item['status']; else $classname = $item['type']; $d = makeTsFromLongDate($item['date']); $jsondata[] = array('start'=>date('c', $d)/*$item['date']*/, 'content'=>$item['msg'], 'className'=>$classname); } } header('Content-Type: application/json'); echo json_encode($jsondata); } /* }}} */ protected function iptcdata($arr) { /* {{{ */ $iptcHeaderArray = array ( '2#005'=>'DocumentTitle', '2#010'=>'Urgency', '2#015'=>'Category', '2#025'=>'Keywords', '2#020'=>'Subcategories', '2#040'=>'SpecialInstructions', '2#055'=>'CreationDate', '2#060'=>'CreationTime', '2#080'=>'AuthorByline', '2#085'=>'AuthorTitle', '2#090'=>'City', '2#095'=>'State', '2#101'=>'Country', '2#103'=>'OTR', '2#105'=>'Headline', '2#110'=>'Source', '2#115'=>'PhotoSource', '2#116'=>'Copyright', '2#120'=>'Caption', '2#122'=>'CaptionWriter' ); $retStr = ''; if(is_array($arr)) { foreach ($arr as $key=>$val) { if(isset($iptcHeaderArray[$key])) $retStr .= ''; elseif($key == '1#090') { $retStr .= ''; } elseif($key == '2#000') { $retStr .= ''; } else $retStr .= ''; } } $retStr .= '
    ' . $iptcHeaderArray[$key] . '' . htmlspecialchars(implode('; ', $val)) . '
    Encoding' . (($val[0] == "\x1B%G") ? 'UTF-8' : '') . '
    RecordVersion' . ord($val[0]) . '
    ' . $key . '' . htmlspecialchars(implode('; ', $val)) . '
    '; return $retStr; } /* }}} */ function js() { /* {{{ */ $dms = $this->params['dms']; $user = $this->params['user']; $document = $this->params['document']; $enableDropUpload = $this->params['enableDropUpload']; $maxuploadsize = $this->params['maxuploadsize']; header('Content-Type: application/javascript; charset=UTF-8'); parent::jsTranslations(array('js_form_error', 'js_form_errors', 'cancel', 'splash_move_document', 'confirm_move_document', 'move_document', 'confirm_transfer_link_document', 'transfer_content', 'link_document', 'splash_move_folder', 'confirm_move_folder', 'move_folder')); if($user->isAdmin()) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) $latestContent = $document->getLatestContent(); $this->printTimelineJs('out.ViewDocument.php?action=timelinedata&documentid='.$latestContent->getDocument()->getID(), 300, '', date('Y-m-d')); } $this->printDeleteDocumentButtonJs(); /* Add js for catching click on document in one page mode */ $this->printClickDocumentJs(); if ($enableDropUpload && $document->getAccessMode($user) >= M_READWRITE) { echo "SeedDMSUpload.setUrl('".$this->params['settings']->_httpRoot."op/op.Ajax.php');"; echo "SeedDMSUpload.setAbortBtnLabel('".getMLText("cancel")."');"; echo "SeedDMSUpload.setEditBtnLabel('');"; echo "SeedDMSUpload.setMaxFileSize($maxuploadsize);\n"; echo "SeedDMSUpload.setMaxFileSizeMsg('".getMLText("uploading_maxsize")."');"; } ?> $(document).ready( function() { $("#form1").validate({ ignore: [], rules: { docid: { required: true }, }, messages: { docid: "", }, }); }); params['dms']; $user = $this->params['user']; $document = $this->params['document']; $accessobject = $this->params['accessobject']; $viewonlinefiletypes = $this->params['viewonlinefiletypes']; $cachedir = $this->params['cachedir']; $conversionmgr = $this->params['conversionmgr']; $previewwidthdetail = $this->params['previewWidthDetail']; $previewconverters = $this->params['previewConverters']; $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; $documentid = $document->getId(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidthdetail, $timeout, $xsendfile); if($conversionmgr) $previewer->setConversionMgr($conversionmgr); else $previewer->setConverters($previewconverters); $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) $latestContent = $document->getLatestContent(); $files = $document->getDocumentFiles($latestContent->getVersion()); $files = SeedDMS_Core_DMS::filterDocumentFiles($user, $files); if (count($files) > 0) { print ""; print "\n\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n\n\n"; foreach($files as $file) { $file_exists=file_exists($dms->contentDir . $file->getPath()); $responsibleUser = $file->getUser(); print ""; print ""; print ""; print ""; print ""; print ""; } print "\n
    ".getMLText("file")."".getMLText("comment")."
    "; $previewer->createPreview($file, $previewwidthdetail); if($file_exists) { if ($viewonlinefiletypes && (in_array(strtolower($file->getFileType()), $viewonlinefiletypes) || in_array(strtolower($file->getMimeType()), $viewonlinefiletypes))) { if($accessobject->check_controller_access('ViewOnline', array('action'=>'run'))) { print "params['settings']->_httpRoot."op/op.ViewOnline.php?documentid=".$documentid."&file=". $file->getID()."\">"; } } else { if($accessobject->check_controller_access('Download', array('action'=>'file'))) { print "params['settings']->_httpRoot."op/op.Download.php?documentid=".$documentid."&file=".$file->getID()."\">"; } } } if($previewer->hasPreview($file)) { print("params['settings']->_httpRoot."op/op.Preview.php?documentid=".$document->getID()."&file=".$file->getID()."&width=".$previewwidthdetail."\" title=\"".htmlspecialchars($file->getMimeType())."\">"); } else { print "getMimeIcon($file->getFileType())."\" title=\"".htmlspecialchars($file->getMimeType())."\">"; } if($file_exists) { if($accessobject->check_controller_access('Download', array('action'=>'run')) || $accessobject->check_controller_access('ViewOnline', array('action'=>'run'))) print ""; } print "
      \n"; print "
    • ".htmlspecialchars($file->getName())."
    • \n"; if($file->getName() != $file->getOriginalFileName()) print "
    • ".htmlspecialchars($file->getOriginalFileName())."
    • \n"; if ($file_exists) { $realmimetype = SeedDMS_Core_File::mimetype($dms->contentDir . $file->getPath()); print "
    • ".SeedDMS_Core_File::format_filesize(filesize($dms->contentDir . $file->getPath())) ." bytes, ".htmlspecialchars($file->getMimeType())."
    • "; } else print "
    • ".htmlspecialchars($file->getMimeType())." - ".getMLText("document_deleted")."
    • "; print "
    • ".getMLText("uploaded_by")." getEmail())."\">".htmlspecialchars($responsibleUser->getFullName())."
    • "; print "
    • ".getLongReadableDate($file->getDate())."
    • "; if($file->getVersion()) print "
    • ".getMLText('linked_to_current_version')."
    • "; else print "
    • ".getMLText('linked_to_document')."
    • "; print "
    ".htmlspecialchars($file->getComment())."
      "; if (($document->getAccessMode($user) == M_ALL)||($file->getUserID()==$user->getID())) { print $this->html_link('RemoveDocumentFile', array('documentid'=>$document->getID(), 'fileid'=>$file->getID()), array(), ''.getMLText("delete"), false, true, array('
    • ', '
    • ')); print $this->html_link('EditDocumentFile', array('documentid'=>$document->getID(), 'fileid'=>$file->getID()), array(), ''.getMLText("edit"), false, true, array('
    • ', '
    • ')); } print "
    \n"; } else $this->infoMsg(getMLText("no_attached_files")); } /* }}} */ function documentInfos() { /* {{{ */ $dms = $this->params['dms']; $user = $this->params['user']; $settings = $this->params['settings']; $document = $this->params['document']; $txt = $this->callHook('documentInfos', $document); if(is_string($txt)) echo $txt; else { $this->contentHeading(htmlspecialchars($document->getName())); $txt = $this->callHook('preDocumentInfos', $document); if(is_string($txt)) echo $txt; ?> isAdmin()) { echo ""; echo "\n"; echo "\n"; echo ""; } ?> getComment()) { if($settings->_markdownComments) { $Parsedown = new Parsedown(); $comment = $Parsedown->text($document->getComment()); } else { $comment = htmlspecialchars($document->getComment()); } ?> getAccessMode($user) == M_ALL) { echo ""; echo ""; echo ""; echo ""; if($document->inheritsAccess()) { echo ""; echo "\n"; echo ""; } else { echo ""; echo ""; echo ""; echo ""; } } ?> expires()) { ?> getKeywords()) { $arr = $this->callHook('showDocumentKeywords', $document); if(is_array($arr)) { echo ""; echo ""; echo ""; echo ""; } elseif(is_string($arr)) { echo $arr; } else { ?> getCategories()) { $arr = $this->callHook('showDocumentCategories', $document); if(is_array($arr)) { echo ""; echo ""; echo ""; echo ""; } elseif(is_string($arr)) { echo $arr; } else { ?> getAttributes(); if($attributes) { foreach($attributes as $attribute) { $arr = $this->callHook('showDocumentAttribute', $document, $attribute); if(is_array($arr)) { echo ""; echo ""; echo ""; echo ""; } elseif(is_string($arr)) { echo $arr; } else { $this->printAttribute($attribute); } } } $arrarr = $this->callHook('additionalDocumentInfos', $document); if(is_array($arrarr)) { foreach($arrarr as $arr) { echo ""; echo ""; echo ""; echo ""; } } elseif(is_string($arrarr)) { echo $arrarr; } ?>
    ".getMLText("id").":".htmlspecialchars($document->getID())."
    : printInlineEdit(htmlspecialchars($document->getName()), $document);?>
    : getOwner(); print "getEmail())."\">".htmlspecialchars($owner->getFullName()).""; ?>
    :
    ".getMLText('default_access').":".$this->getAccessModeText($document->getDefaultAccess())."
    ".getMLText("access_mode").":"; echo getMLText("inherited")."
    "; $this->printAccessList($document); echo "
    ".getMLText('access_mode').":"; $this->printAccessList($document); echo "
    : getUsedDiskSpace());?>
    : getDate()); ?>
    : getExpires()); ?>
    ".$arr[0].":".$arr[1]."
    : getKeywords());?>
    ".$arr[0].":".$arr[1]."
    : getName()); echo implode(', ', $ct); ?>
    ".$arr[0].":".$arr[1]."
    ".$arr[0].":".$arr[1]."
    callHook('postDocumentInfos', $document); if(is_string($txt)) echo $txt; // $this->contentContainerEnd(); } } /* }}} */ function preview() { /* {{{ */ $dms = $this->params['dms']; $settings = $this->params['settings']; $document = $this->params['document']; $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; $showfullpreview = $this->params['showFullPreview']; $converttopdf = $this->params['convertToPdf']; $pdfconverters = $this->params['pdfConverters']; $cachedir = $this->params['cachedir']; $conversionmgr = $this->params['conversionmgr']; if(!$showfullpreview) return; $accessobject = $this->params['accessobject']; if($accessobject->check_controller_access('ViewOnline', array('action'=>'version'))) { $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) $latestContent = $document->getLatestContent(); $txt = $this->callHook('preDocumentPreview', $latestContent); if(is_string($txt)) echo $txt; $txt = $this->callHook('documentPreview', $latestContent); if(is_string($txt)) echo $txt; else { switch($latestContent->getMimeType()) { case 'audio/mpeg': case 'audio/mp3': case 'audio/ogg': case 'audio/wav': $this->contentHeading(getMLText("preview")); ?> contentHeading(getMLText("preview")); ?> contentHeading(getMLText("preview")); ?>
    contentHeading(getMLText("preview")); ?> callHook('additionalDocumentPreview', $latestContent); if(is_string($txt)) { $this->contentHeading(getMLText("preview")); echo $txt; } break; } } $txt = $this->callHook('postDocumentPreview', $latestContent); if(is_string($txt)) echo $txt; if($converttopdf) { $pdfpreviewer = new SeedDMS_Preview_PdfPreviewer($cachedir, $timeout, $xsendfile); if($conversionmgr) $pdfpreviewer->setConversionMgr($conversionmgr); else $pdfpreviewer->setConverters($pdfconverters); if($pdfpreviewer->hasConverter($latestContent->getMimeType())) { $this->contentHeading(getMLText("preview_pdf")); ?>
    "; foreach($items as $item) { if(is_string($item)) echo "
  • ".$item."
  • "; elseif(is_array($item)) { echo "
  • ".(!empty($item['icon']) ? " " : "").''.getMLText($item['label'])."
  • "; } } print ""; return; print ""; } /* }}} */ protected function showVersionDetails($latestContent, $previewer, $islatest=false) { /* {{{ */ $dms = $this->params['dms']; $user = $this->params['user']; $folder = $this->params['folder']; $accessobject = $this->params['accessobject']; $viewonlinefiletypes = $this->params['viewonlinefiletypes']; $enableownerrevapp = $this->params['enableownerrevapp']; $workflowmode = $this->params['workflowmode']; $previewwidthdetail = $this->params['previewWidthDetail']; // verify if file exists $file_exists=file_exists($dms->contentDir . $latestContent->getPath()); $status = $latestContent->getStatus(); // print ""; // print "\n\n"; // print "\n"; // print "\n"; // print "\n"; // print "\n"; // print "\n"; // print ""; // print "\n
    ".htmlspecialchars($latestContent->getOriginalFileName())."
    "; // $this->contentHeading(htmlspecialchars($latestContent->getOriginalFileName())); $this->rowStart(); $this->columnStart(3); if ($file_exists) { if ($viewonlinefiletypes && (in_array(strtolower($latestContent->getFileType()), $viewonlinefiletypes) || in_array(strtolower($latestContent->getMimeType()), $viewonlinefiletypes))) { if($accessobject->check_controller_access('ViewOnline', array('action'=>'run'))) print "params['settings']->_httpRoot."op/op.ViewOnline.php?documentid=".$latestContent->getDocument()->getId()."&version=". $latestContent->getVersion()."\">"; } else { if($accessobject->check_controller_access('Download', array('action'=>'version'))) print "params['settings']->_httpRoot."op/op.Download.php?documentid=".$latestContent->getDocument()->getId()."&version=".$latestContent->getVersion()."\">"; } } $previewer->createPreview($latestContent); if($previewer->hasPreview($latestContent)) { print("params['settings']->_httpRoot."op/op.Preview.php?documentid=".$latestContent->getDocument()->getID()."&version=".$latestContent->getVersion()."&width=".$previewwidthdetail."\" title=\"".htmlspecialchars($latestContent->getMimeType())."\">"); } else { print "getMimeIcon($latestContent->getFileType())."\" title=\"".htmlspecialchars($latestContent->getMimeType())."\">"; } if ($file_exists && ($accessobject->check_controller_access('ViewOnline', array('action'=>'run')) || $accessobject->check_controller_access('Download', array('action'=>'version')))) { print ""; } // print ""; $this->columnEnd(); $this->columnStart(5); print "
      \n"; print "
    • ".htmlspecialchars($latestContent->getOriginalFileName())."
    • \n"; print "
    • ".getMLText('version').": ".$latestContent->getVersion()."
    • \n"; if ($file_exists) { print "
    • ". SeedDMS_Core_File::format_filesize($latestContent->getFileSize()) .", "; print htmlspecialchars($latestContent->getMimeType()); if($user->isAdmin()) { $realmimetype = SeedDMS_Core_File::mimetype($dms->contentDir . $latestContent->getPath()); if($realmimetype != $latestContent->getMimeType()) echo " getId()."\" data-param3=\"formtoken=".createFormKey('setmimetype')."\" title=\"".htmlspecialchars($realmimetype)."\"> "; } if(in_array($latestContent->getMimeType(), ['image/jpeg', 'image/jpg', 'image/png', 'image/bmp'])) { $imsize = getimagesize($dms->contentDir . $latestContent->getPath(), $moreinfo); if(!empty($moreinfo['APP13'])) { echo ', '.$this->printPopupBox(getMLText('iptc_metadata'), $this->iptcdata(iptcparse($moreinfo['APP13'])), true); } if($imsize[0] && $imsize[1]) print ', '.$imsize[0].'×'.$imsize[1].' px'; } print "
    • "; } else print "
    • ".getMLText("document_deleted")."
    • "; $updatingUser = $latestContent->getUser(); print "
    • ".getMLText("uploaded_by")." getEmail())."\">".htmlspecialchars($updatingUser->getFullName())."
    • "; print "
    • ".getLongReadableDate($latestContent->getDate())."
    • "; print "
    • ".getMLText('status').": ".getOverallStatusText($status["status"]); if ( $status["status"]==S_DRAFT_REV || $status["status"]==S_DRAFT_APP || $status["status"]==S_IN_WORKFLOW || $status["status"]==S_EXPIRED ){ print "
      getDocument()->hasExpired()?" class=\"warning\" ":"").">".(!$latestContent->getDocument()->getExpires() ? getMLText("does_not_expire") : getMLText("expires").": ".getReadableDate($latestContent->getDocument()->getExpires())).""; } print "
    • "; print "
    \n"; $txt = $this->callHook('showVersionComment', $latestContent); if($txt) { echo $txt; } else { if($latestContent->getComment()) if($settings->_markdownComments) { $Parsedown = new Parsedown(); $comment = $Parsedown->text($latestContent->getComment()); print "
    ".$comment."
    "; } else { $comment = htmlspecialchars($latestContent->getComment()); print "

    ".$comment."

    "; } } print "
      \n"; $this->printVersionAttributes($folder, $latestContent); print "
    "; // print "
    "; $this->columnEnd(); $this->columnStart(4); if ($file_exists){ $items = array(); if($accessobject->check_controller_access('Download', array('action'=>'version'))) $items[] = array('link'=>$this->params['settings']->_httpRoot."op/op.Download.php?documentid=".$latestContent->getDocument()->getId()."&version=".$latestContent->getVersion(), 'icon'=>'download', 'label'=>'download'); if($accessobject->check_controller_access('ViewOnline', array('action'=>'run'))) if ($viewonlinefiletypes && (in_array(strtolower($latestContent->getFileType()), $viewonlinefiletypes) || in_array(strtolower($latestContent->getMimeType()), $viewonlinefiletypes))) $items[] = array('link'=>$this->params['settings']->_httpRoot."op/op.ViewOnline.php?documentid=".$latestContent->getDocument()->getId()."&version=". $latestContent->getVersion(), 'icon'=>'eye', 'label'=>'view_online', 'target'=>'_blank'); if($newitems = $this->callHook('extraVersionViews', $latestContent)) $items = array_merge($items, $newitems); if($items) { $this->showActions($items); } } $items = array(); if ($file_exists){ if($islatest && $accessobject->mayEditVersion()) { $items[] = array('link'=>$this->html_url('EditOnline', array('documentid'=>$latestContent->getDocument()->getId(), 'version'=>$latestContent->getVersion())), 'icon'=>'edit', 'label'=>'edit_version'); } } /* Only admin has the right to remove version in any case or a regular * user if enableVersionDeletion is on */ if($accessobject->mayRemoveVersion()) { $items[] = array('link'=>$this->html_url('RemoveVersion', array('documentid'=>$latestContent->getDocument()->getId(),'version'=>$latestContent->getVersion())), 'icon'=>'remove', 'label'=>'rm_version'); } if($islatest && $accessobject->mayOverwriteStatus()) { $items[] = array('link'=>$this->html_url('OverrideContentStatus', array('documentid'=>$latestContent->getDocument()->getId(),'version'=>$latestContent->getVersion())), 'icon'=>'align-justify', 'label'=>'change_status'); } if($workflowmode == 'traditional' || $workflowmode == 'traditional_only_approval') { // Allow changing reviewers/approvals only if not reviewed if($accessobject->maySetReviewersApprovers()) { $items[] = array('link'=>$this->html_url('SetReviewersApprovers', array('documentid'=>$latestContent->getDocument()->getId(),'version'=>$latestContent->getVersion())), 'icon'=>'edit', 'label'=>'change_assignments'); } } elseif($workflowmode == 'advanced') { if($accessobject->maySetWorkflow()) { $workflow = $latestContent->getWorkflow(); if(!$workflow) { $items[] = array('link'=>$this->html_url('SetWorkflow', array('documentid'=>$latestContent->getDocument()->getId(),'version'=>$latestContent->getVersion())), 'icon'=>'random', 'label'=>'set_workflow'); } } } if($accessobject->check_view_access('EditComment')) if($accessobject->mayEditComment()) { $items[] = array('link'=>$this->html_url('EditComment', array('documentid'=>$latestContent->getDocument()->getId(),'version'=>$latestContent->getVersion())), 'icon'=>'comment', 'label'=>'edit_comment'); } if($accessobject->check_view_access('EditAttributes')) if($accessobject->mayEditAttributes()) { $items[] = array('link'=>$this->html_url('EditAttributes', array('documentid'=>$latestContent->getDocument()->getId(),'version'=>$latestContent->getVersion())), 'icon'=>'edit', 'label'=>'edit_attributes'); } if(!$islatest) $items[] = array('link'=>$this->html_url('DocumentVersionDetail', array('documentid'=>$latestContent->getDocument()->getId(),'version'=>$latestContent->getVersion())), 'icon'=>'info', 'label'=>'details'); if($newitems = $this->callHook('extraVersionActions', $latestContent)) $items = array_merge($items, $newitems); if($items) { $this->showActions($items); } // echo "
    \n"; $this->columnEnd(); $this->rowEnd(); } /* }}} */ function show() { /* {{{ */ parent::show(); $this->callHook('preViewDocument'); $dms = $this->params['dms']; $user = $this->params['user']; $folder = $this->params['folder']; $document = $this->params['document']; $accessobject = $this->params['accessobject']; $viewonlinefiletypes = $this->params['viewonlinefiletypes']; $enableDropUpload = $this->params['enableDropUpload']; $enableownerrevapp = $this->params['enableownerrevapp']; $enableremoverevapp = $this->params['enableremoverevapp']; $workflowmode = $this->params['workflowmode']; $cachedir = $this->params['cachedir']; $conversionmgr = $this->params['conversionmgr']; $previewwidthlist = $this->params['previewWidthList']; $previewwidthdetail = $this->params['previewWidthDetail']; $previewconverters = $this->params['previewConverters']; $pdfconverters = $this->params['pdfConverters']; $documentid = $document->getId(); $currenttab = $this->params['currenttab']; $timeout = $this->params['timeout']; $xsendfile = $this->params['xsendfile']; $versions = $this->callHook('documentVersions', $document); if($versions === null) $versions = $document->getContent(); $this->htmlAddHeader(''."\n", 'css'); $this->htmlAddHeader(''."\n", 'js'); $this->htmlAddHeader(''."\n", 'js'); $this->htmlAddHeader(''."\n", 'js'); $this->htmlAddHeader(''."\n", 'js'); $this->htmlStartPage(getMLText("document_title", array("documentname" => htmlspecialchars($document->getName())))); $this->globalNavigation($folder); $this->contentStart(); $this->pageNavigation($this->getFolderPathHTML($folder, true, $document), "view_document", $document); echo $this->callHook('preContent'); if ($document->isLocked()) { $lockingUser = $document->getLockingUser(); $txt = $this->callHook('documentIsLocked', $document, $lockingUser); if(is_string($txt)) echo $txt; else { $this->warningMsg(getMLText("lock_message", array("email" => $lockingUser->getEmail(), "username" => htmlspecialchars($lockingUser->getFullName())))); } } /* Retrieve latest content and attacheѕ files */ $latestContent = $this->callHook('documentLatestContent', $document); if($latestContent === null) $latestContent = $document->getLatestContent(); $files = $document->getDocumentFiles($latestContent->getVersion()); $files = SeedDMS_Core_DMS::filterDocumentFiles($user, $files); /* Retrieve linked documents */ $links = $document->getDocumentLinks(); $links = SeedDMS_Core_DMS::filterDocumentLinks($user, $links, 'target'); /* Retrieve reverse linked documents */ $reverselinks = $document->getReverseDocumentLinks(); $reverselinks = SeedDMS_Core_DMS::filterDocumentLinks($user, $reverselinks, 'source'); $needwkflaction = false; $transitions = array(); if($workflowmode == 'traditional' || $workflowmode == 'traditional_only_approval') { } elseif($workflowmode == 'advanced') { $workflow = $latestContent->getWorkflow(); if($workflow) { if($workflowstate = $latestContent->getWorkflowState()) { $transitions = $workflow->getNextTransitions($workflowstate); $needwkflaction = $latestContent->needsWorkflowAction($user); } else { $this->warningMsg(getMLText('workflow_in_unknown_state')); } } } if($needwkflaction) { $this->infoMsg(getMLText('needs_workflow_action')); } $reviewStatus = $latestContent->getReviewStatus(); $approvalStatus = $latestContent->getApprovalStatus(); $this->rowStart(); $this->columnStart(4); $txt = $this->callHook('startLeftColumn', $document); if(is_string($txt)) echo $txt; $this->documentInfos(); if($accessobject->check_controller_access('ViewOnline', array('action'=>'run'))) { $this->preview(); } $this->columnEnd(); $this->columnStart(8); $txt = $this->callHook('startRightColumn', $document); if(is_string($txt)) echo $txt; ?>
    contentContainerStart(); print getMLText('document_content_missing'); $this->contentContainerEnd(); $this->contentEnd(); $this->htmlEndPage(); exit; } $checksum = SeedDMS_Core_File::checksum($dms->contentDir.$latestContent->getPath()); if($checksum != $latestContent->getChecksum()) { $this->errorMsg(getMLText('wrong_checksum')); } $txt = $this->callHook('preLatestVersionTab', $latestContent); if(is_string($txt)) echo $txt; $this->contentContainerStart(); $previewer = new SeedDMS_Preview_Previewer($cachedir, $previewwidthdetail, $timeout, $xsendfile); if($conversionmgr) $previewer->setConversionMgr($conversionmgr); else $previewer->setConverters($previewconverters); $this->showVersionDetails($latestContent, $previewer, true); $this->contentContainerEnd(); if($user->isAdmin()) { $this->contentHeading(getMLText("status")); $this->contentContainerStart(); $statuslog = $latestContent->getStatusLog(); echo ""; echo "\n"; echo ""; foreach($statuslog as $entry) { if($suser = $dms->getUser($entry['userID'])) $fullname = htmlspecialchars($suser->getFullName()); else $fullname = "--"; echo "\n"; } print "\n
    ".getMLText('date')."/".getMLText('user')."".getMLText('status')."".getMLText('comment')."
    ".getLongReadableDate($entry['date'])."
    ".$fullname."
    ".getOverallStatusText($entry['status'])."".htmlspecialchars($entry['comment'])."
    \n"; $this->contentContainerEnd(); } ?>
    0) || (is_array($approvalStatus) && count($approvalStatus)>0)) { ?>
    hasExpired()) $this->warningMsg(getMLText('cannot_revapp_expired_docs')); $this->rowStart(); /* Just check fo an exting reviewStatus, even workflow mode is set * to traditional_only_approval. There may be old documents which * are still in S_DRAFT_REV. */ if (/*$workflowmode != 'traditional_only_approval' &&*/ is_array($reviewStatus) && count($reviewStatus)>0) { $this->columnStart(6); // $this->contentContainerStart(); print "".getMLText('reviewers').""; print "\n"; print "\n"; print "\n"; print "\n"; // print ""; print "\n"; print "\n"; print "\n"; foreach ($reviewStatus as $r) { $class = ''; switch($r['status']) { case '-1': $class = 'error'; break; case '1': $class = 'success'; break; } $required = null; $is_reviewer = false; $accesserr = ''; switch ($r["type"]) { case 0: // Reviewer is an individual. $required = $dms->getUser($r["required"]); if (!is_object($required)) { $reqName = getMLText("unknown_user")." '".$r["required"]."'"; } else { $reqName = " ".htmlspecialchars($required->getFullName()." (".$required->getLogin().")"); if($user->isAdmin()) { if($document->getAccessMode($required) < M_READ || $latestContent->getAccessMode($required) < M_READ) $accesserr = getMLText("access_denied"); elseif(is_object($required) && $required->isDisabled()) $accesserr = getMLText("login_disabled_title"); } if($required->getId() == $user->getId()/* && ($user->getId() != $owner->getId() || $enableownerrevapp == 1)*/) $is_reviewer = true; } break; case 1: // Reviewer is a group. $required = $dms->getGroup($r["required"]); if (!is_object($required)) { $reqName = getMLText("unknown_group")." '".$r["required"]."'"; } else { $reqName = " ".htmlspecialchars($required->getName()); if($user->isAdmin()) { $grpusers = $required->getUsers(); if(!$grpusers) $accesserr = getMLText("no_group_members"); } if($required->isMember($user)/* && ($user->getId() != $owner->getId() || $enableownerrevapp == 1)*/) $is_reviewer = true; } break; } if($user->isAdmin() || $r["status"] > -2) { print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; } } print "
    ".getMLText("name")."".getMLText("last_update").", ".getMLText("comment")."".getMLText("comment")."".getMLText("status")."
    ".$reqName."".getLongReadableDate($r["date"])." - "; /* $updateUser is the user who has done the review */ $updateUser = $dms->getUser($r["userID"]); print (is_object($updateUser) ? htmlspecialchars($updateUser->getFullName()." (".$updateUser->getLogin().")") : "unknown user id '".$r["userID"]."'")."
    "; print htmlspecialchars($r["comment"]); if($r['file']) { echo "
    "; if($accessobject->check_controller_access('Download', array('action'=>'run'))) { echo "params['settings']->_httpRoot."op/op.Download.php?documentid=".$latestContent->getDocument()->getId()."&reviewlogid=".$r['reviewLogID']."\" class=\"btn btn-secondary btn-mini\"> ".getMLText('download').""; } } print "
    "; if($class) echo " "; print getReviewStatusText($r["status"])."
      "; if($accesserr) echo "
    • ".$accesserr."
    • "; if($accessobject->mayReview()) { if ($is_reviewer) { if ($r["status"]==0) { print $this->html_link('ReviewDocument', array('documentid'=>$latestContent->getDocument()->getId(), 'version'=>$latestContent->getVersion(), 'reviewid'=>$r['reviewID']), array('class'=>'btn btn-mini btn-primary'), getMLText("add_review"), false, true, array('
    • ', '
    • ')); } elseif ($accessobject->mayUpdateReview($updateUser) && (($r["status"]==1)||($r["status"]==-1))){ print $this->html_link('ReviewDocument', array('documentid'=>$latestContent->getDocument()->getId(), 'version'=>$latestContent->getVersion(), 'reviewid'=>$r['reviewID']), array('class'=>'btn btn-mini btn-primary'), getMLText("edit"), false, true, array('
    • ', '
    • ')); } } } if($enableremoverevapp && $user->isAdmin() && ($r['status'] == 1 || $r['status'] == -1)) echo '
    • '; print "
    "; // $this->contentContainerEnd(); $this->columnEnd(); } $this->columnStart(6); // $this->contentContainerStart(); print "".getMLText('approvers').""; print "\n"; if (is_array($approvalStatus) && count($approvalStatus)>0) { print "\n"; print "\n"; print "\n"; // print ""; print "\n"; print "\n"; print "\n"; foreach ($approvalStatus as $a) { $class = ''; switch($a['status']) { case '-1': $class = 'error'; break; case '1': $class = 'success'; break; } $required = null; $is_approver = false; $accesserr = ''; switch ($a["type"]) { case 0: // Approver is an individual. $required = $dms->getUser($a["required"]); if (!is_object($required)) { $reqName = getMLText("unknown_user")." '".$a["required"]."'"; } else { $reqName = " ".htmlspecialchars($required->getFullName()." (".$required->getLogin().")"); if($user->isAdmin()) { if($document->getAccessMode($required) < M_READ || $latestContent->getAccessMode($required) < M_READ) $accesserr = getMLText("access_denied"); elseif(is_object($required) && $required->isDisabled()) $accesserr = getMLText("login_disabled_title"); } if($required->getId() == $user->getId()) $is_approver = true; } break; case 1: // Approver is a group. $required = $dms->getGroup($a["required"]); if (!is_object($required)) { $reqName = getMLText("unknown_group")." '".$a["required"]."'"; } else { $reqName = " ".htmlspecialchars($required->getName()); if($user->isAdmin()) { $grpusers = $required->getUsers(); if(!$grpusers) $accesserr = getMLText("no_group_members"); } if($required->isMember($user)/* && ($user->getId() != $owner->getId() || $enableownerrevapp == 1)*/) $is_approver = true; } break; } if($user->isAdmin() || $a["status"] > -2) { print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; } } } print "
    ".getMLText("name")."".getMLText("last_update").", ".getMLText("comment")."".getMLText("comment")."".getMLText("status")."
    ".$reqName."".getLongReadableDate($a["date"])." - "; /* $updateUser is the user who has done the approval */ $updateUser = $dms->getUser($a["userID"]); print (is_object($updateUser) ? htmlspecialchars($updateUser->getFullName()." (".$updateUser->getLogin().")") : "unknown user id '".$a["userID"]."'")."
    "; print htmlspecialchars($a["comment"]); if($a['file']) { echo "
    "; if($accessobject->check_controller_access('Download', array('action'=>'run'))) { echo "params['settings']->_httpRoot."op/op.Download.php?documentid=".$latestContent->getDocument()->getId()."&approvelogid=".$a['approveLogID']."\" class=\"btn btn-secondary btn-mini\"> ".getMLText('download').""; } } echo "
    "; if($class) echo " "; print getApprovalStatusText($a["status"])."
      "; if($accesserr) echo "
    • ".$accesserr."
    • "; if($accessobject->mayApprove()) { if ($is_approver) { if ($a['status'] == 0) { print $this->html_link('ApproveDocument', array('documentid'=>$latestContent->getDocument()->getId(), 'version'=>$latestContent->getVersion(), 'approveid'=>$a['approveID']), array('class'=>'btn btn-mini btn-primary'), getMLText("add_approval"), false, true, array('
    • ', '
    • ')); } elseif ($accessobject->mayUpdateApproval($updateUser) && (($a["status"]==1)||($a["status"]==-1))){ print $this->html_link('ApproveDocument', array('documentid'=>$latestContent->getDocument()->getId(), 'version'=>$latestContent->getVersion(), 'approveid'=>$a['approveID']), array('class'=>'btn btn-mini btn-primary'), getMLText("edit"), false, true, array('
    • ', '
    • ')); } } } if($enableremoverevapp && $user->isAdmin() && ($a['status'] == 1 || $a['status'] == -1)) echo '
    • '; print "
    "; print "
    \n"; // $this->contentContainerEnd(); $this->columnEnd(); $this->rowEnd(); if($user->isAdmin() || $user->getId() == $document->getOwner()->getId()) { $this->rowStart(); /* Check for an existing review log, even if the workflowmode * is set to traditional_only_approval. There may be old documents * that still have a review log if the workflow mode has been * changed afterwards. */ if($latestContent->getReviewStatus(10) /*$workflowmode != 'traditional_only_approval'*/) { $this->columnStart(6); $this->printProtocol($latestContent, 'review'); $this->columnEnd(); } $this->columnStart(6); $this->printProtocol($latestContent, 'approval'); $this->columnEnd(); $this->rowEnd(); } ?>
    triggerWorkflowTransitionIsAllowed($user, $transition)) { $user_is_involved = true; } } ?>
    rowStart(); if ($user_is_involved && $accessobject->check_view_access('WorkflowGraph')) $this->columnStart(6); else $this->columnStart(12); $this->contentContainerStart(); if($user->isAdmin()) { if(!$workflowstate || SeedDMS_Core_DMS::checkIfEqual($workflow->getInitState(), $workflowstate)) { print "
    html_url("RemoveWorkflowFromDocument")."\" method=\"get\">getDocument()->getId()."\" />getVersion()."\" />
    "; } else { print "
    html_url("RewindWorkflow")."\" method=\"get\">getDocument()->getId()."\" />getVersion()."\" />
    "; } } echo "

    ".htmlspecialchars($workflow->getName())."

    "; if($parentworkflow = $latestContent->getParentWorkflow()) { echo "

    Sub workflow of '".htmlspecialchars($parentworkflow->getName())."'

    "; } echo "
    ".getMLText('current_state').": ".($workflowstate ? htmlspecialchars($workflowstate->getName()) : htmlspecialchars(getMLText('workflow_in_unknown_state')))."
    "; echo "\n"; echo ""; echo ""; foreach($transitions as $transition) { $nextstate = $transition->getNextState(); $docstatus = $nextstate->getDocumentStatus(); echo ""; } echo ""; echo ""; echo ""; foreach($transitions as $transition) { $action = $transition->getAction(); echo ""; } echo ""; echo ""; echo ""; foreach($transitions as $transition) { $transusers = $transition->getUsers(); echo ""; } echo ""; echo ""; echo ""; foreach($transitions as $transition) { $transgroups = $transition->getGroups(); echo ""; } echo ""; echo ""; echo ""; foreach($transitions as $transition) { echo ""; } echo ""; echo ""; echo ""; $allowedtransitions = array(); foreach($transitions as $transition) { echo ""; } echo ""; echo "
    ".getMLText('next_state').": ".htmlspecialchars($nextstate->getName())."
    ".getMLText('action').":".getMLText('action_'.strtolower($action->getName()), array(), htmlspecialchars($action->getName()))."
    ".getMLText('users').":"; foreach($transusers as $transuser) { $u = $transuser->getUser(); echo htmlspecialchars($u->getFullName()); if($document->getAccessMode($u) < M_READ) { echo " (no access)"; } echo "
    "; } echo "
    ".getMLText('groups').":"; foreach($transgroups as $transgroup) { $g = $transgroup->getGroup(); echo getMLText('at_least_n_users_of_group', array("number_of_users" => $transgroup->getNumOfUsers(), "group" => htmlspecialchars($g->getName()))); if ($document->getGroupAccessMode($g) < M_READ) { echo " (no access)"; } echo "
    "; } echo "
    ".getMLText('users_done_work').":"; if($latestContent->executeWorkflowTransitionIsAllowed($transition)) { /* If this is reached, then the transition should have been executed * but for some reason the next state hasn't been reached. This can * be caused, if a transition which was previously already executed * is about to be executed again. E.g. there was already a transition * T1 from state S1 to S2 triggered by user U1. * Then there was a second transition T2 from * S2 back to S1. If the state S1 has been reached again, then * executeWorkflowTransitionIsAllowed() will think that T1 could be * executed because there is already a log entry saying, that U1 * has triggered the workflow. */ echo "Done "; } $wkflogs = $latestContent->getWorkflowLog($transition); foreach($wkflogs as $wkflog) { $loguser = $wkflog->getUser(); echo htmlspecialchars($loguser->getFullName()); $names = array(); foreach($loguser->getGroups() as $loggroup) { $names[] = htmlspecialchars($loggroup->getName()); } if($names) echo " (".implode(", ", $names).")"; echo " - "; echo getLongReadableDate($wkflog->getDate()); echo "
    "; } echo "
    "; if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { $action = $transition->getAction(); print "
    html_url("TriggerWorkflow")."\" method=\"get\">getDocument()->getId()."\" />getVersion()."\" />getID()."\" />getName()), array(), htmlspecialchars($action->getName()))."\" />
    "; $allowedtransitions[] = $transition; } echo "
    "; $workflows = $dms->getAllWorkflows(); if($workflows) { $subworkflows = array(); foreach($workflows as $wkf) { if($workflowstate && ($wkf->getInitState()->getID() == $workflowstate->getID())) { if($workflow->getID() != $wkf->getID()) { $subworkflows[] = $wkf; } } } if($subworkflows) { echo "
    html_url("RunSubWorkflow")."\" method=\"get\">getDocument()->getId()."\" />getVersion()."\" />"; echo ""; echo ""; echo "
    "; } } /* If in a sub workflow, the check if return the parent workflow * is possible. */ if($parentworkflow = $latestContent->getParentWorkflow()) { $states = $parentworkflow->getStates(); foreach($states as $state) { /* Check if the current workflow state is also a state in the * parent workflow */ if($latestContent->getWorkflowState()->getID() == $state->getID()) { echo "Switching from sub workflow '".htmlspecialchars($workflow->getName())."' into state ".$state->getName()." of parent workflow '".htmlspecialchars($parentworkflow->getName())."' is possible
    "; /* Check if the transition from the state where the sub workflow * starts into the current state is also allowed in the parent * workflow. Checking at this point is actually too late, because * the sub workflow shouldn't be entered in the first place, * but that is difficult to check. */ /* If the init state has not been left, return is always possible */ if($workflow->getInitState()->getID() == $latestContent->getWorkflowState()->getID()) { echo "Initial state of sub workflow has not been left. Return to parent workflow is possible
    "; echo "
    html_url("ReturnFromSubWorkflow")."\" method=\"get\">getDocument()->getId()."\" />getVersion()."\" />"; echo ""; echo "
    "; } else { /* Get a transition from the last state in the parent workflow * (which is the initial state of the sub workflow) into * current state. */ echo "Check for transition from ".$workflow->getInitState()->getName()." into ".$latestContent->getWorkflowState()->getName()." is possible in parentworkflow ".$parentworkflow->getID()."
    "; $transitions = $parentworkflow->getTransitionsByStates($workflow->getInitState(), $latestContent->getWorkflowState()); if($transitions) { echo "Found transitions in workflow ".$parentworkflow->getID()."
    "; foreach($transitions as $transition) { if($latestContent->triggerWorkflowTransitionIsAllowed($user, $transition)) { echo "Triggering transition is allowed
    "; echo "
    html_url("ReturnFromSubWorkflow")."\" method=\"get\">getDocument()->getId()."\" />getVersion()."\" />getID()."\" />"; echo ""; echo "
    "; } } } } } } } $this->contentContainerEnd(); $this->columnEnd(); if ($user_is_involved && $accessobject->check_view_access('WorkflowGraph')) { $this->columnStart(6); ?> columnEnd(); } $this->rowEnd(); $wkflogs = $latestContent->getWorkflowLog(); if($wkflogs) { $this->rowStart(); $this->columnStart(12); $this->contentHeading(getMLText("workflow_log")); $this->contentContainerStart(); echo ""; echo "\n"; echo ""; foreach($wkflogs as $wkflog) { echo ""; echo ""; echo ""; $loguser = $wkflog->getUser(); echo ""; echo ""; echo ""; } print "\n
    ".getMLText('date')."".getMLText('action')."".getMLText('user')."".getMLText('comment')."
    ".getLongReadableDate($wkflog->getDate())."".htmlspecialchars(getMLText('action_'.strtolower($wkflog->getTransition()->getAction()->getName()), array(), $wkflog->getTransition()->getAction()->getName()))."".htmlspecialchars($loguser->getFullName())."".htmlspecialchars($wkflog->getComment())."
    \n"; $this->contentContainerEnd(); $this->columnEnd(); $this->rowEnd(); } ?>
    1) { ?>
    rowStart(); $this->columnStart(9); ?>
    getID()."\"" : "") ?>>
    columnEnd(); $this->columnStart(3); if($accessobject->check_controller_access('AddFile')) { if ($document->getAccessMode($user) >= M_READWRITE){ if($enableDropUpload){ ?>
    html_link('AddFile', array('documentid'=>$documentid), array(), getMLText('drop_files_here_or_click'), false, true); ?>
    html_link('AddFile', array('documentid'=>$documentid), array('class'=>'btn btn-primary'), getMLText("add"), false, true)."\n"; } } } $this->columnEnd(); $this->rowEnd(); ?>
    $tab) { echo '
    '; echo $tab['content']; echo "
    \n"; } } ?>
    isAdmin()) { $this->contentHeading(getMLText("timeline")); $this->printTimelineHtml(300); } $this->columnEnd(); $this->rowEnd(); echo $this->callHook('postContent'); $this->contentEnd(); $this->htmlEndPage(); } /* }}} */ } ?>