view.php 12 KB
Newer Older
Clare Lenihan's avatar
Clare Lenihan committed
1
2
<?php
/**
3
 * Mahara: Electronic portfolio, weblog, resume builder and social networking
4
5
 * Copyright (C) 2006-2009 Catalyst IT Ltd and others; see:
 *                         http://wiki.mahara.org/Contributors
Clare Lenihan's avatar
Clare Lenihan committed
6
 *
7
8
9
10
 * This program 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 3 of the License, or
 * (at your option) any later version.
Clare Lenihan's avatar
Clare Lenihan committed
11
 *
12
13
14
15
 * This program 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.
Clare Lenihan's avatar
Clare Lenihan committed
16
 *
17
18
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
Clare Lenihan's avatar
Clare Lenihan committed
19
20
21
 *
 * @package    mahara
 * @subpackage interaction-forum
22
 * @author     Catalyst IT Ltd
Clare Lenihan's avatar
Clare Lenihan committed
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL
24
 * @copyright  (C) 2006-2009 Catalyst IT Ltd http://catalyst.net.nz
Clare Lenihan's avatar
Clare Lenihan committed
25
26
 *
 */
27

Clare Lenihan's avatar
Clare Lenihan committed
28
define('INTERNAL', 1);
29
define('PUBLIC', 1);
30
define('MENUITEM', 'groups/forums');
31
32
33
34
define('SECTION_PLUGINTYPE', 'interaction');
define('SECTION_PLUGINNAME', 'forum');
define('SECTION_PAGE', 'view');

Clare Lenihan's avatar
Clare Lenihan committed
35
36
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
require_once('group.php');
Clare Lenihan's avatar
Clare Lenihan committed
37
safe_require('interaction', 'forum');
38
39
require_once(get_config('docroot') . 'interaction/lib.php');
require_once('pieforms/pieform.php');
Clare Lenihan's avatar
Clare Lenihan committed
40
41
42
43
44
45

$forumid = param_integer('id');
$offset = param_integer('offset', 0);
$userid = $USER->get('id');
$topicsperpage = 25;

Clare Lenihan's avatar
Clare Lenihan committed
46
47
48
// if offset isn't a multiple of $topicsperpage, make it the closest smaller multiple
$offset = (int)($offset / $topicsperpage) * $topicsperpage;

