3 * FusionForge Documentation Manager
5 * Copyright 2000, Quentin Cregan/Sourceforge
6 * Copyright 2002, Tim Perdue/GForge, LLC
7 * Copyright 2009, Roland Mas
8 * Copyright 2010, Franck Villaume - Capgemini
9 * Copyright (C) 2011-2012 Alain Peyrat - Alcatel-Lucent
10 * Copyright 2012-2016, Franck Villaume - TrivialDev
11 * http://fusionforge.org
13 * This file is part of FusionForge. FusionForge is free software;
14 * you can redistribute it and/or modify it under the terms of the
15 * GNU General Public License as published by the Free Software
16 * Foundation; either version 2 of the Licence, or (at your option)
19 * FusionForge is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License along
25 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 require_once $gfcommon.'include/FFError.class.php';
30 require_once $gfcommon.'include/MonitorElement.class.php';
32 $DOCUMENTGROUP_OBJ = array();
35 * documentgroup_get_object() - Get document group object by document group ID.
36 * documentgroup_get_object is useful so you can pool document group objects/save database queries
37 * You should always use this instead of instantiating the object directly
39 * @param int $docgroup_id The ID of the document group - required
40 * @param int $group_id Group ID of the project - required
41 * @param int|bool $res The result set handle ("SELECT * FROM doc_groups WHERE doc_group = $1")
42 * @return DocumentGroup a document group object or false on failure
44 function &documentgroup_get_object($docgroup_id, $group_id, $res = false) {
45 global $DOCUMENTGROUP_OBJ;
46 if (!isset($DOCUMENTGROUP_OBJ["_".$docgroup_id."_"])) {
48 //the db result handle was passed in
50 $res = db_query_params('SELECT * FROM doc_groups WHERE doc_group = $1 and group_id = $2',
51 array($docgroup_id, $group_id));
53 if (!$res || db_numrows($res) < 1) {
54 $DOCUMENTGROUP_OBJ["_".$docgroup_id."_"] = false;
56 $DOCUMENTGROUP_OBJ["_".$docgroup_id."_"] = new DocumentGroup(group_get_object($group_id), db_fetch_array($res));
59 return $DOCUMENTGROUP_OBJ["_".$docgroup_id."_"];
62 class DocumentGroup extends FFError {
74 * @var array $data_array.
79 * DocumentGroup - constructor.
81 * Use this constructor if you are modifying an existing doc_group.
85 * @internal param \Group $object object.
86 * @internal param array $OR doc_group id from database.
87 * @return \DocumentGroup
90 function __construct(&$Group, $data = false) {
91 parent::__construct();
93 if (!$Group || !is_object($Group)) {
94 $this->setError(_('No Valid Group Object'));
97 if ($Group->isError()) {
98 $this->setError(_('Document Folder')._(': ').$Group->getErrorMessage());
101 $this->Group =& $Group;
104 if (is_array($data)) {
105 $this->data_array =& $data;
106 if ($this->data_array['group_id'] != $this->Group->getID()) {
107 $this->setError('DocumentGroup'._(': '). _('group_id in db result does not match Group Object'));
108 $this->data_array = null;
112 $this->fetchData($data);
115 if ($this->getState() == 5 && !forge_check_perm('docman', $this->Group->getID(), 'approve')) {
116 $this->data_array = null;
117 $this->setError(_('Permission refused'));
123 * create - create a new item in the database.
125 * @param string $name The name of the directory to create
126 * @param int $parent_doc_group The ID of the parent directory
127 * @param int $state The status of this directory: default is 1 = public.
132 * @param int $createtimestamp Timestamp of the directory creation
133 * @internal param \Item $string name.
134 * @return boolean true on success / false on failure.
137 function create($name, $parent_doc_group = 0, $state = 1, $createtimestamp = null) {
142 $this->setError(_('Name is required'));
146 if ($parent_doc_group) {
147 // check if parent group exists
148 $res = db_query_params('SELECT * FROM doc_groups WHERE doc_group=$1 AND group_id=$2',
149 array($parent_doc_group, $this->Group->getID()));
150 if (!$res || db_numrows($res) < 1) {
151 $this->setError(_('Invalid Documents Folder parent ID'));
155 $parent_doc_group = 0;
158 if ($parent_doc_group || $name != 'Uncategorized Submissions') {
159 $perm =& $this->Group->getPermission();
160 if (!$perm || !$perm->isDocEditor()) {
161 $this->setPermissionDeniedError();
166 $res = db_query_params('SELECT * FROM doc_groups WHERE groupname=$1 AND parent_doc_group=$2 AND group_id=$3',
169 $this->Group->getID())
171 if ($res && db_numrows($res) > 0) {
172 $this->setError(_('Folder name already exists'));
176 $createtimestamp = (($createtimestamp) ? $createtimestamp : time());
177 $user_id = ((session_loggedin()) ? user_getid() : 100);
178 $result = db_query_params('INSERT INTO doc_groups (group_id, groupname, parent_doc_group, stateid, createdate, created_by) VALUES ($1, $2, $3, $4, $5, $6)',
179 array ($this->Group->getID(),
180 htmlspecialchars($name),
186 if ($result && db_affected_rows($result) > 0) {
189 $this->setError(_('Error Adding Folder')._(': ').db_error());
193 $doc_group = db_insertid($result, 'doc_groups', 'doc_group');
195 // Now set up our internal data structures
196 if (!$this->fetchData($doc_group)) {
200 if ($parent_doc_group) {
201 /* update the parent */
202 $parentDg = documentgroup_get_object($parent_doc_group, $this->Group->getID());
203 $parentDg->update($parentDg->getName(), $parentDg->getParentID(), 1, $parentDg->getState());
205 $this->sendNotice(true);
210 * delete - delete a DocumentGroup.
211 * WARNING delete is recursive and permanent
213 * @param int $doc_groupid
214 * @param int $project_group_id
215 * @internal param \Document $integer Group Id, integer Project Group Id
216 * @return boolean success
219 function delete($doc_groupid, $project_group_id) {
220 $perm =& $this->Group->getPermission();
221 if (!$perm || !$perm->isDocEditor()) {
222 $this->setPermissionDeniedError();
226 /* delete documents in directory */
227 $result = db_query_params('DELETE FROM doc_data where doc_group = $1 and group_id = $2',
228 array($doc_groupid, $project_group_id));
230 /* delete directory */
231 $result = db_query_params('DELETE FROM doc_groups where doc_group = $1 and group_id = $2',
232 array($doc_groupid, $project_group_id));
240 /* update the parent if any */
241 if ($this->getParentID()) {
242 $parentDg = documentgroup_get_object($this->getParentID(), $this->Group->getID());
243 $parentDg->update($parentDg->getName(), $parentDg->getParentID(), 1, $parentDg->getState());
245 /* is there any subdir ? */
246 $subdir = db_query_params('select doc_group from doc_groups where parent_doc_group = $1 and group_id = $2',
247 array($doc_groupid, $project_group_id));
248 /* make a recursive call */
249 while ($arr = db_fetch_array($subdir)) {
250 $this->delete($arr['doc_group'], $project_group_id);
257 * injectArchive - extract the attachment and create the directory tree if needed
259 * @param array $uploaded_data uploaded data
260 * @return bool success or not
263 function injectArchive($uploaded_data) {
264 if (!is_uploaded_file($uploaded_data['tmp_name'])) {
265 $this->setError(_('Invalid file name.'));
268 if (function_exists('finfo_open')) {
269 $finfo = finfo_open(FILEINFO_MIME_TYPE);
270 $uploaded_data_type = finfo_file($finfo, $uploaded_data['tmp_name']);
272 $uploaded_data_type = $uploaded_data['type'];
275 switch ($uploaded_data_type) {
276 case 'application/zip': {
277 $returned = $this->injectZip($uploaded_data);
280 case 'application/x-rar-compressed': {
281 $returned = $this->injectRar($uploaded_data);
285 $this->setError( _('Unsupported injected file')._(': ').$uploaded_data_type);
293 * fetchData - re-fetch the data for this DocumentGroup from the database.
295 * @param int $id ID of the doc_group.
296 * @return bool success
299 function fetchData($id) {
300 $res = db_query_params('SELECT * FROM doc_groups WHERE doc_group = $1 and group_id = $2',
301 array($id, $this->Group->getID()));
302 if (!$res || db_numrows($res) < 1) {
303 $this->setError(_('Invalid Document Folder ID'));
306 $this->data_array = db_fetch_array($res);
307 $this->data_array['numberFiles'] = array();
308 db_free_result($res);
313 * getGroup - get the Group Object this DocumentGroup is associated with.
315 * @return Object Group.
318 function &getGroup() {
323 * getID - get this DocumentGroup's ID.
325 * @return integer The id #.
329 return $this->data_array['doc_group'];
333 * getID - get parent DocumentGroup's id.
335 * @return integer The id #.
338 function getParentID() {
339 return $this->data_array['parent_doc_group'];
343 * getName - get the name.
345 * @return string The name.
349 return $this->data_array['groupname'];
353 * getState - get the state id.
355 * @return integer The state id.
358 function getState() {
359 return $this->data_array['stateid'];
363 * getCreatedate - get the creation date.
365 * @return integer The creation date.
368 function getCreatedate() {
369 return $this->data_array['createdate'];
373 * getUpdatedate - get the update date.
375 * @return integer The update date.
378 function getUpdatedate() {
379 return $this->data_array['updatedate'];
383 * getLastModifyDate - get the bigger value between update date and creation date.
385 * @return integer The last modified date.
388 function getLastModifyDate() {
389 if($this->data_array['updatedate']) {
390 return $this->data_array['updatedate'];
392 return $this->data_array['createdate'];
398 * getMonitoredUserEmailAddress - get the email addresses of users who monitor this directory
400 * @return string The list of emails comma separated
402 function getMonitoredUserEmailAddress() {
403 $MonitorElementObject = new MonitorElement('docgroup');
404 return $MonitorElementObject->getAllEmailsInCommatSeparated($this->getID());
408 * isMonitoredBy - get the monitored status of this document directory for a specific user id.
410 * @param string $userid
411 * @internal param \User $int ID
412 * @return boolean true if monitored by this user
414 function isMonitoredBy($userid = 'ALL') {
415 $MonitorElementObject = new MonitorElement('docgroup');
416 if ( $userid == 'ALL' ) {
417 return $MonitorElementObject->isMonitoredByAny($this->getID());
419 return $MonitorElementObject->isMonitoredByUserId($this->getID(), $userid);
424 * removeMonitoredBy - remove this document directory for a specific user id for monitoring.
426 * @param int $userid User ID
427 * @return boolean true if success
429 function removeMonitoredBy($userid) {
430 $MonitorElementObject = new MonitorElement('docgroup');
431 if (!$MonitorElementObject->disableMonitoringByUserId($this->getID(), $userid)) {
432 $this->setError($MonitorElementObject->getErrorMessage());
439 * addMonitoredBy - add this document for a specific user id for monitoring.
441 * @param int $userid User ID
442 * @return boolean true if success
444 function addMonitoredBy($userid) {
445 $MonitorElementObject = new MonitorElement('docgroup');
446 if (!$MonitorElementObject->enableMonitoringByUserId($this->getID(), $userid)) {
447 $this->setError($MonitorElementObject->getErrorMessage());
454 * clearMonitor - remove all entries of monitoring for this document.
456 * @return boolean true if success.
458 function clearMonitor() {
459 $MonitorElementObject = new MonitorElement('docgroup');
460 if (!$MonitorElementObject->clearMonitor($this->getID())) {
461 $this->setError($MonitorElementObject->getErrorMessage());
468 * getCreated_by - get the creator (user) id.
470 * @return integer The User id.
473 function getCreated_by() {
474 return $this->data_array['created_by'];
478 * update - update a DocumentGroup.
480 * @param string $name Name of the category.
481 * @param int $parent_doc_group the doc_group id of the parent. default = 0
482 * @param int $metadata update only the metadata : created_by, updatedate
483 * @param int $state state of the directory. Default is 1 = public. See create function for valid values
484 * @param int $updatetimestamp Timestamp of the update
485 * @return boolean success or not
488 function update($name, $parent_doc_group = 0, $metadata = 0, $state = 1, $updatetimestamp = null) {
489 $perm =& $this->Group->getPermission();
490 if (!$perm || !$perm->isDocEditor()) {
491 $this->setPermissionDeniedError();
495 $this->setMissingParamsError();
499 if ($parent_doc_group) {
500 // check if parent group exists
501 $res = db_query_params('SELECT * FROM doc_groups WHERE doc_group=$1 AND group_id=$2',
502 array($parent_doc_group,
503 $this->Group->getID())
505 if (!$res || db_numrows($res) < 1) {
506 $this->setError(_('Invalid Documents Folder parent ID'));
512 $res = db_query_params('SELECT * FROM doc_groups WHERE groupname=$1 AND parent_doc_group=$2 AND group_id=$3',
515 $this->Group->getID())
517 if ($res && db_numrows($res) > 0) {
518 $this->setError(_('Documents Folder name already exists'));
523 $user_id = ((session_loggedin()) ? user_getid() : 100);
524 $updatetimestamp = (($updatetimestamp) ? $updatetimestamp : time());
525 $colArr = array('groupname', 'parent_doc_group', 'updatedate', 'created_by', 'locked', 'locked_by', 'stateid');
526 $valArr = array(htmlspecialchars($name), $parent_doc_group, $updatetimestamp, $user_id, 0, NULL, $state);
527 if ($this->setValueinDB($colArr, $valArr)) {
528 $parentDg = new DocumentGroup($this->Group, $parent_doc_group);
529 if ($parentDg->getParentID())
530 $parentDg->update($parentDg->getName(), $parentDg->getParentID(), 1, $parentDg->getState(), $updatetimestamp);
532 $this->fetchData($this->getID());
533 $this->sendNotice(false);
536 $this->setOnUpdateError(_('Error')._(': '). db_error());
542 * hasDocuments - Recursive function that checks if this group or any of it childs has documents associated to it
544 * A group has associated documents if and only if there are documents associated to this
545 * group or to any of its childs
547 * @param array $nested_groups
548 * @param object $document_factory
549 * @param int $stateid
550 * @internal param Array $array of nested groups information, fetched from DocumentGroupFactory class
551 * @internal param \The $object DocumentFactory object
552 * @internal param int $State of the documents
553 * @return boolean success
556 function hasDocuments(&$nested_groups, &$document_factory, $stateid = 0) {
557 $doc_group_id = $this->getID();
558 static $result = array(); // this function will probably be called several times so we better store results in order to speed things up
559 if (!array_key_exists($stateid, $result) || !is_array($result[$stateid]))
560 $result[$stateid] = array();
562 if (array_key_exists($doc_group_id, $result[$stateid]))
563 return $result[$stateid][$doc_group_id];
567 if (forge_check_perm('docman', $document_factory->Group->getID(), 'approve')) {
570 $document_factory->setDocGroupID($doc_group_id);
571 $document_factory->setDocGroupState($stateIdDg);
572 // check if it has documents
574 $document_factory->setStateID(array($stateid));
576 $document_factory->setStateID(array(1, 4, 5));
579 $document_factory->setDocGroupID($doc_group_id);
580 $docs = $document_factory->getDocuments();
581 if (is_array($docs) && count($docs) > 0) { // this group has documents
582 $result[$stateid][$doc_group_id] = true;
586 // this group doesn't have documents... check recursively on the childs
587 if (array_key_exists($doc_group_id, $nested_groups) && is_array($nested_groups[$doc_group_id])) {
588 $count = count($nested_groups[$doc_group_id]);
589 for ($i=0; $i < $count; $i++) {
590 if ($nested_groups[$doc_group_id][$i]->hasDocuments($nested_groups, $document_factory, $stateid)) {
591 // child has documents
592 $result[$stateid][$doc_group_id] = true;
596 // no child has documents, then this group doesn't have associated documents
597 $result[$stateid][$doc_group_id] = false;
599 } else { // this group doesn't have childs
600 $result[$stateid][$doc_group_id] = false;
605 function hasDocument($filename, $stateid = 1) {
606 $result = db_query_params('SELECT filename, doc_group, docid from docdata_vw
610 array($filename, $this->getID(), $stateid));
612 if (!$result || db_numrows($result) > 0) {
613 $row = db_fetch_array($result);
614 return $row['docid'];
620 * getNumberOfDocuments - get the number of files in this doc_group, group_id and for a document state
622 * @param int $stateId the state id
623 * @return int the number of found documents
625 function getNumberOfDocuments($stateId = 1) {
626 if (isset($this->data_array['numberFiles'][$stateId]))
627 return $this->data_array['numberFiles'][$stateId];
629 $res = db_query_params('select count(*) from docdata_vw where doc_group = $1 and group_id = $2 and stateid = $3',
630 array($this->getID(), $this->Group->getID(), $stateId));
634 $arr = db_fetch_array($res);
635 $this->data_array['numberFiles'][$stateId] = $arr[0];
640 * getSubgroup - Return the ids of any sub folders (first level only) in specific folder
642 * @param int $docGroupId ID of the specific folder
643 * @param array $stateId the state ids of this specific folder (default is 1)
644 * @return array the ids of any sub folders
646 function getSubgroup($docGroupId, $stateId = array(1)) {
647 $returnArr = array();
648 $res = db_query_params('SELECT doc_group from doc_groups where parent_doc_group = $1 and stateid = ANY ($2) and group_id = $3 order by groupname',
649 array($docGroupId, db_int_array_to_any_clause($stateId), $this->Group->getID()));
654 while ($row = db_fetch_array($res)) {
655 $returnArr[] = $row['doc_group'];
662 * getPath - return the complete_path
664 * @param boolean $url does path is url clickable (default is false)
665 * @param boolean $includename does path include this document group name ? (default is true)
666 * @return string|boolean the complete_path or false if user has not proper access to this path.
669 function getPath($url = false, $includename = true) {
670 if ($this->getState() != 1 && !forge_check_perm('docman', $this->Group->getID(), 'approve')) {
674 if ($this->getParentID()) {
675 $parentDg = documentgroup_get_object($this->getParentID(), $this->Group->getID());
676 if ($parentDg->isError()) {
677 $this->setError = $parentDg->getErrorMessage();
680 //need to check if user has access to this path. If not, return false.
681 if ($parentDg->getState() != 1) {
682 if (!forge_check_perm('docman', $this->Group->getID(), 'approve')) {
686 $returnPath = $parentDg->getPath($url);
693 $browselink = '/docman/?view=listfile&dirid='.$this->getID();
694 if (isset($GLOBALS['childgroup_id']) && $GLOBALS['childgroup_id']) {
695 $browselink .= '&childgroup_id='.$GLOBALS['childgroup_id'];
697 $browselink .= '&group_id='.$this->Group->getID();
698 $returnPath .= '/'.util_make_link($browselink, $this->getName(), array('title' => _('Browse this folder')));
700 $returnPath .= '/'.$this->getName();
707 * setStateID - set the state id of this document group.
709 * @param int $stateid State ID.
710 * @param bool $recursive set the state id recursively. (i.e. move the directory and his content to trash)
711 * @return boolean success or not.
714 function setStateID($stateid, $recursive = false) {
716 $df = new DocumentFactory($this->Group);
718 exit_error($df->getErrorMessage(), 'docman');
720 $dgf = new DocumentGroupFactory($this->Group);
722 exit_error($dgf->getErrorMessage(), 'docman');
724 $stateidArr = array(1, 3, 4, 5);
725 $nested_groups =& $dgf->getNested($stateidArr);
727 $df->setStateID($stateidArr);
728 $df->setDocGroupID($this->getID());
729 $d_arr =& $df->getDocuments();
731 $nested_docs = array();
732 /* put the doc objects into an array keyed of the docgroup */
733 if (is_array($d_arr)) {
734 foreach ($d_arr as $doc) {
735 $nested_docs[$doc->getDocGroupID()][] = $doc;
739 $localdocgroup_arr = array();
740 $localdocgroup_arr[] = $this->getID();
741 if (is_array($nested_groups[$this->getID()])) {
742 foreach ($nested_groups[$this->getID()] as $dg) {
743 if (!$dg->setStateID($stateid))
746 $localdocgroup_arr[] = $dg->getID();
747 $localdf = new DocumentFactory($this->Group);
748 $localdf->setDocGroupID($dg->getID());
749 $d_arr =& $localdf->getDocuments();
750 if (is_array($d_arr)) {
751 foreach ($d_arr as $doc) {
752 $nested_docs[$doc->getDocGroupID()][] = $doc;
758 foreach ($localdocgroup_arr as $docgroup_id) {
759 if (isset($nested_docs[$docgroup_id]) && is_array($nested_docs[$docgroup_id])) {
760 foreach ($nested_docs[$docgroup_id] as $d) {
761 if (!$d->setState($stateid))
767 return $this->setValueinDB(array('stateid'), array($stateid));
771 * setParentDocGroupId - set the parent doc_group id of this document group.
773 * @param int $parentDocGroupId Parent Doc_group Id.
774 * @return boolean success or not.
777 function setParentDocGroupId($parentDocGroupId) {
778 return $this->setValueinDB(array('parent_doc_group'), array($parentDocGroupId));
782 * sendNotice - Notifies of directory submissions
784 * @param boolean $new true = new directory (default value)
787 function sendNotice($new = true) {
788 $BCC = $this->Group->getDocEmailAddress();
789 if ($this->isMonitoredBy('ALL')) {
790 $BCC .= $this->getMonitoredUserEmailAddress();
792 if (strlen($BCC) > 0) {
793 $sess = session_get_user();
795 $status = _('New Folder');
797 $status = _('Updated folder by').' '.$sess->getRealName();
799 $subject = '['.$this->Group->getPublicName().'] '.$status.' - '.$this->getName();
800 $body = _('Project')._(': ').$this->Group->getPublicName()."\n";
801 $body .= _('Folder')._(': ').$this->getName()."\n";
802 $user = user_get_object($this->getCreated_by());
803 $body .= _('Submitter')._(': ').$user->getRealName()." (".$user->getUnixName().") \n";
805 $body .= _('Updated by')._(': ').$sess->getRealName();
807 $body .= "\n\n-------------------------------------------------------\n".
808 _('For more info, visit:').
809 "\n\n" . util_make_url('/docman/?group_id='.$this->Group->getID().'&view=listfile&dirid='.$this->getID());
811 $BCCarray = explode(',',$BCC);
812 foreach ($BCCarray as $dest_email) {
813 util_send_message($dest_email, $subject, $body, 'noreply@'.forge_get_config('web_host'), '', _('Docman'));
820 * trash - move this directory and his contents to trash
822 * @return bool success or not.
825 if (!$this->getLocked() || ((time() - $this->getLockdate()) > 600)) {
826 //we need to move recursively all docs and all doc_groups in trash
827 // aka setStateID to 2.
828 if (!$this->setStateID(2, true))
831 $dm = new DocumentManager($this->Group);
832 $this->setParentDocGroupId($dm->getTrashID());
834 $this->sendNotice(false);
835 $this->clearMonitor();
838 $this->setError(_('Unable to move this folder to trash. Folder locked.'));
842 * injectZip - private method to inject a zip archive tree and files
844 * @param array $uploadedZip uploaded zip
845 * @return boolean success or not
848 private function injectZip($uploadedZip) {
849 $zip = new ZipArchive();
850 if ($zip->open($uploadedZip['tmp_name'])) {
851 $extractDir = sys_get_temp_dir().'/'.uniqid();
852 if ($zip->extractTo($extractDir)) {
854 if ($this->injectContent($extractDir)) {
862 $this->setError(_('Unable to extract ZIP file.'));
867 $this->setError(_('Unable to open ZIP file.'));
872 * injectRar - private method to inject a rar archive tree and files
874 * @param array $uploadedRar uploaded rar
875 * @return boolean success or not
878 private function injectRar($uploadedRar) {
883 * injectContent - private method to inject a directory tree and files
885 * @param string $directory the directory to inject
886 * @return boolean success or not
889 private function injectContent($directory) {
890 if (is_dir($directory)) {
891 $dir_arr = scandir($directory);
892 for ($i = 0; $i < count($dir_arr); $i++) {
893 if ($dir_arr[$i] != '.' && $dir_arr[$i] != '..') {
894 if (is_dir($directory.'/'.$dir_arr[$i])) {
895 $ndg = new DocumentGroup($this->getGroup());
896 if ($ndg->create($dir_arr[$i], $this->getID())) {
897 if (!$ndg->injectContent($directory.'/'.$dir_arr[$i])) {
898 $this->setError($ndg->getErrorMessage());
902 } elseif (is_file($directory.'/'.$dir_arr[$i])) {
903 $d = new Document($this->getGroup());
904 if (function_exists('finfo_open')) {
905 $finfo = finfo_open(FILEINFO_MIME_TYPE);
906 $dir_arr_type = finfo_file($finfo, $directory.'/'.$dir_arr[$i]);
908 $dir_arr_type = 'application/binary';
910 if (util_is_valid_filename($dir_arr[$i])) {
911 // ugly hack in case of ppl injecting zip at / when there is not directory in the ZIP file...
912 // force upload in the first directory of the tree ...
913 if (!$this->getID()) {
914 $subGroupArrID = $this->getSubgroup(0);
915 $this->data_array['doc_group'] = $subGroupArrID[0];
917 if (strlen($dir_arr[$i]) < 5) {
918 $filename = $dir_arr[$i].' '._('(Title must be at least 5 characters.)');
920 $filename = $dir_arr[$i];
922 if (!$d->create($dir_arr[$i], $dir_arr_type, $directory.'/'.$dir_arr[$i], $this->getID(),
923 $filename, _('Injected by ZIP:').date(DATE_ATOM))) {
924 $this->setError($dir_arr[$i]._(': ').$d->getErrorMessage());
928 $this->setError($dir_arr[$i]._(': ')._('Invalid file name.'));
932 $this->setError($dir_arr[$i]._(': ')._('Unknown item.'));
939 $this->setError(_('Unable to open folder for injecting into tree'));
945 * getLocked - get the lock status of this doc_group.
947 * @return int The lock status of this doc_group.
949 function getLocked() {
950 return $this->data_array['locked'];
954 * getLockdate - get the lock time of this doc_group.
956 * @return int The lock time of this doc_group.
958 function getLockdate() {
959 return $this->data_array['lockdate'];
963 * getLockedBy - get the user id who set lock on this doc_group.
965 * @return int The user id who set lock on this doc_group.
967 function getLockedBy() {
968 return $this->data_array['locked_by'];
972 * setLock - set the locking status of the doc_group.
973 * recursive call. we lock all subfolders...
975 * @param int $stateLock the status to be set
976 * @param string $userid the lock owner
977 * @param int $thistime the epoch time
978 * @internal param \The $int status of the lock.
979 * @internal param \The $int userid who set the lock.
980 * @return boolean success or not.
982 function setLock($stateLock, $userid = NULL, $thistime = 0) {
983 $colArr = array('locked', 'locked_by', 'lockdate');
984 $valArr = array($stateLock, $userid, $thistime);
985 if (!$this->setValueinDB($colArr, $valArr)) {
988 $this->data_array['locked'] = $stateLock;
989 $this->data_array['locked_by'] = $userid;
990 $this->data_array['lockdate'] = $thistime;
991 $subGroupArray = $this->getSubgroup($this->getID(), array($this->getState()));
992 foreach ($subGroupArray as $docgroupId) {
993 $ndg = documentgroup_get_object($docgroupId, $this->Group->getID());
994 $ndg->setLock($stateLock, $userid, $thistime);
1000 * setValueinDB - private function to update columns in db
1002 * @param array $colArr the columns to update in array form array('col1', col2')
1003 * @param int $valArr the values to store in array form array('val1', 'val2')
1004 * @return boolean success or not
1007 private function setValueinDB($colArr, $valArr) {
1008 if ((count($colArr) != count($valArr)) || !count($colArr) || !count($valArr)) {
1009 $this->setOnUpdateError(_('wrong parameters'));
1013 $qpa = db_construct_qpa(false, 'UPDATE doc_groups SET ');
1014 for ($i = 0; $i < count($colArr); $i++) {
1015 switch ($colArr[$i]) {
1017 case 'parent_doc_group':
1025 $qpa = db_construct_qpa($qpa, ',');
1027 $qpa = db_construct_qpa($qpa, $colArr[$i]);
1028 $qpa = db_construct_qpa($qpa, '=$1 ', array($valArr[$i]));
1032 $this->setOnUpdateError(_('wrong column name'));
1037 $qpa = db_construct_qpa($qpa, ' WHERE group_id=$1
1039 array($this->Group->getID(),
1041 $res = db_query_qpa($qpa);
1042 if (!$res || db_affected_rows($res) < 1) {
1043 $this->setOnUpdateError(db_error());
1046 for ($i = 0; $i < count($colArr); $i++) {
1047 switch ($colArr[$i]) {
1049 case 'parent_doc_group':
1056 $this->data_array[$colArr[$i]] = $valArr[$i];
1066 // c-file-style: "bsd"