5 * Copyright 1999-2000, Tim Perdue/Sourceforge
6 * Copyright 2002, Tim Perdue/GForge, LLC
7 * Copyright 2009, Roland Mas
8 * Copyright (C) 2011 Alain Peyrat - Alcatel-Lucent
10 * This file is part of FusionForge. FusionForge is free software;
11 * you can redistribute it and/or modify it under the terms of the
12 * GNU General Public License as published by the Free Software
13 * Foundation; either version 2 of the Licence, or (at your option)
16 * FusionForge is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 require_once $gfcommon.'include/Error.class.php';
27 require_once $gfcommon.'forum/ForumMessage.class.php';
28 // This string is used when sending the notification mail for identifying the
30 define('FORUM_MAIL_MARKER', '#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+');
33 * Gets a Forum object from its id
35 * @param int the Forum id
36 * @return object the Forum object
38 function &forum_get_object($forum_id) {
39 $res = db_query_params('SELECT group_id FROM forum_group_list WHERE group_forum_id=$1',
41 if (!$res || db_numrows($res) < 1) {
45 $data = db_fetch_array($res);
46 $Group = group_get_object($data["group_id"]);
47 $f = new Forum($Group, $forum_id);
49 $f->fetchData($forum_id);
54 function forum_get_groupid ($forum_id) {
55 $res = db_query_params('SELECT group_id FROM forum_group_list WHERE group_forum_id=$1',
57 if (!$res || db_numrows($res) < 1) {
60 $arr = db_fetch_array($res);
61 return $arr['group_id'];
64 class Forum extends Error {
67 * Associative array of data from db.
69 * @var array $data_array.
78 var $Group; //group object
81 * An array of 'types' for this forum - nested, flat, ultimate, etc.
83 * @var array view_types.
90 * @param object The Group object to which this forum is associated.
91 * @param int The group_forum_id.
92 * @param array The associative array of data.
93 * @return boolean success.
95 function Forum(&$Group, $group_forum_id=false, $arr=false, $is_news=false) {
97 if (!$Group || !is_object($Group)) {
98 $this->setError(_('Forums: No Valid Group Object'));
101 if ($Group->isError()) {
102 $this->setError('Forums: '.$Group->getErrorMessage());
105 if (!$is_news && $group_forum_id) {
107 // Is this a news posting (or a real forum)?
109 $res = db_query_params('SELECT forum_id FROM news_bytes
111 array($group_forum_id));
112 $is_news = $res && db_numrows($res) >= 1;
114 if (!$is_news && !$Group->usesForum()) {
115 $this->setError(sprintf(_('%s does not use the Forum tool'),
116 $Group->getPublicName()));
119 $this->Group =& $Group;
121 if ($group_forum_id) {
122 if (!$arr || !is_array($arr)) {
123 if (!$this->fetchData($group_forum_id)) {
127 $this->data_array =& $arr;
128 if ($this->data_array['group_id'] != $this->Group->getID()) {
129 $this->setError(_('Group_id in db result does not match Group Object'));
130 $this->data_array = null;
135 // Make sure they can even access this object
138 !forge_check_perm ('forum', $this->getID(), 'read')) {
139 $this->setPermissionDeniedError();
140 $this->data_array = null;
144 $this->view_types[] = 'ultimate';
145 $this->view_types[] = 'flat';
146 $this->view_types[] = 'nested';
147 $this->view_types[] = 'threaded';
148 $this->is_news = $is_news;
153 * create - use this function to create a new entry in the database.
155 * @param string The name of the forum.
156 * @param string The description of the forum.
157 * @param string The email address to send all new posts to.
158 * @param int Pass (1) if a welcome message should be created (0) for no welcome message.
159 * @return boolean success.
161 function create($forum_name,$description,$send_all_posts_to='',$create_default_message=1) {
162 if (!$this->is_news && strlen($forum_name) < 3) {
163 $this->setError(_('Forum Name Must Be At Least 3 Characters'));
166 if (!$this->is_news && strlen($description) < 10) {
167 $this->setError(_('Forum Description Must Be At Least 10 Characters'));
170 if (!preg_match('/^([_\.0-9a-z-])*$/i',$forum_name)) {
171 if (preg_match('/ /',$forum_name)){
172 $this->setError(_('Illegal Characters in Forum Name').' - '._('No space'));
174 $this->setError(_('Illegal Characters in Forum Name'));
178 if ($send_all_posts_to) {
179 $send_all_posts_to = str_replace(';', ',', $send_all_posts_to);
180 $invalid_mails = validate_emails($send_all_posts_to);
181 if (count($invalid_mails) > 0) {
182 $this->setInvalidEmailError($send_all_posts_to);
187 $project_name = $this->Group->getUnixName();
188 $result_list_samename = db_query_params('SELECT 1 FROM mail_group_list WHERE list_name=$1 AND group_id=$2',
190 array($project_name.'-'.strtolower($forum_name),
191 $this->Group->getID()));
193 if (db_numrows($result_list_samename) > 0){
194 $this->setError(_('Mailing List Exists with same name'));
199 // This is a hack to allow non-site-wide-admins to post
200 // news. The news/submit.php checks for proper permissions.
201 // This needs to be revisited.
203 if ($this->Group->getID() == forge_get_config('news_group')) {
204 // Future check will be added.
207 // Current permissions check.
209 if (!forge_check_perm ('forum_admin', $this->Group->getID())) {
210 $this->setPermissionDeniedError();
216 $result = db_query_params('INSERT INTO forum_group_list (group_id,forum_name,description,send_all_posts_to) VALUES ($1,$2,$3,$4)',
217 array($this->Group->getID(),
218 strtolower($forum_name),
219 htmlspecialchars($description),
220 $send_all_posts_to));
222 $this->setError(_('Error Adding Forum:').' '.db_error());
226 $this->group_forum_id=db_insertid($result,'forum_group_list','group_forum_id');
227 $this->fetchData($this->group_forum_id);
229 if ($create_default_message) {
230 $fm=new ForumMessage($this);
231 // Use the system side default language
232 setup_gettext_from_sys_lang();
233 $string = sprintf(_('Welcome to %1$s'), $forum_name);
234 // and switch back to the user preference
235 setup_gettext_from_context();
236 if (!$fm->create($string, $string)) {
237 $this->setError($fm->getErrorMessage());
242 $this->Group->normalizeAllRoles () ;
248 * fetchData - re-fetch the data for this forum from the database.
250 * @param int The forum_id.
251 * @return boolean success.
253 function fetchData($group_forum_id) {
254 $res=db_query_params('SELECT * FROM forum_group_list_vw WHERE group_forum_id=$1 AND group_id=$2',
255 array($group_forum_id, $this->Group->getID()));
256 if (!$res || db_numrows($res) < 1) {
257 $this->setError(_('Invalid forum group identifier'));
260 $this->data_array = db_fetch_array($res);
261 db_free_result($res);
266 * getGroup - get the Group object this ArtifactType is associated with.
268 * @return object The Group object.
270 function &getGroup() {
275 * getID - The id of this forum.
277 * @return int The group_forum_id #.
280 return $this->data_array['group_forum_id'];
284 * getNextThreadID - The next thread_id for a new top in this forum.
286 * @return int The next thread_id #.
288 function getNextThreadID() {
289 $result = db_query_params('SELECT nextval($1)',
290 array('forum_thread_seq'));
291 if (!$result || db_numrows($result) < 1) {
295 return db_result($result, 0, 0);
299 * getUnixName - returns the name used by email gateway
301 * @return string unix name
303 function getUnixName() {
304 return $this->Group->getUnixName().'-'.$this->getName();
308 * getSavedDate - The unix time when the person last hit "save my place".
310 * @return int The unix time.
312 function getSavedDate() {
313 if (isset($this->save_date)) {
314 return $this->save_date;
316 if (session_loggedin()) {
317 $result = db_query_params('SELECT save_date FROM forum_saved_place WHERE user_id=$1 AND forum_id=$2',
320 if ($result && db_numrows($result) > 0) {
321 $this->save_date=db_result($result, 0, 'save_date');
322 return $this->save_date;
324 //highlight new messages from the past week only
325 $this->save_date=(time()-604800);
326 return $this->save_date;
329 //highlight new messages from the past week only
330 $this->save_date=(time()-604800);
331 return $this->save_date;
337 * getName - get the name of this forum.
339 * @return string The name of this forum.
342 return $this->data_array['forum_name'];
346 * getSendAllPostsTo - an optional email address to send all forum posts to.
348 * @return string The email address.
350 function getSendAllPostsTo() {
351 return $this->data_array['send_all_posts_to'];
355 * getDescription - the description of this forum.
357 * @return string The description.
359 function getDescription() {
360 return $this->data_array['description'];
364 * getMessageCount - the total number of messages in this forum.
366 * @return int The count.
368 function getMessageCount() {
369 return $this->data_array['total'];
373 * getThreadCount - the total number of threads in this forum.
375 * @return int The count.
377 function getThreadCount() {
378 return $this->data_array['threads'];
382 * getMostRecentDate - the most recent date of a post to this board.
384 * @return int The most recent date.
386 function getMostRecentDate() {
387 return $this->data_array['recent'];
391 * getMonitoringIDs - return an array of user_id's for those monitoring this forum.
393 * @return array The array of user_id's.
395 function getMonitoringIDs() {
396 $result = db_query_params('SELECT user_id FROM forum_monitored_forums WHERE forum_id=$1',
397 array($this->getID()));
398 return util_result_column_to_array($result);
402 * getReturnEmailAddress() - return the return email address for notification emails
404 * @return string return email address
406 function getReturnEmailAddress() {
408 if(forge_get_config('use_gateways')) {
409 $address = $this->getUnixName();
411 $address = 'noreply';
414 if(forge_get_config('use_gateways') && forge_get_config('forum_return_domain')) {
415 $address .= forge_get_config('forum_return_domain');
417 $address .= forge_get_config('web_host');
423 * setMonitor - Add the current user to the list of people monitoring the forum.
425 * @param int user id of the user which will be set to monitor this forum. Defaults to 0, meaning the current logged in user will be used.
426 * @return boolean success.
428 function setMonitor($u = -1) {
430 if (!session_loggedin()) {
431 $this->setError(_('You can only monitor if you are logged in'));
436 $result = db_query_params('SELECT * FROM forum_monitored_forums WHERE user_id=$1 AND forum_id=$2',
439 if (!$result || db_numrows($result) < 1) {
441 User is not already monitoring thread, so
442 insert a row so monitoring can begin
444 $result = db_query_params('INSERT INTO forum_monitored_forums (forum_id,user_id) VALUES ($1,$2)',
445 array($this->getID(),
449 $this->setError(_('Unable To Add Monitor').' : '.db_error());
458 * stopMonitor - Remove the current user from the list of people monitoring the forum.
460 * @return boolean success.
462 function stopMonitor($u = -1) {
464 if (!session_loggedin()) {
465 $this->setError(_('You can only monitor if you are logged in'));
470 return db_query_params('DELETE FROM forum_monitored_forums WHERE user_id=$1 AND forum_id=$2',
476 * isMonitoring - See if the current user is in the list of people monitoring the forum.
478 * @return boolean is_monitoring.
480 function isMonitoring() {
481 if (!session_loggedin()) {
484 $result = db_query_params('SELECT count(*) AS count FROM forum_monitored_forums WHERE user_id=$1 AND forum_id=$2',
487 $row_count = db_fetch_array($result);
488 return $result && $row_count['count'] > 0;
492 * savePlace - set a unix time into the database for this user, so future messages can be highlighted.
494 * @return boolean success.
496 function savePlace() {
497 if (!session_loggedin()) {
498 $this->setError(_('You Can Only Save Your Place If You Are Logged In'));
501 $result = db_query_params('SELECT * FROM forum_saved_place WHERE user_id=$1 AND forum_id=$2',
505 if (!$result || db_numrows($result) < 1) {
507 User is not already monitoring thread, so
508 insert a row so monitoring can begin
510 $result = db_query_params('INSERT INTO forum_saved_place (forum_id,user_id,save_date) VALUES ($1,$2,$3)',
511 array($this->getID(),
516 $this->setError(_('Forum::savePlace()').': '.db_error());
521 $result = db_query_params('UPDATE forum_saved_place SET save_date=$1 WHERE user_id=$2 AND forum_id=$3',
527 $this->setError('Forum::savePlace() '.db_error());
535 * update - use this function to update an entry in the database.
537 * @param string The name of the forum.
538 * @param string The description of the forum.
539 * @param string The email address to send all new posts to.
540 * @return boolean success.
542 function update($forum_name, $description, $send_all_posts_to = '') {
543 if (strlen($forum_name) < 3) {
544 $this->setError(_('Forum Name Must Be At Least 3 Characters'));
547 if (strlen($description) < 10) {
548 $this->setError(_('Forum Description Must Be At Least 10 Characters'));
551 if (!preg_match('/^([_\.0-9a-z-])*$/i',$forum_name)) {
552 if (preg_match('/ /',$forum_name)){
553 $this->setError(_('Illegal Characters in Forum Name').' - '._('No space'));
555 $this->setError(_('Illegal Characters in Forum Name'));
559 if ($send_all_posts_to) {
560 $send_all_posts_to = str_replace(';', ',', $send_all_posts_to);
561 $invalid_mails = validate_emails($send_all_posts_to);
562 if (count($invalid_mails) > 0) {
563 $this->setInvalidEmailError($send_all_posts_to);
568 if (!forge_check_perm('forum_admin', $this->Group->getID())) {
569 $this->setPermissionDeniedError();
573 $res = db_query_params('UPDATE forum_group_list SET
578 AND group_forum_id=$5',
579 array(strtolower($forum_name),
580 htmlspecialchars($description),
582 $this->Group->getID(),
585 if (!$res || db_affected_rows($res) < 1) {
586 $this->setError(_('Error On Update:').': '.db_error());
593 * delete - delete this forum and all its related data.
595 * @param bool I'm Sure.
596 * @param bool I'm REALLY sure.
597 * @return bool true/false;
599 function delete($sure, $really_sure) {
600 if (!$sure || !$really_sure) {
601 $this->setMissingParamsError(_('Please tick all checkboxes.'));
604 if (!forge_check_perm ('forum_admin', $this->Group->getID())) {
605 $this->setPermissionDeniedError();
609 $result = db_query_params('DELETE FROM forum_agg_msg_count WHERE group_forum_id=$1',
610 array($this->getID()));
612 $this->setError(_('Error Deleting Forum:').' '.db_error());
617 $result = db_query_params('DELETE FROM forum_monitored_forums WHERE forum_id=$1',
618 array($this->getID()));
620 $this->setError(_('Error Deleting Forum:').' '.db_error());
625 $result = db_query_params('DELETE FROM forum_saved_place WHERE forum_id=$1',
626 array($this->getID()));
628 $this->setError(_('Error Deleting Forum:').' '.db_error());
633 $result = db_query_params('DELETE FROM forum_attachment WHERE msg_id IN (SELECT msg_id from forum where group_forum_id=$1)',
634 array($this->getID()));
636 $this->setError(_('Error Deleting Forum:').' '.db_error());
641 $result = db_query_params('DELETE FROM forum WHERE group_forum_id=$1',
642 array($this->getID()));
644 $this->setError(_('Error Deleting Forum:').' '.db_error());
649 $result = db_query_params('DELETE FROM forum_group_list WHERE group_forum_id=$1',
650 array($this->getID()));
652 $this->setError(_('Error Deleting Forum:').' '.db_error());
659 $this->Group->normalizeAllRoles();
668 // c-file-style: "bsd"