'."\n";
$this->rowStart();
$this->columnStart(12);
echo $this->errorMsg("This page contains missing translations in the selected language. Please help to improve SeedDMS and provide the translation.");
echo "
";
echo "
Key
engl. Text
Your translation
\n";
foreach($MISSING_LANG as $key=>$lang) {
echo "
\n";
return;
} /* }}} */
private function calendarNavigationBar($d){ /* {{{ */
$accessobject = $this->params['accessobject'];
$menuitems = array();
if (!$this->params['user']->isGuest())
$menuitems['addevent'] = array('link'=>$this->params['settings']->_httpRoot."out/out.AddEvent.php", 'label'=>getMLText('add_event'));
/* Do not use $this->callHook() because $menuitems must be returned by the the
* first hook and passed to next hook. $this->callHook() will just pass
* the menuitems to each single hook. Hence, the last hook will win.
*/
$hookObjs = $this->getHookObjects();
foreach($hookObjs as $hookObj) {
if (method_exists($hookObj, 'calendarNavigationBar')) {
$menuitems = $hookObj->calendarNavigationBar($this, $menuitems);
}
}
self::showNavigationBar($menuitems);
} /* }}} */
function pageList($pageNumber, $totalPages, $baseURI, $params, $dataparams=[]) { /* {{{ */
$maxpages = 25; // skip pages when more than this is shown
$range = 2; // pages left and right of current page
if (!is_numeric($pageNumber) || !is_numeric($totalPages) || $totalPages<2) {
return;
}
// Construct the basic URI based on the $_GET array. One could use a
// regular expression to strip out the pg (page number) variable to
// achieve the same effect. This seems to be less haphazard though...
$resultsURI = $baseURI;
unset($params['pg']);
$first=true;
if($params) {
$resultsURI .= '?'.http_build_query($params);
$first=false;
}
$datastr = '';
if($dataparams) {
$datastr .= ' ';
foreach($dataparams as $k=>$v)
$datastr .= 'data-'.$k.'="'.$v.'"';
}
echo "";
return;
} /* }}} */
function contentContainer($content) { /* {{{ */
echo "
';
}
} /* }}} */
/**
* Get attributes for a button opening a modal box
*
* @param array $config contains elements
* target: id of modal box
* remote: URL of data to be loaded into box
* @return string
*/
function getModalBoxLinkAttributes($config) { /* {{{ */
$attrs = array();
$attrs[] = array('data-target', '#'.$config['target']);
if(isset($config['remote'])) {
$attrs[] = array('href', $config['remote']);
$attrs[] = array('data-remote', $config['remote']);
}
$attrs[] = array('data-toggle', 'modal');
$attrs[] = array('role', 'button');
if(isset($config['class'])) {
if($config['class'])
$attrs[] = array('class', $config['class']);
} else
$attrs[] = array('class', 'btn');
return $attrs;
} /* }}} */
/**
* Get html for button opening a modal box
*
* @param array $config contains elements
* target: id of modal box
* remote: URL of data to be loaded into box
* title: text on button
* @return string
*/
function getModalBoxLink($config) { /* {{{ */
// $content = '';
// $content .= "$attrval)
$content .= ' '.$attrname.'="'.$attrval.'"';
}
$content .= ">".$config['title']."\n";
return $content;
} /* }}} */
/**
* Get html for a modal box with buttons
*
* @param array $config contains elements
* id: id of modal box (must match target of getModalBoxLink())
* title: title of modal box
* content: content to be shown in the body of the box. Can be left
* empty if the body is loaded from the remote link passed to the button
* to open this box.
* buttons: array of buttons, each having a title and an optional id
* @return string
*/
function getModalBox($config) { /* {{{ */
$content = '';
$content .= '
\n";
if(!$skiptree)
$content .= $this->getModalBox(
array(
'id' => 'docChooser'.$formid,
'title' => getMLText('choose_target_document'),
'buttons' => array(
array('title'=>getMLText('close'))
)
));
return $content;
} /* }}} */
function printDocumentChooserHtml($formName) { /* {{{ */
echo self::getDocumentChooserHtml($formName);
} /* }}} */
/**
* This function is deprecated. Don't use it anymore. There is a generic
* folderSelected and documentSelected function in application.js
* If you extra functions to be called then define them in your own js code
*/
function printDocumentChooserJs($form, $formname='') { /* {{{ */
if(!$formname)
$formname = "docid";
$formid = md5($formname.$form);
?>
function documentSelected(id, name) {
$('#').val(id);
$('#choosedocsearch').val(name);
$('#docChooser').modal('hide');
}
function folderSelected(id, name) {
}
printDocumentChooserHtml($form);
?>
getID() : "") ."\" data-target-highlight=\"choosefoldersearch".$formid."\">";
$content .= "
\n";
} /* }}} */
function ___exitError($pagetitle, $error, $noexit=false, $plain=false) { /* {{{ */
/* This is just a hack to prevent creation of js files in an error
* case, because they will contain this error page again. It would be much
* better, if there was extra error() function similar to show() and calling
* $view() after setting the action to 'error'. This would also allow to
* set separate error pages for each view.
*/
if(!$noexit && isset($_REQUEST['action'])) {
if(in_array($_REQUEST['action'], array('js', 'footerjs'))) {
exit;
}
if($_REQUEST['action'] == 'webrootjs') {
$this->webrootjs();
exit;
}
}
if(!$plain) {
$this->htmlStartPage($pagetitle);
$this->globalNavigation();
$this->contentStart();
}
$html = '';
$html .= "
".getMLText('error')."!
";
$html .= htmlspecialchars($error);
$this->errorMsg($html);
if(!$plain) {
print "";
$this->contentEnd();
$this->htmlEndPage();
}
add_log_line(" UI::exitError error=".$error." pagetitle=".$pagetitle, PEAR_LOG_ERR);
if($noexit)
return;
exit;
} /* }}} */
function printNewTreeNavigation($folderid=0, $accessmode=M_READ, $showdocs=0, $formid='form1', $expandtree=0, $orderby='') { /* {{{ */
$this->printNewTreeNavigationHtml($folderid, $accessmode, $showdocs, $formid, $expandtree, $orderby);
?>
\n";
echo "\n";
} /* }}} */
/**
* Create a tree of folders using jqtree.
*
* The tree can contain folders only or include documents.
*
* @param integer $folderid current folderid. If set the tree will be
* folded out and the all folders in the path will be visible
* @param integer $accessmode use this access mode when retrieving folders
* and documents shown in the tree
* @param boolean $showdocs set to true if tree shall contain documents
* as well.
* @param integer $expandtree level to which the tree shall be opened
* @param boolean $partialtree set to true if the given folder is the start folder
*/
function printNewTreeNavigationJs($folderid=0, $accessmode=M_READ, $showdocs=0, $formid='form1', $expandtree=0, $orderby='', $partialtree=false) { /* {{{ */
function jqtree($path, $folder, $user, $accessmode, $showdocs=1, $expandtree=0, $orderby='', $level=0) { /* {{{ */
$orderdir = (isset($orderby[1]) ? ($orderby[1] == 'd' ? 'desc' : 'asc') : 'asc');
if($path/* || $expandtree>=$level*/) {
if($path)
$pathfolder = array_shift($path);
$children = array();
if($expandtree) {
$subfolders = $folder->getSubFolders(isset($orderby[0]) ? $orderby[0] : '', $orderdir);
$subfolders = SeedDMS_Core_DMS::filterAccess($subfolders, $user, $accessmode);
} else {
$subfolders = array($pathfolder);
}
foreach($subfolders as $subfolder) {
$node = array('label'=>$subfolder->getName(), 'id'=>$subfolder->getID(), 'load_on_demand'=>(1 && ($subfolder->hasSubFolders() || ($subfolder->hasDocuments() && $showdocs))) ? true : false, 'is_folder'=>true);
/* if the subfolder is in the path then further unfold the tree. */
if(/*$expandtree>=$level ||*/ $path && ($path[0]->getID() == $subfolder->getID())) {
$node['children'] = jqtree($path, $subfolder, $user, $accessmode, $showdocs, $expandtree, $orderby, $level+1);
if($showdocs) {
$documents = $subfolder->getDocuments(isset($orderby[0]) ? $orderby[0] : '', $orderdir);
$documents = SeedDMS_Core_DMS::filterAccess($documents, $user, $accessmode);
foreach($documents as $document) {
$node2 = array('label'=>$document->getName(), 'id'=>$document->getID(), 'load_on_demand'=>false, 'is_folder'=>false);
$node['children'][] = $node2;
}
}
}
$children[] = $node;
}
return $children;
} else {
$subfolders = $folder->getSubFolders(isset($orderby[0]) ? $orderby[0] : '', $orderdir);
$subfolders = SeedDMS_Core_DMS::filterAccess($subfolders, $user, $accessmode);
$children = array();
foreach($subfolders as $subfolder) {
$node = array('label'=>$subfolder->getName(), 'id'=>$subfolder->getID(), 'load_on_demand'=>($subfolder->hasSubFolders() || ($subfolder->hasDocuments() && $showdocs)) ? true : false, 'is_folder'=>true);
$children[] = $node;
}
return $children;
}
return array();
} /* }}} */
$orderdir = (isset($orderby[1]) ? ($orderby[1] == 'd' ? 'desc' : 'asc') : 'asc');
if($folderid && ($folder = $this->params['dms']->getFolder($folderid))) {
$path = null;
if(!$partialtree) {
$path = $folder->getPath();
/* Get the first folder (root folder) of path */
$folder = array_shift($path);
}
$node = array('label'=>$folder->getName(), 'id'=>$folder->getID(), 'load_on_demand'=>false, 'is_folder'=>true);
if(!$folder->hasSubFolders()) {
$node['load_on_demand'] = true;
$node['children'] = array();
} else {
$node['children'] = jqtree($path, $folder, $this->params['user'], $accessmode, $showdocs, 1 /*$expandtree*/, $orderby, 0);
if($showdocs) {
$documents = $folder->getDocuments(isset($orderby[0]) ? $orderby[0] : '', $orderdir);
$documents = SeedDMS_Core_DMS::filterAccess($documents, $this->params['user'], $accessmode);
foreach($documents as $document) {
$node2 = array('label'=>$document->getName(), 'id'=>$document->getID(), 'load_on_demand'=>false, 'is_folder'=>false);
$node['children'][] = $node2;
}
}
}
/* Nasty hack to remove the highest folder */
if(isset($this->params['remove_root_from_tree']) && $this->params['remove_root_from_tree']) {
foreach($node['children'] as $n)
$tree[] = $n;
} else {
$tree[] = $node;
}
} else {
if($root = $this->params['dms']->getFolder($this->params['rootfolderid']))
$tree = array(array('label'=>$root->getName(), 'id'=>$root->getID(), 'load_on_demand'=>false, 'is_folder'=>true));
else
$tree = array();
}
?>
var data = ;
$(function() {
const $tree = $('#jqtree');
$tree.tree({
// saveState: false,
selectable: false,
data: data,
saveState: 'jqtree',
openedIcon: $(''),
closedIcon: $(''),
/*
_onCanSelectNode: function(node) {
if(node.is_folder) {
folderSelected= $formid ?>(node.id, node.name);
treeFolderSelected('= $formid ?>', node.id, node.name);
} else {
documentSelected= $formid ?>(node.id, node.name);
treeDocumentSelected('= $formid ?>', node.id, node.name);
}
},
*/
autoOpen: false,
drapAndDrop: true,
onCreateLi: function(node, $li) {
// Add 'icon' span before title
if(node.is_folder)
$li.find('.jqtree-title').prepend(' ').attr('data-name', node.name).attr('rel', 'folder_' + node.id).attr('formtoken', '').attr('data-uploadformtoken', '').attr('data-droptarget', 'folder_' + node.id).addClass('droptarget');
else
$li.find('.jqtree-title').prepend(' ');
}
});
// Unfold node for currently selected folder
$('#jqtree').tree('selectNode', $('#jqtree').tree('getNodeById', ), false, true);
$('#jqtree').on(
'tree.click',
function(event) {
var node = event.node;
if(!node)
return;
if(node.is_folder) {
$('#jqtree').tree('openNode', node);
// event.preventDefault();
if(typeof node.fetched == 'undefined') {
node.fetched = true;
$(this).tree('loadDataFromUrl', node, function () {
$(this).tree('openNode', node);
});
}
/* folderSelectedXXXX() can still be set, e.g. for the main tree
* to update the folder list.
*/
if (typeof folderSelected= $formid ?> === 'function') {
folderSelected= $formid ?>(node.id, node.name);
}
treeFolderSelected('= $formid ?>', node.id, node.name);
} else {
if (typeof documentSelected= $formid ?> === 'function') {
documentSelected= $formid ?>(node.id, node.name);
}
treeDocumentSelected('= $formid ?>', node.id, node.name);
}
}
);
$('#jqtree').on(
'tree.contextmenu',
function(event) {
// The clicked node is 'event.node'
var node = event.node;
if(typeof node.fetched == 'undefined') {
node.fetched = true;
$(this).tree('loadDataFromUrl', node);
}
$(this).tree('openNode', node);
}
);
$("#jqtree").on('dragenter', function (e) {
attr_rel = $(e.srcElement).attr('rel');
if(typeof attr_rel == 'undefined')
return;
target_type = attr_rel.split("_")[0];
target_id = attr_rel.split("_")[1];
var node = $(this).tree('getNodeById', parseInt(target_id));
if(typeof node.fetched == 'undefined') {
node.fetched = true;
$(this).tree('loadDataFromUrl', node, function() {$(this).tree('openNode', node);});
}
});
});
params['dms'];
$user = $this->params['user'];
$folder = $dms->getFolder($folderid);
if (!is_object($folder)) return '';
$subfolders = $folder->getSubFolders($orderby);
$subfolders = SeedDMS_Core_DMS::filterAccess($subfolders, $user, M_READ);
$tree = array();
foreach($subfolders as $subfolder) {
$loadondemand = $subfolder->hasSubFolders() || ($subfolder->hasDocuments() && $showdocs);
$level = array('label'=>$subfolder->getName(), 'id'=>$subfolder->getID(), 'load_on_demand'=>$loadondemand, 'is_folder'=>true);
if(!$subfolder->hasSubFolders())
$level['children'] = array();
$tree[] = $level;
}
if($showdocs) {
$documents = $folder->getDocuments($orderby);
$documents = SeedDMS_Core_DMS::filterAccess($documents, $user, M_READ);
foreach($documents as $document) {
$level = array('label'=>$document->getName(), 'id'=>$document->getID(), 'load_on_demand'=>false, 'is_folder'=>false);
$tree[] = $level;
}
}
header('Content-Type: application/json');
echo json_encode($tree);
} /* }}} */
/**
* Deprecated!
*/
function __printTreeNavigation($folderid, $showtree){ /* {{{ */
if ($showtree==1){
$this->contentHeading("params['settings']->_httpRoot."out/out.ViewFolder.php?folderid=". $folderid."&showtree=0\">", true);
$this->contentContainerStart();
?>
printNewTreeNavigation($folderid, M_READ, 0, '');
$this->contentContainerEnd();
} else {
$this->contentHeading("params['settings']->_httpRoot."out/out.ViewFolder.php?folderid=". $folderid."&showtree=1\">", true);
}
} /* }}} */
/**
* Print clipboard in div container
*
* @param array clipboard
*/
function printClipboard($clipboard, $previewer){ /* {{{ */
echo "
";
if(!empty($extracontent['columns_last'])) {
foreach($extracontent['columns_last'] as $col)
$content .= '
'.$col.'
';
}
if(!$skipcont)
$content .= $this->documentListRowEnd($document);
}
return $content;
} /* }}} */
/**
* Start the row for a folder in list of documents and folders
*
* This method creates the starting tr tag for a new table row containing
* a folder list entry. The tr tag contains various attributes which are
* used for removing the table line and to make drap&drop work.
*
* id=table-row-folder- : used for identifying the row when removing the table
* row after deletion of the folder by clicking on the delete button in that table
* row.
* data-droptarget=folder_ : identifies the folder represented by this row
* when it used as a target of the drag&drop operation.
* If an element (either a file or a dragged item) is dropped on this row, the
* data-droptarget will be evaluated to identify the underlying dms object.
* Dropping a file on a folder will upload that file into the folder. Droping
* an item (which is currently either a document or a folder) from the page will
* move that item into the folder.
* rel=folder_ : This data is put into drag data when a drag starts. When the
* item is dropped on some other item this data will identify the source object.
* The attributes data-droptarget and rel are usually equal. At least there is
* currently no scenario where they are different.
* formtoken= : token made of key 'movefolder'
* formtoken is also placed in the drag data just like the value of attibute 'rel'.
* This is always set to a value made of 'movefolder'.
* data-uploadformtoken= : token made of key 'adddocument'
* class=table-row-folder : The class must have a class named 'table-row-folder' in
* order to be draggable and to extract the drag data from the attributes 'rel' and
* 'formtoken'
*
* @param object $folder
* @return string starting tr tag for a table
*/
function folderListRowStart($folder, $class='') { /* {{{ */
if($class) {
if($class == 'error')
$class = 'table-danger';
else
$class = 'table-'.$class;
}
return "
";
if($enableRecursiveCount) {
if($user->isAdmin()) {
/* No need to check for access rights in countChildren() for
* admin. So pass 0 as the limit.
*/
$cc = $subFolder->countChildren($user, 0);
if($cc['folder_count'])
$content .= ' '.$cc['folder_count']." ";
if($cc['document_count'])
$content .= ' '.$cc['document_count'];
} else {
$cc = $subFolder->countChildren($user, $maxRecursiveCount);
if($maxRecursiveCount > 5000)
$rr = 100.0;
else
$rr = 10.0;
if($cc['folder_count'])
$content .= ' '.(!$cc['folder_precise'] ? '~'.(round($cc['folder_count']/$rr)*$rr) : $cc['folder_count'])." ";
if($cc['document_count'])
$content .= ' '.(!$cc['document_precise'] ? '~'.(round($cc['document_count']/$rr)*$rr) : $cc['document_count']);
}
} else {
/* FIXME: the following is very inefficient for just getting the number of
* subfolders and documents. Making it more efficient is difficult, because
* the access rights need to be checked.
*/
$subsub = $subFolder->getSubFolders();
$subsub = SeedDMS_Core_DMS::filterAccess($subsub, $user, M_READ);
$subdoc = $subFolder->getDocuments();
$subdoc = SeedDMS_Core_DMS::filterAccess($subdoc, $user, M_READ);
if(count($subsub))
$content .= ' '.count($subsub)." ";
if(count($subdoc))
$content .= ' '.count($subdoc);
}
$content .= "
";
$html .= htmlspecialchars($errormsg);
$this->errorMsg($html);
print "";
$this->contentEnd();
$this->htmlEndPage();
add_log_line(" UI::exitError error=".$errormsg." pagetitle=".$pagetitle, PEAR_LOG_ERR);
if($noexit)
return;
exit;
} /* }}} */
/**
* Return HTML Template for jumploader
*
* @param string $uploadurl URL where post data is send
* @param integer $folderid id of folder where document is saved
* @param integer $maxfiles maximum number of files allowed to upload
* @param array $fields list of post fields
*/
function getFineUploaderTemplate() { /* {{{ */
return '
';
} /* }}} */
/**
* Output HTML Code for Fine Uploader
*
* @param string $uploadurl URL where post data is send
* @param integer $folderid id of folder where document is saved
* @param integer $maxfiles maximum number of files allowed to upload
* @param array $fields list of post fields
*/
function printFineUploaderHtml($prefix='userfile') { /* {{{ */
echo self::getFineUploaderHtml($prefix);
} /* }}} */
/**
* Get HTML Code for Fine Uploader
*
* @param string $uploadurl URL where post data is send
* @param integer $folderid id of folder where document is saved
* @param integer $maxfiles maximum number of files allowed to upload
* @param array $fields list of post fields
*/
function getFineUploaderHtml($prefix='userfile') { /* {{{ */
$html = '
';
return $html;
} /* }}} */
/**
* Output Javascript Code for fine uploader
*
* @param string $uploadurl URL where post data is send
* @param integer $folderid id of folder where document is saved
* @param integer $maxfiles maximum number of files allowed to upload
* @param array $fields list of post fields
*/
function printFineUploaderJs($uploadurl, $partsize=0, $maxuploadsize=0, $multiple=true, $prefix='userfile', $formname='form1') { /* {{{ */
?>
$(document).ready(function() {
uploader = new qq.FineUploader({
debug: false,
autoUpload: false,
multiple: ,
element: $('#-fine-uploader')[0],
template: 'qq-template',
request: {
endpoint: 'params['settings']->_encryptionKey.'uploadchunks'); ?>'
},
0 ? '
validation: {
sizeLimit: '.$maxuploadsize.'
},
' : ''); ?>
chunking: {
enabled: true,
mandatory: true
},
messages: {
sizeError: '{file} is too large, maximum file size is {sizeLimit}.'
},
callbacks: {
onComplete: function(id, name, json, xhr) {
},
onAllComplete: function(succeeded, failed) {
var uuids = Array();
var names = Array();
for (var i = 0; i < succeeded.length; i++) {
uuids.push(this.getUuid(succeeded[i]))
names.push(this.getName(succeeded[i]))
}
$('#-fine-uploader-uuids').val(uuids.join(';'));
$('#-fine-uploader-names').val(names.join(';'));
/* Run upload only if all files could be uploaded */
if(succeeded.length > 0 && failed.length == 0)
document.getElementById('= $formname ?>').submit();
},
onError: function(id, name, reason, xhr) {
noty({
text: reason,
type: 'error',
dismissQueue: true,
layout: 'topRight',
theme: 'defaultTheme',
timeout: 3500,
});
}
}
});
});
params['dms'];
$document = $latestContent->getDocument();
$accessop = $this->params['accessobject'];
?>
,
getReviewStatus(10);
break;
case "approval":
$statusList = $latestContent->getApprovalStatus(10);
break;
default:
$statusList = array();
}
foreach($statusList as $rec) {
echo "
";
echo "
";
switch ($rec["type"]) {
case 0: // individual.
$required = $dms->getUser($rec["required"]);
if (!is_object($required)) {
$reqName = getMLText("unknown_user")." '".$rec["required"]."'";
} else {
$reqName = htmlspecialchars($required->getFullName()." (".$required->getLogin().")");
}
break;
case 1: // Approver is a group.
$required = $dms->getGroup($rec["required"]);
if (!is_object($required)) {
$reqName = getMLText("unknown_group")." '".$rec["required"]."'";
}
else {
$reqName = "".htmlspecialchars($required->getName())."";
}
break;
}
echo $reqName;
echo "