5 * Copyright 1999-2001, Tim Perdue - Sourceforge
6 * Copyright 2002, Tim Perdue - GForge, LLC
7 * Copyright 2010 (c) Franck Villaume - Capgemini
8 * Copyright (C) 2010-2012 Alain Peyrat - Alcatel-Lucent
9 * Copyright 2013, French Ministry of National Education
10 * Copyright 2013-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 $gfwww.'include/note.php';
30 require_once $gfwww.'include/trove.php';
31 require_once $gfwww.'news/news_utils.php';
32 require_once $gfcommon.'forum/ForumAdmin.class.php';
33 require_once $gfcommon.'forum/AttachManager.class.php';
35 function forum_header($params = array()) {
36 global $HTML, $group_id, $forum_id, $f, $group_forum_id;
38 if ($group_forum_id) {
39 $forum_id = $group_forum_id;
41 if (!forge_get_config('use_forum')) {
45 $params['group'] = $group_id;
46 $params['toptab'] = 'forums';
49 // Check if this is a news item, to display it at the top of the page
50 $result = db_query_params('SELECT submitted_by, post_date, group_id, forum_id, summary, details FROM news_bytes WHERE forum_id=$1',
53 if (db_numrows($result) == 1) {
55 // checks which group the news item belongs to
56 $params['group'] = db_result($result, 0, 'group_id');
57 $params['toptab'] = 'news';
58 $params['title'] = _('Forum')._(': ').db_result($result,0,'summary');
59 $HTML->header($params);
61 echo '<table><tr><td class="top">';
62 $user = user_get_object(db_result($result,0,'submitted_by'));
63 $group = group_get_object($params['group']);
64 if (!$group || !is_object($group) || $group->isError()) {
68 <strong>'._('Posted by')._(': ').'</strong> '.$user->getRealName().'<br />
69 <strong>'._('Date')._(': ').'</strong> '. relative_date(db_result($result,0,'post_date')).'<br />
70 <strong>'._('Summary')._(': ').'</strong>'.
71 util_make_link('/forum/forum.php?forum_id='.db_result($result, 0, 'forum_id').'&group_id='.$group_id,
72 db_result($result, 0, 'summary')).'<br/>
73 <strong>'._('Project')._(': ').'</strong>'.
74 util_make_link_g($group->getUnixName(),db_result($result, 0, 'group_id'),$group->getPublicName()).'<br />
78 // display classification
79 if ($params['group'] == forge_get_config('news_group')) {
80 print stripslashes(trove_getcatlisting(db_result($result,0,'forum_id'),0,1));
81 } elseif (forge_get_config('use_trove')) {
82 print stripslashes(trove_getcatlisting($params['group'],0,1));
85 echo '<p><strong>'._('Content')._(':').'</strong></p>';
86 $body = db_result($result,0,'details');
87 $body = TextSanitizer::purify($body);
88 if (!strstr($body,'<')) {
89 //backwards compatibility for non html messages
90 echo util_make_links(nl2br($body));
92 echo util_make_links($body);
94 echo '</td><td class="top" style="width:35%">';
95 echo $HTML->boxTop(_('Latest News'));
96 echo news_show_latest($params['group'],5,false);
97 echo $HTML->boxBottom();
98 echo '</td></tr></table>';
100 $HTML->header($params);
103 $menu_text = array();
104 $menu_links = array();
106 $menu_text[] = _('View Forums');
107 $menu_links[] = '/forum/?group_id='.$group_id;
111 $menu_text[]=_('Discussion Forums:') .' '. $f->getName();
112 $menu_links[]='/forum/forum.php?forum_id='.$forum_id;
114 if (forge_check_perm ('forum_admin', $f->Group->getID())) {
115 $menu_text[]=_('Administration');
116 $menu_links[]='/forum/admin/?group_id='.$group_id;
119 if (forge_check_perm ('forum_admin', $group_id)) {
120 $menu_text[]=_('Administration');
121 $menu_links[]='/forum/admin/?group_id='.$group_id;
124 if (count($menu_text) > 0) {
125 $params['submenu'] =$HTML->subMenu($menu_text,$menu_links);
128 site_project_header($params);
131 $pluginManager = plugin_manager_get_object();
132 if ($f && $pluginManager->PluginIsInstalled('blocks') && plugin_hook("blocks", "forum_".$f->getName()))
135 if (session_loggedin()) {
137 if ($f->isMonitoring()) {
138 echo util_make_link('/forum/monitor.php?forum_id='.$forum_id.'&group_id='.$group_id.'&stop=1',
139 html_image('ic/xmail16w.png').' '._('Stop monitoring')).' | ';
141 echo util_make_link('/forum/monitor.php?forum_id='.$forum_id.'&group_id='.$group_id.'&start=1',
142 html_image('ic/mail16w.png').' '._('Monitor Forum')).' | ';
144 echo util_make_link('/forum/save.php?forum_id='.$forum_id.'&group_id='.$group_id,
145 html_image('ic/save.png') .' '._('Save Place')).' | ';
148 echo util_make_link('/forum/monitor.php?forum_id='.$forum_id.'&group_id='.$group_id.'&start=1', html_image('ic/mail16w.png').' '._('Monitor Forum')).' | ';
151 if ($f && $forum_id) {
152 echo util_make_link ('/forum/new.php?forum_id='.$forum_id.'&group_id='.$group_id,
153 html_image('ic/write16w.png', 20, 20, array('alt'=>_('Start New Thread'))) .' '.
154 _('Start New Thread'));
158 function forum_footer($params = array()) {
159 site_project_footer($params);
164 * Wrap many forum functions in this class
167 class ForumHTML extends FFError {
175 function __construct(&$Forum) {
176 parent::__construct();
177 if (!$Forum || !is_object($Forum)) {
178 $this->setError(_('Invalid Forum Object'));
181 if ($Forum->isError()) {
182 $this->setError('ForumMessage: '.$Forum->getErrorMessage());
185 $this->Forum =& $Forum;
190 * showPendingMessage - get the HTML code of a pending message
192 * @param object $msg The message.
193 * @return string return the html output
195 function showPendingMessage(&$msg) {
196 global $HTML,$group_id;
198 $am = new AttachManager();
199 $ret_val = $am->PrintHelperFunctions();
200 html_feedback_top(_('This is the content of the pending message'));
201 $bold_begin='<strong>';
202 $bold_end='</strong>';
206 <td class="tablecontent" style="white-space: nowrap;">'._('By')._(': ').
207 $msg->getPosterRealName().
210 $msgforum =& $msg->getForum();
211 $ret_val .= $am->PrintAttachLink($msg,$group_id,$msgforum->getID()) . '
214 html_image('ic/msg.png') .
215 $bold_begin. $msg->getSubject() . $bold_end .
216 '<br />'. date(_('Y-m-d H:i'),$msg->getPostDate()) .'
221 '. $msg->getBody() .'
229 function showNestedMessage(&$msg) {
232 accepts a database result handle to display a single message
233 in the format appropriate for the nested messages
236 global $HTML,$group_id;
238 See if this message is new or not
239 If so, highlight it in bold
241 if ($this->Forum->getSavedDate() < $msg->getPostDate()) {
242 $bold_begin='<strong>';
243 $bold_end='</strong>';
248 $am = new AttachManager();
249 $msgforum =& $msg->getForum();
250 $fa = new ForumAdmin($msgforum->Group->getID());
251 $url = util_make_uri('/forum/message.php?msg_id='. $msg->getID() .'&group_id='.$group_id);
252 $ret_val = $HTML->listTableTop().'
254 <td class="tablecontent top" style="white-space: nowrap;">';
256 $params = array('user_id' => $msg->getPosterID(), 'size' => 's', 'content' => '');
257 plugin_hook_by_reference("user_logo", $params);
258 if ($params['content']) {
259 $ret_val .= $params['content'];
262 $ret_val .= $bold_begin. $msg->getSubject(). ' <a href="'.$url.'">[ '._("Reply").' ]</a>'. $bold_end;
263 $ret_val .= '<br/>'._('By')._(': ').util_make_link_u ($msg->getPosterName(),$msg->getPosterID(),$msg->getPosterRealName());
264 $ret_val .= ' on '.date('Y-m-d H:i',$msg->getPostDate());
265 $ret_val .= '</td><td class="tablecontent align-right">';
266 $ret_val .= '<a href="'.$url.'">[forum:'.$msg->getID().']</a><br/>';
267 if (forge_check_perm('forum_admin', $msgforum->Group->getID())) {
268 $ret_val .= $fa->PrintAdminMessageOptions($msg->getID(),$group_id,$msg->getThreadID(),$msgforum->getID());
270 $ret_val .= $am->PrintAttachLink($msg,$group_id,$msgforum->getID());
277 if (strpos($msg->getBody(),'<') === false) {
278 $ret_val .= nl2br($msg->getBody()); //backwards compatibility for non html messages
280 $ret_val .= $msg->getBody();
284 </tr>'.$HTML->listTableBottom();
289 * LinkAttachEditForm - Returns the link to the attach form for editing
291 * @param string $filename Filename
292 * @param int $group_id group id
293 * @param int $forum_id forum id
294 * @param int $attachid attach id
295 * @param int $msg_id msg id
296 * @return string The HTML output
298 function LinkAttachEditForm($filename,$group_id,$forum_id,$attachid,$msg_id) {
300 $return_val = $HTML->openForm(array('method' => 'post', 'enctype' => 'multipart/form-data', 'action' => '/forum/attachment.php?attach_id='.$attachid.'group='.$group_id.'&forum_id='.$forum_id.'&msg_id='.$msg_id));
304 <td>' . _('Current File') . ": <span class=\"selected\">" . $filename . '</span></td>
308 <fieldset class=\"fieldset\">
312 <td>' . _('Use the “Browse” button to find the file you want to attach') . '</td>
315 <td>' . _('File to upload') . ': <input type="file" name="attachment1"/></td>
318 <td>'.$HTML->warning_msg(_('Warning: Uploaded file will replace current file')).'</td>
321 <input type="submit" name="go" value="'._('Update').'" />
322 <input type="hidden" name="doedit" value="1" />
323 <input type="hidden" name="edit" value="yes" />
324 <input type="hidden" name="forum_id" value="'.$forum_id.'" />
325 <input type="hidden" name="group_id" value="'.$group_id.'" />
326 <input type="hidden" name="attachid" value="'.$attachid.'" />
327 <input type="hidden" name="msg_id" value="'.$msg_id.'" />
329 $return_val .= $HTML->closeForm();
334 * LinkAttachForm - echoes the link to the attach form
336 function LinkAttachForm() {
338 <fieldset class="fieldset">
339 <legend>' . _('Attachments') . "</legend>
342 <td>" . _('Use the “Browse” button to find the file you want to attach') . "</td>
345 <td>" . _('File to upload') . ": <input type=\"file\" name=\"attachment1\"/></td>
353 * @param string $msg_arr
354 * @param string $msg_id
357 function showNestedMessages(&$msg_arr, $msg_id) {
360 $rows=count($msg_arr["$msg_id"]);
363 if ($msg_arr["$msg_id"] && $rows > 0) {
365 <ul><li style="list-style: none">';
368 iterate and show the messages in this result
369 for each message, recurse to show any submessages
371 for ($i=($rows-1); $i >= 0; $i--) {
372 // increment the global total count
375 // show the actual nested message
376 $ret_val .= $this->showNestedMessage ($msg_arr["$msg_id"][$i]).'<p />';
378 if ($msg_arr["$msg_id"][$i]->hasFollowups()) {
379 // Call yourself if there are followups
380 $ret_val .= $this->showNestedMessages ( $msg_arr,$msg_arr["$msg_id"][$i]->getID() );
386 //$ret_val .= "<p><strong>no messages actually follow up to $msg_id</strong>";
398 function showSubmessages(&$msg_arr, $msg_id, $level) {
400 Recursive. Selects this message's id in this thread,
401 then checks if any messages are nested underneath it.
402 If there are, it calls itself, incrementing $level
403 $level is used for indentation of the threads.
405 global $total_rows,$current_message,$group_id, $HTML;
407 if (!isset($msg_arr["$msg_id"]))
410 $rows=count($msg_arr["$msg_id"]);
412 //echo "<p>ShowSubmessages() $msg_id | $rows";
414 for ($i=($rows-1); $i >= 0; $i--) {
416 Is this row's background shaded or not?
421 <tr '. $HTML->boxGetAltRowStyle($total_rows) .'><td style="white-space: nowrap;">';
423 How far should it indent?
425 for ($i2=0; $i2<$level; $i2++) {
426 $ret_val .= ' ';
430 If it this is the message being displayed, don't show a link to it
432 if ($current_message != $msg_arr[$msg_id][$i]->getID()) {
433 $ah_begin='<a href="'.util_make_uri('/forum/message.php?msg_id='. $msg_arr[$msg_id][$i]->getID() .'&group_id='.$group_id).'">';
440 $ret_val .= $ah_begin .
441 html_image('ic/msg.png').' ';
443 See if this message is new or not
445 if ($this->Forum->getSavedDate() < $msg_arr[$msg_id][$i]->getPostDate()) {
446 $bold_begin='<strong>';
447 $bold_end='</strong>';
453 $ret_val .= $bold_begin.$msg_arr[$msg_id][$i]->getSubject() .$bold_end.$ah_end.'</td>'.
454 '<td>'.util_display_user($msg_arr[$msg_id][$i]->getPosterName(),$msg_arr[$msg_id][$i]->getPosterID(),$msg_arr[$msg_id][$i]->getPosterRealName()) .'</td>'.
455 '<td>'.relative_date($msg_arr[$msg_id][$i]->getPostDate()).'</td></tr>';
457 if ($msg_arr[$msg_id][$i]->hasFollowups() > 0) {
459 Call yourself, incrementing the level
461 $ret_val .= $this->showSubmessages($msg_arr,$msg_arr[$msg_id][$i]->getID(),($level+1));
469 * showEditForm - Prints the form to edit a message
471 * @param int $msg The Message
472 * @return The HTML output echoed
474 function showEditForm(&$msg) {
476 $thread_id = $msg->getThreadID();
477 $msg_id = $msg->getID();
478 $posted_by = $msg->getPosterID();
479 $subject = $msg->getSubject();
480 $body = $msg->getBody();
481 $post_date = $msg->getPostDate();
482 $is_followup_to = $msg->getParentID();
483 $has_followups = $msg->hasFollowups();
484 $most_recent_date = $msg->getMostRecentDate();
485 $g = $this->Forum->getGroup();
486 $group_id = $g->getID();
488 if (forge_check_perm ('forum', $this->Forum->getID(), 'post')) { // minor control, but anyways it should be an admin at this point
491 <div style="margin-left: auto; margin-right: auto;">
492 <?php echo $HTML->openForm(array('id' => 'ForumEditForm', 'enctype' => 'multipart/form-data', 'action' => '/forum/admin/index.php', 'method' => 'post'));
493 $objid = $this->Forum->getID(); ?>
494 <input type="hidden" name="thread_id" value="<?php echo $thread_id; ?>" />
495 <input type="hidden" name="forum_id" value="<?php echo $objid; ?>" />
496 <input type="hidden" name="editmsg" value="<?php echo $msg_id; ?>" />
497 <input type="hidden" name="is_followup_to" value="<?php echo $is_followup_to; ?>" />
498 <input type="hidden" name="form_key" value="<?php echo form_generate_key();?>" />
499 <input type="hidden" name="posted_by" value="<?php echo $posted_by;?>" />
500 <input type="hidden" name="post_date" value="<?php echo $post_date;?>" />
501 <input type="hidden" name="has_followups" value="<?php echo $has_followups;?>" />
502 <input type="hidden" name="most_recent_date" value="<?php echo $most_recent_date;?>" />
503 <input type="hidden" name="group_id" value="<?php echo $group_id;?>" />
504 <fieldset class="fieldset">
505 <legend><?php echo _('Edit Message'); ?></legend>
506 <table><tr><td class="top">
507 </td><td class="top">
509 <strong><?php echo _('Subject').utils_requiredField()._(':'); ?></strong><br />
510 <input type="text" autofocus="autofocus" required="required" name="subject" value="<?php echo $subject; ?>" size="80" maxlength="80" />
513 <strong><?php echo _('Message').utils_requiredField()._(': '); ?></strong>
514 <?php echo notepad_button('document.forms.ForumEditForm.body'); ?>
517 $GLOBALS['editor_was_set_up']=false;
519 $params['body'] = $body;
520 $params['width'] = "800";
521 $params['height'] = "500";
522 $params['group'] = $group_id;
523 plugin_hook("text_editor",$params);
524 if (!$GLOBALS['editor_was_set_up']) {
525 //if we don't have any plugin for text editor, display a simple textarea edit box
526 echo '<textarea required="required" name="body" rows="10" cols="70">' . $body . '</textarea>';
528 unset($GLOBALS['editor_was_set_up']);
531 <p style="text-align: center">
532 <input type="submit" name="ok" value="<?php echo _('Update'); ?>" />
533 <input type="submit" name="cancel" formnovalidate="formnovalidate" value="<?php echo _('Cancel'); ?>" />
535 </td></tr></table></fieldset>
536 <?php echo $HTML->closeForm(); ?>
543 * @param int $thread_id
544 * @param int $is_followup_to
545 * @param string $subject
547 function showPostForm($thread_id=0, $is_followup_to=0, $subject="") {
548 global $group_id, $HTML;
552 $rl = RoleLoggedIn::getInstance() ;
553 if (forge_check_perm ('forum', $this->Forum->getID(), 'post')) {
554 //if this is a followup, put a RE: before it if needed
555 if ($subject && !preg_match('/RE:/i',$subject,$test)) {
556 $subject ='RE: '.$subject;
560 <div class="align-center">
561 <?php echo $HTML->openForm(array('id' => 'ForumPostForm', 'enctype' => 'multipart/form-data', 'action' => '/forum/forum.php?forum_id='.$this->Forum->getID().'&group_id='.$group_id, 'method' => 'post')); ?>
562 <input type="hidden" name="post_message" value="y" />
563 <input type="hidden" name="thread_id" value="<?php echo $thread_id; ?>" />
564 <input type="hidden" name="msg_id" value="<?php echo $is_followup_to; ?>" />
565 <input type="hidden" name="is_followup_to" value="<?php echo $is_followup_to; ?>" />
566 <input type="hidden" name="form_key" value="<?php echo form_generate_key();?>" />
567 <fieldset class="fieldset"><table><tr>
571 <strong><?php echo _('Subject').utils_requiredField()._(': '); ?></strong><br />
572 <input type="text" autofocus="autofocus" required="required" name="subject" value="<?php echo $subject; ?>" size="80" maxlength="80" />
574 <strong><?php echo _('Message').utils_requiredField()._(': '); ?></strong>
575 <?php echo notepad_button('document.forms.ForumPostForm.body') ?><br />
578 $GLOBALS['editor_was_set_up']=false;
580 $params['body'] = $body;
581 $params['width'] = "800";
582 $params['height'] = "500";
583 $params['group'] = $group_id;
584 plugin_hook("text_editor",$params);
585 if (!$GLOBALS['editor_was_set_up']) {
586 //if we don't have any plugin for text editor, display a simple textarea edit box
587 echo '<textarea required="required" name="body" rows="10" cols="70">' . $body . '</textarea>';
589 unset($GLOBALS['editor_was_set_up']);
590 //$text_support->displayTextField('body'); ?>
592 <!-- <span class="selected"><?php echo _('HTML tags will display in your post as text'); ?></span> -->
594 <?php $this->LinkAttachForm();?>
597 if (!session_loggedin()) {
598 echo '<span class="highlight">';
599 printf (_('You are posting anonymously because you are not <a href="%s">logged in</a>'),util_make_url ('/account/login.php?return_to='. urlencode(getStringFromServer('REQUEST_URI'))));
603 <input type="submit" name="submit"
604 value="<?php echo _('Post Comment'); echo ((!session_loggedin())?' '._('Anonymously'):''); ?>" /><?php
605 echo ((session_loggedin()) ? ' <input type="checkbox" value="1" name="monitor" /> '._('Receive comments via email').'.' : ''); ?>
611 <?php echo $HTML->closeForm(); ?>
615 } elseif ($rl->hasPermission('forum', $this->Forum->getID(), 'post')) {
616 echo $HTML->error_msg(_('You could post if you were <a href="%s">logged in</a>.'), util_make_uri('/account/login.php?return_to='.urlencode(getStringFromServer('REQUEST_URI'))));
617 } elseif (!session_loggedin()) {
618 echo $HTML->error_msg(_('Please <a href="%s">log in</a>'), util_make_uri('/account/login.php?return_to='.urlencode(getStringFromServer('REQUEST_URI'))));
626 // c-file-style: "bsd"