3 * FusionForge document manager
5 * Copyright 2000, Quentin Cregan/Sourceforge
6 * Copyright 2002-2003, Tim Perdue/GForge, LLC
7 * Copyright 2009, Roland Mas
8 * Copyright 2010, Franck Villaume - Capgemini
10 * This file is part of FusionForge.
12 * FusionForge is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published
14 * by the Free Software Foundation; either version 2 of the License,
15 * or (at your option) any later version.
17 * FusionForge is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with FusionForge; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28 require_once $gfcommon.'include/Error.class.php';
29 require_once $gfcommon.'docman/Parsedata.class.php';
31 class Document extends Error {
34 * Associative array of data from db.
36 * @var array $data_array.
46 * The Search engine path.
48 * @var string $engine_path
55 * @param object The Group object to which this document is associated.
56 * @param int The docid.
57 * @param array The associative array of data.
58 * @return boolean success.
60 function Document(&$Group, $docid=false, $arr=false, $engine = "") {
62 if (!$Group || !is_object($Group)) {
63 $this->setNotValidGroupObjectError();
66 if ($Group->isError()) {
67 $this->setError('Document:: '.$Group->getErrorMessage());
70 $this->Group =& $Group;
73 if (!$arr || !is_array($arr)) {
74 if (!$this->fetchData($docid)) {
78 $this->data_array =& $arr;
79 if ($this->data_array['group_id'] != $this->Group->getID()) {
80 $this->setError(_('Group_id in db result does not match Group Object'));
81 $this->data_array = null;
85 if (!$this->isPublic()) {
86 $perm =& $this->Group->getPermission ();
88 if (!$perm || !is_object($perm) || !$perm->isMember()) {
89 $this->setPermissionDeniedError();
90 $this->data_array = null;
95 $this->engine_path = $engine;
100 * create - use this function to create a new entry in the database.
102 * @param string The filename of this document. Can be a URL.
103 * @param string The filetype of this document. If filename is URL, this should be 'URL';
104 * @param string The contents of this document.
105 * @param int The doc_group id of the doc_groups table.
106 * @param string The title of this document.
107 * @param int The language id of the supported_languages table.
108 * @param string The description of this document.
109 * @return boolean success.
111 function create($filename,$filetype,$data,$doc_group,$title,$description) {
112 if (strlen($title) < 5) {
113 $this->setError(_('Title Must Be At Least 5 Characters'));
116 if (strlen($description) < 10) {
117 $this->setError(_('Document Description Must Be At Least 10 Characters'));
121 $result = db_query_params('SELECT filename,doc_group from docdata_vw',
122 array($filename,$doc_group));
124 if (!$result || db_numrows($res) > 0) {
125 $this->setError(_('Document already published in this directory'));
129 $user_id = ((session_loggedin()) ? user_getid() : 100);
131 $doc_initstatus = '3';
132 // If Editor - uploaded Documents are ACTIVE
133 if ( session_loggedin() ) {
134 $perm =& $this->Group->getPermission ();
135 if ($perm && is_object($perm) && $perm->isDocEditor()) {
136 $doc_initstatus = '1';
140 // If $filetype is "text/plain", $body convert UTF-8 encoding.
141 if (strcasecmp($filetype,"text/plain") === 0 &&
142 function_exists('mb_convert_encoding') &&
143 function_exists('mb_detect_encoding')) {
144 $data = mb_convert_encoding($data,'UTF-8',mb_detect_encoding($data));
148 // key words for in-document search
149 if ($this->Group->useDocmanSearch()) {
150 $kw = new Parsedata ($this->engine_path);
151 $kwords = $kw->get_parse_data ($data1, htmlspecialchars($title), htmlspecialchars($description), $filetype);
156 $filesize = strlen($data);
159 $result = db_query_params('INSERT INTO doc_data (group_id,title,description,createdate,doc_group,
160 stateid,filename,filetype,filesize,data_words,created_by)
161 VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11)',
162 array($this->Group->getId(),
163 htmlspecialchars($title),
164 htmlspecialchars($description),
174 $this->setError(_('Error Adding Document: ').db_error().$result);
179 $docid=db_insertid($result,'doc_data','docid');
181 switch ($this->Group->getStorageAPI()) {
183 $result = db_query_params('UPDATE doc_data set data = $1 where docid = $2',
184 array(base64_encode($data),
187 $this->setError(_('Error Adding Document: ').db_error().$result);
193 $this->setError(_('Error Adding Document: No Storage API'));
198 if (!$this->fetchData($docid)) {
202 $this->sendNotice(true);
208 * fetchData() - re-fetch the data for this document from the database.
210 * @param int The document id.
211 * @return boolean success
213 function fetchData($docid) {
214 $res = db_query_params ('SELECT * FROM docdata_vw WHERE docid=$1 AND group_id=$2',
216 $this->Group->getID()));
217 if (!$res || db_numrows($res) < 1) {
218 $this->setError(_('Document:: Invalid docid'));
221 $this->data_array = db_fetch_array($res);
222 db_free_result($res);
227 * getGroup - get the Group object this Document is associated with.
229 * @return Object The Group object.
231 function &getGroup() {
236 * getID - get this docid.
238 * @return int The docid.
241 return $this->data_array['docid'];
245 * getName - get the name of this document.
247 * @return string The name of this document.
250 return $this->data_array['title'];
254 * getDescription - the description of this document.
256 * @return string The description.
258 function getDescription() {
259 return $this->data_array['description'];
263 * isURL - whether this document is a URL and not a local file.
265 * @return boolean is_url.
268 return ($this->data_array['filetype'] == 'URL');
272 * isText - whether this document is a text document and not a binary one.
274 * @return boolean is_text.
277 $doctype = $this->data_array['filetype'];
278 if (preg_match('|^text/|i',$doctype)) { // text plain, text html, text x-patch, etc
285 * isHtml - whether this document is a html document.
287 * @return boolean is_html.
290 $doctype = $this->data_array['filetype'];
291 if (preg_match('/html/i',$doctype)) {
298 * isPublic - whether this document is available to the general public.
300 * @return boolean is_public.
302 function isPublic() {
303 return (($this->data_array['stateid'] == 1) ? true : false);
307 * getStateID - get this stateid.
309 * @return int The stateid.
311 function getStateID() {
312 return $this->data_array['stateid'];
316 * getStateName - the statename of this document.
318 * @return string The statename.
320 function getStateName() {
321 return $this->data_array['state_name'];
325 * getDocGroupID - get this doc_group_id.
327 * @return int The doc_group_id.
329 function getDocGroupID() {
330 return $this->data_array['doc_group'];
334 * getDocGroupName - the doc_group_name of this document.
336 * @return string The docgroupname.
338 function getDocGroupName() {
339 return $this->data_array['group_name'];
343 * getCreatorID - get this creator's user_id.
345 * @return int The user_id.
347 function getCreatorID() {
348 return $this->data_array['created_by'];
352 * getCreatorUserName - the unix name of the person who created this document.
354 * @return string The unix name of the creator.
356 function getCreatorUserName() {
357 return $this->data_array['user_name'];
361 * getCreatorRealName - the real name of the person who created this document.
363 * @return string The real name of the creator.
365 function getCreatorRealName() {
366 return $this->data_array['realname'];
370 * getCreatorEmail - the email of the person who created this document.
372 * @return string The email of the creator.
374 function getCreatorEmail() {
375 return $this->data_array['email'];
379 * getFileName - the filename of this document.
381 * @return string The filename.
383 function getFileName() {
384 return $this->data_array['filename'];
388 * getFileType - the filetype of this document.
390 * @return string The filetype.
392 function getFileType() {
393 return $this->data_array['filetype'];
397 * getFileData - the filedata of this document.
399 * @return string The filedata.
401 function getFileData() {
403 // Because this could be a large string, we only fetch if we actually need it
405 $res = db_query_params ('SELECT data FROM doc_data WHERE docid=$1',
406 array ($this->getID())) ;
407 return base64_decode(db_result($res,0,'data'));
411 * getFileSize - Return the size of the document
413 * @return int The file size
415 function getFileSize() {
416 return $this->data_array['filesize'];
419 * getUpdated - get the time this document was updated.
421 * @return int The epoch date this document was updated.
423 function getUpdated() {
424 return $this->data_array['updatedate'];
428 * getCreated - get the time this document was created.
430 * @return int The epoch date this document was created.
432 function getCreated() {
433 return $this->data_array['createdate'];
437 * getLocked - get the lock status of this document.
439 * @return int The lock status of this document.
441 function getLocked() {
442 return $this->data_array['locked'];
446 * getLockdate - get the lock time of this document.
448 * @return int The lock time of this document.
450 function getLockdate() {
451 return $this->data_array['lockdate'];
455 * getLockedBy - get the user id who set lock on this document.
457 * @return int The user id who set lock on this document.
459 function getLockedBy() {
460 return $this->data_array['locked_by'];
464 * getReservedBy - get the owner of the reversed status of this document.
466 * @return int The owner of the reversed status of this document.
468 function getReservedBy() {
469 return $this->data_array['reserved_by'];
473 * getReserved - get the reversed status of this document.
475 * @return int The reversed status of this document.
477 function getReserved() {
478 return $this->data_array['reserved'];
482 * getMonitoredUserEmailAddress - get the email addresses of users who monitor this file
484 * @return string The list of emails comma separated
486 function getMonitoredUserEmailAddress() {
487 $result = db_query_params('select users.email from users,docdata_monitored_docman where users.user_id = docdata_monitored_docman.user_id and docdata_monitored_docman.doc_id = $1', array ($this->getID()));
488 if (!$result || db_numrows($result) < 1) {
494 while ($arr = db_fetch_array($result)) {
498 $values .=$comma.$arr['email'];
506 * isMonitoredBy - get the monitored status of this document for a specific user id.
509 * @return bool true if monitored by this user
511 function isMonitoredBy($userid = 'ALL') {
512 if ( $userid == 'ALL' ) {
515 $condition = 'user_id='.$userid.' AND';
517 $result = db_query_params('SELECT * FROM docdata_monitored_docman WHERE '.$condition.' doc_id=$1',
518 array ($this->getID()));
520 if (!$result || db_numrows($result) < 1)
527 * removeMonitoredBy - remove this document for a specific user id for monitoring.
530 * @return bool true if success
532 function removeMonitoredBy($userid) {
533 $result = db_query_params('DELETE FROM docdata_monitored_docman WHERE doc_id=$1 AND user_id=$2',
534 array ($this->getID(), $userid));
537 $this->setError(_('Unable To Remove Monitor').' : '.db_error());
544 * addMonitoredBy - add this document for a specific user id for monitoring.
547 * @return bool true if success
549 function addMonitoredBy($userid) {
550 $result = db_query_params('SELECT * FROM docdata_monitored_docman WHERE user_id=$1 AND doc_id=$2',
551 array ($userid, $this->getID()));
553 if (!$result || db_numrows($result) < 1) {
554 $result = db_query_params('INSERT INTO docdata_monitored_docman (doc_id,user_id) VALUES ($1,$2)',
555 array ($this->getID(), $userid));
558 $this->setError(_('Unable To Add Monitor').' : '.db_error());
566 * setState - set the stateid of the document.
568 * @param int The state id of the doc_states table.
569 * @return boolean success.
571 function setState($stateid) {
572 $res = db_query_params ('UPDATE doc_data SET
577 $this->Group->getID(),
580 if (!$res || db_affected_rows($res) < 1) {
581 $this->setOnUpdateError(db_error());
584 $this->sendNotice(false);
589 * setLock - set the locking status of the document
591 * @param int The status of the lock
592 * @param int The userid who set the lock
593 * @return boolean success
595 function setLock($stateLock,$userid=NULL,$thistime=0) {
596 $res = db_query_params ('UPDATE doc_data SET
605 $this->Group->getID(),
608 if (!$res || db_affected_rows($res) < 1) {
609 $this->setOnUpdateError(_('Document lock failed').' '.db_error());
612 $this->sendNotice(false);
613 $this->data_array['locked'] = $stateLock;
614 $this->data_array['locked_by'] = $userid;
615 $this->data_array['lockdate'] = $thistime;
620 * setReservedBy - set the reserved status of the document and the owner
622 * @param int The status of the reserved
623 * @param int The ID of the owner : by default : noone
624 * @return boolean success
626 function setReservedBy($statusReserved,$idReserver=NULL) {
627 $res = db_query_params ('UPDATE doc_data SET
632 array ($statusReserved,
634 $this->Group->getID(),
637 if (!$res || db_affected_rows($res) < 1) {
638 $this->setOnUpdateError(_('Document reservation failed').' '.db_error());
641 $this->sendNotice(false);
646 * update - use this function to update an existing entry in the database.
648 * @param string The filename of this document. Can be a URL.
649 * @param string The filetype of this document. If filename is URL, this should be 'URL';
650 * @param string The contents of this document.
651 * @param int The doc_group id of the doc_groups table.
652 * @param string The title of this document.
653 * @param int The language id of the supported_languages table.
654 * @param string The description of this document.
655 * @param int The state id of the doc_states table.
656 * @return boolean success.
658 function update($filename,$filetype,$data,$doc_group,$title,$description,$stateid) {
660 if (strlen($title) < 5) {
661 $this->setError(_('Title Must Be At Least 5 Characters'));
664 if (strlen($description) < 10) {
665 $this->setError(_('Document Description Must Be At Least 10 Characters'));
669 $result = db_query_params('SELECT filename,doc_group from docdata_vw',
670 array($filename,$doc_group));
673 if (!$result || db_numrows($res) > 0) {
674 $this->setError(_('Document already published in this directory'));
679 $perm =& $this->Group->getPermission ();
681 if (!$perm || !is_object($perm) || !$perm->isDocEditor()) {
682 $this->setPermissionDeniedError();
685 if ($this->getLockedBy() != $LUSER->getID()) {
686 $this->setPermissionDeniedError();
690 $res = db_query_params ('UPDATE doc_data SET
702 array (htmlspecialchars($title),
703 htmlspecialchars($description),
711 $this->Group->getID(),
714 if (!$res || db_affected_rows($res) < 1) {
715 $this->setOnUpdateError(db_error());
722 // key words for in-document search
723 if ($this->Group->useDocmanSearch()) {
724 $kw = new Parsedata ($this->engine_path);
725 $kwords = $kw->get_parse_data ($data1, htmlspecialchars($title), htmlspecialchars($description), $filetype);
730 $res = db_query_params ('UPDATE doc_data SET filesize=$1, data_words=$2 WHERE group_id=$3 AND docid=$4',
731 array (strlen($data),
733 $this->Group->getID(),
736 if (!$res || db_affected_rows($res) < 1) {
737 $this->setOnUpdateError(db_error());
741 switch ($this->Group->getStorageAPI()) {
743 $res = db_query_params ('UPDATE doc_data SET data = $1 where group_id = $2 and docid = $3',
744 array(base64_encode($data),
745 $this->Group->getID(),
748 if (!$res || db_affected_rows($res) < 1) {
749 $this->setOnUpdateError(db_error());
754 $this->setOnUpdateError(_('No Storage API'));
759 $this->sendNotice(false);
764 * sendNotice - Notifies of document submissions
766 function sendNotice ($new=true) {
767 $BCC = $this->Group->getDocEmailAddress();
768 if ($this->isMonitoredBy('ALL')) {
769 $BCC .= $this->getMonitoredUserEmailAddress();
771 if (strlen($BCC) > 0) {
772 $subject = '['.$this->Group->getPublicName().'] New document - '.$this->getName();
773 $body = "Project: ".$this->Group->getPublicName()."\n";
774 $body .= "Group: ".$groupname."\n";
775 $body .= "Document title: ".$this->getName()."\n";
776 $body .= "Document description: ".util_unconvert_htmlspecialchars( $this->getDescription() )."\n";
777 $body .= "Submitter: ".$this->getCreatorRealName()." (".$this->getCreatorUserName().") \n";
778 $body .= "\n\n-------------------------------------------------------".
779 "\nFor more info, visit:".
780 "\n\n" . util_make_url('/docman/index.php?group_id='.$this->Group->getID());
782 util_send_message('',$subject,$body,'',$BCC);
789 * delete - Delete this file
792 $perm =& $this->Group->getPermission ();
793 if (!$perm || !is_object($perm) || !$perm->isDocEditor()) {
794 $this->setPermissionDeniedError();
798 $result = db_query_params ('DELETE FROM doc_data WHERE docid=$1',
799 array ($this->getID())) ;
801 $this->setError(_('Error Deleting Document: ').db_error());
806 switch ($this->Group->getStorageAPI()) {
810 $this->setError(_('Error Deleting Document: No Storage API'));
815 // we should be able to send a notice that this doc has been deleted .... but we need to rewrite sendNotice
816 //$this->sendNotice(false);
823 // c-file-style: "bsd"