49
$forum = get_record_sql(
50
    'SELECT f.title, f.description, f.id, COUNT(t.id) AS topiccount, s.forum AS subscribed, g.id AS groupid, g.name AS groupname, ic.value AS newtopicusers
Clare Lenihan's avatar
Clare Lenihan committed
51
    FROM {interaction_instance} f
52
    INNER JOIN {group} g ON (g.id = f."group" AND g.deleted = ?)
Clare Lenihan's avatar
Clare Lenihan committed
53
54
    LEFT JOIN {interaction_forum_topic} t ON (t.forum = f.id AND t.deleted != 1 AND t.sticky != 1)
    LEFT JOIN {interaction_forum_subscription_forum} s ON (s.forum = f.id AND s."user" = ?)
55
    LEFT JOIN {interaction_forum_instance_config} ic ON (f.id = ic.forum AND ic.field = \'createtopicusers\')
56
    WHERE f.id = ?
57
    AND f.deleted != 1
58
    GROUP BY 1, 2, 3, 5, 6, 7, 8',
59
    array(0, $userid, $forumid)
Clare Lenihan's avatar
Clare Lenihan committed
60
61
);

62
define('GROUP', $forum->groupid);
63

64
if (!$forum) {
65
    throw new InteractionInstanceNotFoundException(get_string('cantfindforum', 'interaction.forum', $forumid));
Clare Lenihan's avatar
Clare Lenihan committed
66
67
}

68
69
70
$membership = user_can_access_forum((int)$forumid);
$admin = (bool)($membership & INTERACTION_FORUM_ADMIN);
$moderator = (bool)($membership & INTERACTION_FORUM_MOD);
Evan Goldenberg's avatar
Evan Goldenberg committed
71
72
$publicgroup = get_field('group', 'public', 'id', $forum->groupid);
if (!$membership && !$publicgroup) {
73
    throw new GroupAccessDeniedException(get_string('cantviewforums', 'interaction.forum'));
Clare Lenihan's avatar
Clare Lenihan committed
74
75
}

76
define('TITLE', $forum->groupname . ' - ' . $forum->title);
Clare Lenihan's avatar
Clare Lenihan committed
77

Evan Goldenberg's avatar
Evan Goldenberg committed
78
79
$feedlink = get_config('wwwroot') . 'interaction/forum/atom.php?type=f&id=' . $forum->id;

80
81
82
83
84
85
$moderators = get_column_sql(
    'SELECT gm.user FROM {interaction_forum_moderator} gm
    INNER JOIN {usr} u ON (u.id = gm.user AND u.deleted = 0)
    WHERE gm.forum = ?',
    array($forumid)
);
86

87
// updates the selected topics as subscribed/closed/sticky
88
if ($membership && isset($_POST['checked'])) {
89
    $checked = array_map('intval', array_keys($_POST['checked']));
Clare Lenihan's avatar
Clare Lenihan committed
90
    // get type based on which button was pressed
91
92
    if (isset($_POST['updatetopics'])) {
        $type = $_POST['type'];
Clare Lenihan's avatar
Clare Lenihan committed
93
    }
94
95
    // check that user is only messing with topics from this forum
    $alltopics = get_column('interaction_forum_topic', 'id', 'forum', $forumid, 'deleted', 0);
96
    if ($checked == array_intersect($checked, $alltopics)) { // $checked is a subset of the topics in this forum
97
        form_validate(param_variable('sesskey', null));
Clare Lenihan's avatar
Clare Lenihan committed
98
        if ($moderator && $type == 'sticky') {
99
            set_field_select('interaction_forum_topic', 'sticky', 1, 'id IN (' . implode(',', $checked) . ')', array());
100
101
            $SESSION->add_ok_msg(get_string('topicstickysuccess', 'interaction.forum'));
        }
Clare Lenihan's avatar
Clare Lenihan committed
102
        else if ($moderator && $type == 'unsticky') {
103
            set_field_select('interaction_forum_topic', 'sticky', 0, 'id IN (' . implode(',', $checked) . ')', array());
Clare Lenihan's avatar
Clare Lenihan committed
104
105
106
            $SESSION->add_ok_msg(get_string('topicunstickysuccess', 'interaction.forum'));
        }
        else if ($moderator && $type == 'closed') {
107
            set_field_select('interaction_forum_topic', 'closed', 1, 'id IN (' . implode(',', $checked) . ')', array());
108
109
            $SESSION->add_ok_msg(get_string('topicclosedsuccess', 'interaction.forum'));
        }
Clare Lenihan's avatar
Clare Lenihan committed
110
        else if ($moderator && $type == 'open') {
111
            set_field_select('interaction_forum_topic', 'closed', 0, 'id IN (' . implode(',', $checked) . ')', array());
112
            $SESSION->add_ok_msg(get_string('topicopenedsuccess', 'interaction.forum'));
Clare Lenihan's avatar
Clare Lenihan committed
113
114
115
        }
        else if ($type == 'subscribe' && !$forum->subscribed) {
            db_begin();
116
            foreach ($checked as $key => $value) {
117
118
119
120
121
122
                if (!record_exists('interaction_forum_subscription_topic', 'user', $USER->get('id'), 'topic', $value)) {
                    insert_record('interaction_forum_subscription_topic',
                        (object) array(
                            'user'  => $USER->get('id'),
                            'topic' => $value,
                            'key'   => PluginInteractionForum::generate_unsubscribe_key(),
123
                    ));
124
                }
125
            }
Clare Lenihan's avatar
Clare Lenihan committed
126
            db_commit();
127
128
            $SESSION->add_ok_msg(get_string('topicsubscribesuccess', 'interaction.forum'));
        }
Clare Lenihan's avatar
Clare Lenihan committed
129
130
        else if ($type == 'unsubscribe' && !$forum->subscribed) {
            delete_records_sql('DELETE FROM {interaction_forum_subscription_topic}
131
                WHERE topic IN (' . implode(',', $checked) . ') AND "user" = ?',
Clare Lenihan's avatar
Clare Lenihan committed
132
133
134
135
                array($USER->get('id')
            ));
            $SESSION->add_ok_msg(get_string('topicunsubscribesuccess', 'interaction.forum'));
        }
Clare Lenihan's avatar
Clare Lenihan committed
136
    }
137
    else { // $checked contains bad values
138
        $SESSION->add_error_msg(get_string('topicupdatefailed', 'interaction.forum'));
Clare Lenihan's avatar
Clare Lenihan committed
139
    }
Clare Lenihan's avatar
Clare Lenihan committed
140
    redirect('/interaction/forum/view.php?id=' . $forumid . '&offset=' . $offset);
141
142
}

143
144
145
146
147
148
149
150
151
152
if ($membership) {
    $forum->subscribe = pieform(array(
        'name' => 'subscribe_forum',
        'renderer' => 'div',
        'plugintype' => 'interaction',
        'pluginname' => 'forum',
        'autofocus' => false,
        'elements' => array(
            'submit' => array(
                'type' => 'submit',
153
                'class' => 'btn-subscribe',
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
                'value' => $forum->subscribed ? get_string('unsubscribefromforum', 'interaction.forum') : get_string('subscribetoforum', 'interaction.forum'),
                'help' => true
            ),
            'forum' => array(
                'type' => 'hidden',
                'value' => $forumid
            ),
            'redirect' => array(
                'type' => 'hidden',
                'value' => 'view'
            ),
            'offset' => array(
                'type' => 'hidden',
                'value' => $offset
            ),
            'type' => array(
                'type' => 'hidden',
                'value' => $forum->subscribed ? 'unsubscribe' : 'subscribe'
            )
173
        )
174
175
    ));
}
176

177
178
179
// gets the info about topics
// the last post is found by taking the max id of the posts in a topic with the max post time
// taking the max id is needed because multiple posts can have the same post time
180
$sql = 'SELECT t.id, p1.subject, p1.body, p1.poster, p1.deleted, m.user AS moderator, COUNT(p2.id) AS postcount, t.closed, s.topic AS subscribed, p4.id AS lastpost, ' . db_format_tsfield('p4.ctime', 'lastposttime') . ', p4.poster AS lastposter, m2.user AS lastpostermoderator
181
    FROM {interaction_forum_topic} t
Clare Lenihan's avatar
Clare Lenihan committed
182
    INNER JOIN {interaction_forum_post} p1 ON (p1.topic = t.id AND p1.parent IS NULL)
183
184
185
186
187
    LEFT JOIN (
        SELECT m.forum, m.user
        FROM {interaction_forum_moderator} m
        INNER JOIN {usr} u ON (m.user = u.id AND u.deleted = 0)
    ) m ON (m.forum = t.forum AND p1.poster = m.user)
188
    INNER JOIN {interaction_forum_post} p2 ON (p2.topic = t.id AND p2.deleted != 1)
Clare Lenihan's avatar
Clare Lenihan committed
189
    LEFT JOIN {interaction_forum_subscription_topic} s ON (s.topic = t.id AND s."user" = ?)
190
    INNER JOIN (
191
        SELECT MAX(p2.id) AS post, t.id AS topic
Clare Lenihan's avatar
Clare Lenihan committed
192
        FROM {interaction_forum_topic} t
193
194
195
        INNER JOIN (
            SELECT MAX(p.ctime) AS ctime, t.id AS topic
            FROM {interaction_forum_topic} t
196
            INNER JOIN {interaction_forum_post} p ON (p.topic = t.id AND p.deleted = 0)
197
198
            GROUP BY 2
        ) p1 ON t.id = p1.topic
199
        INNER JOIN {interaction_forum_post} p2 ON (p1.topic = p2.topic AND p1.ctime = p2.ctime AND p2.deleted = 0)
Clare Lenihan's avatar
Clare Lenihan committed
200
201
        GROUP BY 2
    ) p3 ON p3.topic = t.id
202
    LEFT JOIN {interaction_forum_post} p4 ON (p4.id = p3.post)
203
    LEFT JOIN {interaction_forum_topic} t2 ON (p4.topic = t2.id)
204
205
206
207
208
    LEFT JOIN (
        SELECT m.forum, m.user
        FROM {interaction_forum_moderator} m
        INNER JOIN {usr} u ON (m.user = u.id AND u.deleted = 0)
    ) m2 ON (p4.poster = m2.user AND t2.forum = m2.forum)
Clare Lenihan's avatar
Clare Lenihan committed
209
    WHERE t.forum = ?
Clare Lenihan's avatar
Clare Lenihan committed
210
    AND t.sticky = ?
Clare Lenihan's avatar
Clare Lenihan committed
211
    AND t.deleted != 1
Clare Lenihan's avatar
Clare Lenihan committed
212
    GROUP BY 1, 2, 3, 4, 5, 6, 8, 9, 10, p4.ctime, p4.poster, p4.id, m2.user
213
    ORDER BY p4.ctime DESC, p4.id DESC';
Clare Lenihan's avatar
Clare Lenihan committed
214

Clare Lenihan's avatar
Clare Lenihan committed
215
216
217
218
$stickytopics = get_records_sql_array($sql, array($userid, $forumid, 1));

$regulartopics = get_records_sql_array($sql, array($userid, $forumid, 0), $offset, $topicsperpage);

Clare Lenihan's avatar
Clare Lenihan committed
219
220
setup_topics($stickytopics);
setup_topics($regulartopics);
Clare Lenihan's avatar
Clare Lenihan committed
221
222

$pagination = build_pagination(array(
Clare Lenihan's avatar
Clare Lenihan committed
223
    'url' => get_config('wwwroot') . 'interaction/forum/view.php?id=' . $forumid,
224
    'count' => $forum->topiccount,
Clare Lenihan's avatar
Clare Lenihan committed
225
226
    'limit' => $topicsperpage,
    'offset' => $offset,
Eugene Venter's avatar
Eugene Venter committed
227
228
    'jumplinks' => 6,
    'numbersincludeprevnext' => 2,
Clare Lenihan's avatar
Clare Lenihan committed
229
230
    'resultcounttextsingular' => get_string('topiclower', 'interaction.forum'),
    'resultcounttextplural' => get_string('topicslower', 'interaction.forum')
Clare Lenihan's avatar
Clare Lenihan committed
231
232
));

233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
$inlinejavascript = <<<EOF
addLoadEvent(function() {
    forEach(getElementsByTagAndClassName('input', 'topic-checkbox'), function(checkbox) {
        var tr = getFirstParentByTagAndClassName(checkbox, 'tr', null);
        var origColour = tr.style.backgroundColor;
        connect(checkbox, 'onclick', function(e) {
            if (tr.style.backgroundColor == origColour) {
                tr.style.backgroundColor = '#ffc';
            }
            else {
                tr.style.backgroundColor = origColour;
            }
        });
    });
});
EOF;

Evan Goldenberg's avatar
Evan Goldenberg committed
250
251
252
253
254
255
$headers = array();
if ($publicgroup) {
    $headers[] = '<link rel="alternate" type="application/atom+xml" href="' . $feedlink . '" />';
}

$smarty = smarty(array(), $headers, array(), array());
256
257
$smarty->assign('heading', $forum->groupname);
$smarty->assign('subheading', $forum->title);
Clare Lenihan's avatar
Clare Lenihan committed
258
$smarty->assign('forum', $forum);
Evan Goldenberg's avatar
Evan Goldenberg committed
259
260
$smarty->assign('publicgroup', $publicgroup);
$smarty->assign('feedlink', $feedlink);
261
$smarty->assign('membership', $membership);
Clare Lenihan's avatar
Clare Lenihan committed
262
263
$smarty->assign('moderator', $moderator);
$smarty->assign('admin', $admin);
264
$smarty->assign('groupadmins', group_get_admin_ids($forum->groupid));
Clare Lenihan's avatar
Clare Lenihan committed
265
266
$smarty->assign('stickytopics', $stickytopics);
$smarty->assign('regulartopics', $regulartopics);
267
$smarty->assign('moderators', $moderators);
268
269
$smarty->assign('closedicon', $THEME->get_url('images/closed.gif', false, 'interaction/forum'));
$smarty->assign('subscribedicon', $THEME->get_url('images/subscribed.gif', false, 'interaction/forum'));
Clare Lenihan's avatar
Clare Lenihan committed
270
$smarty->assign('pagination', $pagination['html']);
271
$smarty->assign('INLINEJAVASCRIPT', $inlinejavascript);
Clare Lenihan's avatar
Clare Lenihan committed
272
$smarty->display('interaction:forum:view.tpl');
Clare Lenihan's avatar
Clare Lenihan committed
273
274
275
276
277
278
279

/**
 * format body
 * format lastposttime
 */
function setup_topics(&$topics) {
    if ($topics) {
280
        foreach ($topics as $topic) {
281
            $topic->lastposttime = relative_date(get_string('strftimerecentrelative', 'interaction.forum'), get_string('strftimerecent'), $topic->lastposttime);
Evan Goldenberg's avatar
Evan Goldenberg committed
282
            $topic->feedlink = get_config('wwwroot') . 'interaction/forum/atom.php?type=t&id=' . $topic->id;
Clare Lenihan's avatar
Clare Lenihan committed
283
284
285
        }
    }
}