1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345
|
<?php
/**
* FusionForge document manager
*
* Copyright 2011-2013, Franck Villaume - TrivialDev
* Copyright (C) 2012 Alain Peyrat - Alcatel-Lucent
* Copyright 2013, French Ministry of National Education
* http://fusionforge.org
*
* This file is part of FusionForge. FusionForge is free software;
* you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software
* Foundation; either version 2 of the Licence, or (at your option)
* any later version.
*
* FusionForge is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with FusionForge; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
require_once $gfcommon.'include/Error.class.php';
require_once $gfcommon.'include/User.class.php';
require_once $gfcommon.'docman/DocumentGroup.class.php';
class DocumentManager extends Error {
/**
* Associative array of data from db.
*
* @var array $data_array.
*/
var $data_array;
/**
* The Group object.
*
* @var object $Group.
*/
var $Group;
/**
* Constructor.
*
* @param $Group
* @internal param \The $object Group object to which this document is associated.
* @return \DocumentManager
*/
function __construct(&$Group) {
$this->Error();
if (!$Group || !is_object($Group)) {
$this->setError(_('No Valid Group Object'));
return;
}
if ($Group->isError()) {
$this->setError('DocumentManager:: '. $Group->getErrorMessage());
return;
}
$this->Group =& $Group;
}
/**
* getGroup - get the Group object this Document is associated with.
*
* @return Object The Group object.
*/
function &getGroup() {
return $this->Group;
}
/**
* getTrashID - the trash doc_group id for this DocumentManager.
*
* @return integer The trash doc_group id.
*/
function getTrashID() {
if (isset($this->data_array['trashid']))
return $this->data_array['trashid'];
$res = db_query_params('SELECT doc_group from doc_groups
WHERE groupname = $1
AND group_id = $2
AND stateid = $3',
array('.trash', $this->Group->getID(), '2'));
if (db_numrows($res) == 1) {
$arr = db_fetch_array($res);
$this->data_array['trashid'] = $arr['doc_group'];
return $this->data_array['trashid'];
} else {
$dg = new DocumentGroup($this->Group);
$dg->create('.trash');
$dg->setStateID('2');
return $dg->getID();
}
}
/**
* cleanTrash - delete all items in trash for this DocumentManager
*
* @return boolean true on success
*/
function cleanTrash() {
$trashId = $this->getTrashID();
if ($trashId !== -1) {
db_begin();
$result = db_query_params('select docid FROM doc_data WHERE stateid=$1 and group_id=$2', array('2', $this->Group->getID()));
$emptyFile = db_query_params('DELETE FROM doc_data WHERE stateid=$1 and group_id=$2', array('2', $this->Group->getID()));
if (!$emptyFile) {
db_rollback();
return false;
}
$emptyDir = db_query_params('DELETE FROM doc_groups WHERE stateid=$1 and group_id=$2 and groupname !=$3', array('2', $this->Group->getID(), '.trash'));
if (!$emptyDir) {
db_rollback();
return false;
}
while ($arr = db_fetch_array($result)) {
DocumentStorage::instance()->delete($arr['docid'])->commit();
}
db_commit();
return true;
}
return false;
}
/**
* isTrashEmpty - check if the trash is empty
* @return boolean success or not
*/
function isTrashEmpty() {
$res = db_query_params('select ( select count(*) from doc_groups where group_id = $1 and stateid = 2 and groupname !=$2 )
+ ( select count(*) from docdata_vw where group_id = $3 and stateid = 2 ) as c',
array($this->Group->getID(), '.trash', $this->Group->getID()));
if (!$res) {
return false;
}
return (db_result($res, 0, 'c') == 0);
}
/**
* getTree - display recursively the content of the doc_group. Only doc_groups within doc_groups.
*
* @param int $selecteddir the selected directory
* @param string $linkmenu the type of link in the menu
* @param int $docGroupId the doc_group to start: default 0
*/
function getTree($selecteddir, $linkmenu, $docGroupId = 0) {
global $g; // the master group of all the groups .... anyway.
$dg = new DocumentGroup($this->Group);
switch ($linkmenu) {
case "listtrashfile": {
$stateId = 2;
break;
}
default: {
$stateId = 1;
break;
}
}
$subGroupIdArr = $dg->getSubgroup($docGroupId, $stateId);
if (sizeof($subGroupIdArr)) {
foreach ($subGroupIdArr as $subGroupIdValue) {
$localDg = new DocumentGroup($this->Group, $subGroupIdValue);
$liclass = 'docman_li_treecontent';
if ($selecteddir == $localDg->getID()) {
$liclass = 'docman_li_treecontent_selected';
}
if ($this->Group->getID() != $g->getID()) {
$link = '/docman/?group_id='.$g->getID().'&view='.$linkmenu.'&dirid='.$localDg->getID().'&childgroup_id='.$this->Group->getID();
} else {
$link = '/docman/?group_id='.$this->Group->getID().'&view='.$linkmenu.'&dirid='.$localDg->getID();
}
$nbDocsLabel = '';
$nbDocs = $localDg->getNumberOfDocuments($stateId);
if ($stateId == 1 && forge_check_perm('docman', $this->Group->getID(), 'approve')) {
$nbDocsPending = $localDg->getNumberOfDocuments(3);
$nbDocsHidden = $localDg->getNumberOfDocuments(4);
$nbDocsPrivate = $localDg->getNumberOfDocuments(5);
}
if ($stateId == 2 && forge_check_perm('docman', $this->Group->getID(), 'approve')) {
$nbDocsTrashed = $localDg->getNumberOfDocuments(2);
}
if ($nbDocs && (!isset($nbDocsPending) || $nbDocsPending == 0) && (!isset($nbDocsHidden) || $nbDocsHidden == 0) && (!isset($nbDocsPrivate) || $nbDocsPrivate) && (!isset($nbDocsTrashed) || $nbDocsTrashed)) {
$nbDocsLabel = '<span class="tabtitle-nw" title="'._('Number of documents in this folder').'" >('.$nbDocs.')</span>';
}
if (isset($nbDocsPending) && isset($nbDocsHidden) && isset($nbDocsPrivate)) {
$nbDocsLabel = '<span class="tabtitle-nw" title="'._('Number of documents in this folder per status. active/pending/hidden/private').'" >('.$nbDocs.'/'.$nbDocsPending.'/'.$nbDocsHidden.'/'.$nbDocsPrivate.')</span>';
}
if (isset($nbDocsTrashed)) {
$nbDocsLabel = '<span class="tabtitle-nw" title="'._('Number of deleted documents in this folder').'" >('.$nbDocsTrashed.')</span>';
}
if ($localDg->getName() != '.trash') {
$lititle = '';
if ($localDg->getCreated_by()) {
$user = user_get_object($localDg->getCreated_by());
$lititle .= _('Created by')._(': ').$user->getRealName();
}
if ($localDg->getLastModifyDate()) {
if ($lititle) {
$lititle .= _('; ');
}
$lititle .= _('Last Modified')._(': ').relative_date($localDg->getLastModifyDate());
}
echo '<li id="leaf-'.$subGroupIdValue.'" class="'.$liclass.'">'.util_make_link($link, $localDg->getName(), array('class'=>'tabtitle-nw', 'title'=>$lititle)).$nbDocsLabel;
} else {
echo '<li id="leaf-'.$subGroupIdValue.'" class="'.$liclass.'">'.util_make_link($link, $localDg->getName()).$nbDocsLabel;
}
if ($dg->getSubgroup($subGroupIdValue, $stateId)) {
echo '<ul class="simpleTreeMenu" >';
$this->getTree($selecteddir, $linkmenu, $subGroupIdValue);
echo '</ul>';
}
echo '</li>';
}
}
}
/**
* getStatusNameList - get all status for documents
*
* @param string $format format of the return values. json returns : { name: id, }. Default is DB object.
* @param string $removedval skipped status id
* @return resource|string
*/
function getStatusNameList($format = '', $removedval = '') {
if (!empty($removedval)) {
$stateQuery = db_query_params('select * from doc_states where stateid not in ($1) order by stateid', array($removedval));
} else {
$stateQuery = db_query_params('select * from doc_states order by stateid', array());
}
switch ($format) {
case 'json': {
$returnString = '{';
while ($stateArr = db_fetch_array($stateQuery)) {
$returnString .= util_html_secure($stateArr['name']).': \''.$stateArr['stateid'].'\',';
}
$returnString .= '}';
return $returnString;
break;
}
default: {
return $stateQuery;
}
}
}
/**
* getDocGroupList - Returns as a string used in javascript the list of available folders
*
* @param $nested_groups
* @param string must be json which is wrong, this function does not return any json object
* @param bool allow the "None" which is the "/"
* @param int the selected folder id
* @param array folders id to not display
* @return string
*/
function getDocGroupList($nested_groups, $format = '', $allow_none = true, $selected_id = 0, $dont_display = array()) {
$id_array = array();
$text_array = array();
$this->buildArrays($nested_groups, $id_array, $text_array, $dont_display);
$rows = count($id_array);
switch ($format) {
case "json": {
$returnString = '{';
for ($i=0; $i<$rows; $i++) {
$returnString .= '\''.util_html_secure(addslashes($text_array[$i])).'\':'.$id_array[$i].',';
}
$returnString .= '}';
break;
}
}
return $returnString;
}
/**
* buildArrays - Build the arrays to call html_build_select_box_from_arrays()
*
* @param array Array of groups.
* @param array Reference to the array of ids that will be build
* @param array Reference to the array of group names
* @param array Array of IDs of groups that should not be displayed
* @param int The ID of the parent whose childs are being showed (0 for root groups)
* @param int The current level
*/
function buildArrays($group_arr, &$id_array, &$text_array, &$dont_display, $parent = 0, $level = 0) {
if (!is_array($group_arr) || !array_key_exists("$parent", $group_arr)) return;
$child_count = count($group_arr["$parent"]);
for ($i = 0; $i < $child_count; $i++) {
$doc_group =& $group_arr["$parent"][$i];
// Should we display this element?
if (in_array($doc_group->getID(), $dont_display)) continue;
$margin = str_repeat("--", $level);
$id_array[] = $doc_group->getID();
$text_array[] = $margin.$doc_group->getName();
// Show childs (if any)
$this->buildArrays($group_arr, $id_array, $text_array, $dont_display, $doc_group->getID(), $level+1);
}
}
/**
* getActivity - return the number of searched actions per sections between two dates
*
* @param array Sections to search for activity
* @param int the start date time format time()
* @param int the end date time format time()
* @return array number per section of activities found between begin and end values
*/
function getActivity($sections, $begin, $end) {
$qpa = db_construct_qpa(false);
for ($i = 0; $i < count($sections); $i++) {
$union = 0;
if (count($sections) >= 1 && $i != count($sections) -1) {
$union = 1;
}
$qpa = db_construct_qpa($qpa, 'SELECT count(*) FROM activity_vw WHERE activity_date BETWEEN $1 AND $2
AND group_id = $3 AND section = $4 ',
array($begin,
$end,
$this->getGroup()->getID(),
$sections[$i]));
if ($union) {
$qpa = db_construct_qpa($qpa, ' UNION ALL ', array());
}
}
$res = db_query_qpa($qpa);
$results = array();
$j = 0;
while ($arr = db_fetch_array($res)) {
$results[$sections[$j]] = $arr['0'];
$j++;
}
return $results;
}
}
|