view.php 16.7 KB
Newer Older
1
2
3
4
5
<?php
/**
 *
 * @package    mahara
 * @subpackage core
6
 * @author     Catalyst IT Ltd
7
8
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
 * @copyright  For copyright information on Mahara, please see the README file distributed with this software.
9
10
11
12
 *
 */

define('INTERNAL', 1);
13
define('PUBLIC', 1);
14
15
16
17
define('SECTION_PLUGINTYPE', 'core');
define('SECTION_PLUGINNAME', 'view');
define('SECTION_PAGE', 'view');

18
require(dirname(dirname(__FILE__)) . '/init.php');
19

20
require_once(get_config('libroot') . 'view.php');
21
require_once(get_config('libroot') . 'collection.php');
22
require_once(get_config('libroot') . 'objectionable.php');
23
require_once('institution.php');
24
require_once('group.php');
25
safe_require('artefact', 'comment');
26
safe_require('artefact', 'file');
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
// access key for roaming teachers
$mnettoken = $SESSION->get('mnetuser') ? param_alphanum('mt', null) : null;

// access key for logged out users
$usertoken = (is_null($mnettoken) && get_config('allowpublicviews')) ? param_alphanum('t', null) : null;

if ($mnettoken) {
    if (!$viewid = get_view_from_token($mnettoken, false)) {
        throw new AccessDeniedException(get_string('accessdenied', 'error'));
    }
}
else if ($usertoken) {
    if (!$viewid = get_view_from_token($usertoken, true)) {
        throw new AccessDeniedException(get_string('accessdenied', 'error'));
Richard Mansfield's avatar
Richard Mansfield committed
42
43
    }
}
44
45
46
47
48
49
50
51
52
53
54
55
else if ($pageurl = param_alphanumext('page', null)) {
    if ($profile = param_alphanumext('profile', null)) {
        $view = new View(array('urlid' => $pageurl, 'ownerurlid' => $profile));
    }
    else if ($homepage = param_alphanumext('homepage', null)) {
        $view = new View(array('urlid' => $pageurl, 'groupurlid' => $homepage));
    }
    else {
        throw new ViewNotFoundException(get_string('viewnotfoundexceptiontitle', 'error'));
    }
    $viewid = $view->get('id');
}
Richard Mansfield's avatar
Richard Mansfield committed
56
57
58
else {
    $viewid = param_integer('id');
}
59

60
$new = param_boolean('new');
61
62
63
64
$showmore = param_boolean('showmore');
if (!$showmore) {
    $showmore = 0;
}
65

66
67
68
69
70
if (!isset($view)) {
    $view = new View($viewid);
}

if (!can_view_view($view)) {
71
    throw new AccessDeniedException(get_string('accessdenied', 'error'));
72
}
73
74
75
76
77
78
79
80
81
else {
    // To save the atime in the db - make it a millisecond in the past
    // so it differs from the atime in the View constructor and so triggers
    // the saving of the atime change. Can't use $view->set('dirty', true)
    // as that will also get the view object to update the mtime which is not
    // what we want.
    $view->set('atime', (time()) - 1);
    $view->commit();
}
82
83

// Feedback list pagination requires limit/offset params
84
85
86
$limit       = param_integer('limit', 10);
$offset      = param_integer('offset', 0);
$showcomment = param_integer('showcomment', null);
87
88

// Create the "make feedback private form" now if it's been submitted
89
90
if (param_variable('make_public_submit', null)) {
    pieform(ArtefactTypeComment::make_public_form(param_integer('comment')));
91
}
92
else if (param_variable('delete_comment_submit_x', null)) {
Richard Mansfield's avatar
Richard Mansfield committed
93
    pieform(ArtefactTypeComment::delete_comment_form(param_integer('comment')));
94
95
}

96
97
$owner    = $view->get('owner');
$viewtype = $view->get('type');
98

99
100
if ($viewtype == 'profile' || $viewtype == 'dashboard' || $viewtype == 'grouphomepage') {
    redirect($view->get_url());
101
}
102

103
104
define('TITLE', $view->get('title'));

105
$collection = $view->get('collection');
106
$submittedgroup = (int)$view->get('submittedgroup');
107
if ($USER->is_logged_in() && $submittedgroup && group_user_can_assess_submitted_views($submittedgroup, $USER->get('id'))) {
108
    // The user is a tutor of the group that this view has
109
    // been submitted to, and is entitled to release the view
110
    $submittedgroup = get_record('group', 'id', $submittedgroup);
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
    // If the view is part of a submitted collection, the whole
    // collection must be released at once.
    $releasecollection = !empty($collection) && $collection->get('submittedgroup') == $submittedgroup->id;
    if ($releasecollection) {
        if ($ctime = $collection->get('submittedtime')) {
            $text = get_string(
                'collectionsubmittedtogroupon', 'view', group_homepage_url($submittedgroup), hsc($submittedgroup->name),
                format_date(strtotime($ctime))
            );
        }
        else {
            $text = get_string('collectionsubmittedtogroup', 'view', group_homepage_url($submittedgroup), hsc($submittedgroup->name));
        }
    }
    else if ($view->get('submittedtime')) {
126
        $text = get_string('viewsubmittedtogroupon', 'view', group_homepage_url($submittedgroup), hsc($submittedgroup->name), format_date(strtotime($view->get('submittedtime'))));
127
128
    }
    else {
129
        $text = get_string('viewsubmittedtogroup', 'view', group_homepage_url($submittedgroup), hsc($submittedgroup->name));
130
    }
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
    if (($releasecollection && $collection->get('submittedstatus') == Collection::SUBMITTED) || $view->get('submittedstatus') == View::SUBMITTED) {
        $releaseform = pieform(array(
            'name'     => 'releaseview',
            'method'   => 'post',
            'plugintype' => 'core',
            'pluginname' => 'view',
            'autofocus' => false,
            'elements' => array(
                'submittedview' => array(
                    'type'  => 'html',
                    'value' => $text,
                ),
                'submit' => array(
                    'type'  => 'submit',
                    'value' => $releasecollection ? get_string('releasecollection', 'group') : get_string('releaseview', 'group'),
                ),
147
            ),
148
149
150
151
152
        ));
    }
    else {
        $releaseform = $text . ' ' . get_string('submittedpendingrelease', 'view');
    }
153
}
154
155
156
157
158
else {
    $releaseform = '';
}

function releaseview_submit() {
159
    global $USER, $SESSION, $view, $collection, $submittedgroup, $releasecollection;
160

161
    if ($releasecollection) {
162
163
164
165
166
167
168
169
        if (is_object($submittedgroup) && $submittedgroup->allowarchives) {
            $collection->pendingrelease($USER);
            $SESSION->add_ok_msg(get_string('collectionreleasedpending', 'group'));
        }
        else {
            $collection->release($USER);
            $SESSION->add_ok_msg(get_string('collectionreleasedsuccess', 'group'));
        }
170
171
    }
    else {
172
173
174
175
176
177
178
179
        if (is_object($submittedgroup) && $submittedgroup->allowarchives) {
            $view->pendingrelease($USER);
            $SESSION->add_ok_msg(get_string('viewreleasedpending', 'group'));
        }
        else {
            $view->release($USER);
            $SESSION->add_ok_msg(get_string('viewreleasedsuccess', 'group'));
        }
180
    }
181
    if ($submittedgroup) {
182
183
        // The tutor might not have access to the view any more; send
        // them back to the group page.
184
        redirect(group_homepage_url($submittedgroup));
185
    }
186
    redirect($view->get_url());
187
}
188

189
$javascript = array('paginator', 'viewmenu', 'expandable', 'author', 'js/jquery/jquery-ui/js/jquery-ui-1.10.2.min.js');
190
191
192
$blocktype_js = $view->get_all_blocktype_javascript();
$javascript = array_merge($javascript, $blocktype_js['jsfiles']);
$inlinejs = "addLoadEvent( function() {\n" . join("\n", $blocktype_js['initjs']) . "\n});";
193
194

$extrastylesheets = array('style/views.css');
195

196
197
// If the view has comments turned off, tutors can still leave
// comments if the view is submitted to their group.
198
if (!empty($releaseform) || ($commenttype = $view->user_comments_allowed($USER))) {
199
    $defaultprivate = !empty($releaseform);
200
201
    $moderate = isset($commenttype) && $commenttype === 'private';
    $addfeedbackform = pieform(ArtefactTypeComment::add_comment_form($defaultprivate, $moderate));
202
203
    $extrastylesheets[] = 'style/jquery.rating.css';
    $javascript[] = 'jquery.rating';
204
205
206
}
if ($USER->is_logged_in()) {
    $objectionform = pieform(objection_form());
207
    if ($notrudeform = notrude_form()) {
208
209
        $notrudeform = pieform($notrudeform);
    }
210
211
}

212
$viewbeingwatched = (int)record_exists('usr_watchlist_view', 'usr', $USER->get('id'), 'view', $viewid);
213
214
215
216
217
218
$commentoptions = ArtefactTypeComment::get_comment_options();
$commentoptions->limit = $limit;
$commentoptions->offset = $offset;
$commentoptions->showcomment = $showcomment;
$commentoptions->view = $view;
$feedback = ArtefactTypeComment::get_comments($commentoptions);
219

220
// Set up theme
221
222
223
$viewtheme = $view->get('theme');
if ($viewtheme && $THEME->basename != $viewtheme) {
    $THEME = new Theme($viewtheme);
224
}
225
$headers = array('<link rel="stylesheet" type="text/css" href="' . append_version_number(get_config('wwwroot') . 'theme/views.css') . '">');
226
$headers[] = '<link rel="stylesheet" type="text/css" href="' . append_version_number(get_config('wwwroot') . 'js/jquery/jquery-ui/css/ui-lightness/jquery-ui-1.10.2.min.css') . '">';
227
$headers = array_merge($headers, $view->get_all_blocktype_css());
228
229
// Set up skin, if the page has one
$viewskin = $view->get('skin');
230
231
$issiteview = $view->get('institution') == 'mahara';
if ($viewskin && get_config('skins') && can_use_skins($owner, false, $issiteview) && (!isset($THEME->skins) || $THEME->skins !== false)) {
232
    $skin = array('skinid' => $viewskin, 'viewid' => $view->get('id'));
233
    $skindata = unserialize(get_field('skin', 'viewskin', 'id', $viewskin));
234
235
236
237
238
}
else {
    $skin = false;
}

239
240
241
if (!$view->is_public()) {
    $headers[] = '<meta name="robots" content="noindex">';  // Tell search engines not to index non-public views
}
242

243
244
245
246
// include slimbox2 js and css files, if it is enabled...
if (get_config_plugin('blocktype', 'gallery', 'useslimbox2')) {
    $langdir = (get_string('thisdirection', 'langconfig') == 'rtl' ? '-rtl' : '');
    $headers = array_merge($headers, array(
247
        '<script type="application/javascript" src="' . append_version_number(get_config('wwwroot') . 'lib/slimbox2/js/slimbox2.js') . '"></script>',
248
        '<link rel="stylesheet" type="text/css" href="' . append_version_number(get_config('wwwroot') . 'lib/slimbox2/css/slimbox2' . $langdir . '.css') . '">'
249
250
251
    ));
}

252
$can_edit = $USER->can_edit_view($view) && !$submittedgroup && !$view->is_submitted();
253
$can_copy = $view->is_copyable($view);
254

255
256
257
258
259
260
261
262
263
$viewgroupform = false;
if ($owner && $owner == $USER->get('id')) {
    if ($tutorgroupdata = group_get_user_course_groups()) {
        if (!$view->is_submitted()) {
            $viewgroupform = view_group_submission_form($view, $tutorgroupdata, 'view');
        }
    }
}

264
265
$viewcontent = $view->build_rows(); // Build content before initialising smarty in case pieform elements define headers.

266
$smarty = smarty(
267
    $javascript,
268
    $headers,
269
270
271
272
    array('confirmcopytitle' => 'view',
          'confirmcopydesc' => 'view',
          'View' => 'view',
          'Collection' => 'collection'),
273
    array(
274
        'stylesheets' => $extrastylesheets,
275
        'sidebars' => false,
276
        'skin' => $skin
277
    )
278
);
279

280
281
$javascript = <<<EOF
var viewid = {$viewid};
282
var showmore = {$showmore};
283
284
285
addLoadEvent(function () {
    paginator = {$feedback->pagination_js}
});
286
287
288
289
290
291
292
293
294
295

\$j(function() {
    \$j('#column-container .blockinstance-content .commentlink').each(function() {
        var blockid = \$j(this).attr('id').match(/\d+/);
        // only use comments expander if there are comments on the artefact
        \$j(this).on('click', function(e) {
            var commentlink = \$j(this);
            var chtml = commentlink.parent().parent().find('#feedbacktable_' + blockid).parent();
            // add a 'close' link at the bottom of the list for convenience
            if (\$j('#closer_' + blockid).length == 0) {
296
                var closer = \$j('<a id="closer_' + blockid + '" href="#" class="close-link">Close</a>').click(function(e) {
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
                    \$j(this).parent().toggle(400, function() {
                        commentlink.focus();
                    });
                    e.preventDefault();
                });
                chtml.append(closer);
            }
            chtml.toggle(400, function() {
                if (chtml.is(':visible')) {
                    chtml.find('a').first().focus();
                }
                else {
                    commentlink.focus();
                }
            });
            e.preventDefault();
        });
    });
});

317
318
EOF;

319
// collection top navigation
320
if ($collection) {
321
322
    $shownav = $collection->get('navigation');
    if ($shownav) {
323
324
        if ($views = $collection->get('views')) {
            if (count($views['views']) > 1) {
325
                $smarty->assign_by_ref('collection', array_chunk($views['views'], 5));
326
327
            }
        }
328
    }
329
330
}

331
$smarty->assign('INLINEJAVASCRIPT', $javascript . $inlinejs);
332
$smarty->assign('new', $new);
333
$smarty->assign('viewid', $viewid);
334
$smarty->assign('viewtype', $viewtype);
335
$smarty->assign('feedback', $feedback);
Richard Mansfield's avatar
Richard Mansfield committed
336
337
$smarty->assign('owner', $owner);
$smarty->assign('tags', $view->get('tags'));
338

339
340
341
342
343
344
345
346
347
348
349
350
351
if ($view->is_anonymous()) {
  $smarty->assign('PAGEAUTHOR', get_string('anonymoususer'));
  $smarty->assign('author', get_string('anonymoususer'));
  if ($view->is_staff_or_admin_for_page()) {
    $smarty->assign('realauthor', $view->display_author());
  }
  $smarty->assign('anonymous', TRUE);
} else {
  $smarty->assign('PAGEAUTHOR', $view->formatted_owner());
  $smarty->assign('author', $view->display_author());
  $smarty->assign('anonymous', FALSE);
}

352

353
$titletext = ($collection && $shownav) ? hsc($collection->get('name')) : $view->display_title(true, false, false);
354
$smarty->assign('visitstring', $view->visit_message());
355
if (get_config('viewmicroheaders')) {
356
    $microheaderlinks = array();
357
    $smarty->assign('microheaders', true);
358
359

    $smarty->assign('microheadertitle', $titletext);
360

361
    $smarty->assign('maharalogofilename', 'site-logo-small');
362
    // Support for normal, light, or dark small Mahara logo - to use with skins
363
    if ($skin) {
364
        if ($skindata['header_logo_image'] == 'light') {
365
            $smarty->assign('maharalogofilename', 'site-logo-small-light');
366
367
        }
        else if ($skindata['header_logo_image'] == 'dark') {
368
            $smarty->assign('maharalogofilename', 'site-logo-small-dark');
369
370
371
        }
    }

372
    if ($can_edit) {
373
        if ($new) {
374
375
376
377
            $microheaderlinks[] = array(
                'name' => get_string('back'),
                'url' => get_config('wwwroot') . 'view/blocks.php?id=' . $viewid . '&new=1',
                'type' => 'reply',
378
379
380
            );
        }
        else {
381
382
            $microheaderlinks[] = array(
                'name' => get_string('edit', 'mahara'),
383
                'image' => $THEME->get_image_url('btn_edit'),
384
                'url' => get_config('wwwroot') . 'view/blocks.php?id=' . $viewid,
385
386
            );
        }
387
    }
388
389
390
    if ($can_copy) {
        $microheaderlinks[] = array(
            'name' => get_string('copy', 'mahara'),
391
            'image' => $THEME->get_image_url('btn_edit'),
392
393
            'url' => get_config('wwwroot') . 'view/copy.php?id=' . $viewid . (!empty($collection) ? '&collection=' . $collection->get('id') : ''),
            'class' => 'copyview',
394
395
396
        );
    }
    $smarty->assign('microheaderlinks', $microheaderlinks);
397
}
398
399
400
401
402
else {
    if ($can_edit) {
        $smarty->assign('editurl', get_config('wwwroot') . 'view/blocks.php?id=' . $viewid . ($new ? '&new=1' : ''));
    }
    if ($can_copy) {
403
        $smarty->assign('copyurl', get_config('wwwroot') . 'view/copy.php?id=' . $viewid . (!empty($collection) ? '&collection=' . $collection->get('id') : ''));
404
    }
405
}
406

407
408
$title = hsc(TITLE);

409
if (!get_config('viewmicroheaders')) {
410
    $smarty->assign('maintitle', $titletext);
411
    if ($skin) {
412
413
414
415
416
417
        if ($skindata['header_logo_image'] == 'light' || $skindata['header_logo_image'] == 'dark') {
            // override the default $smarty->assign('sitelogo') that happens
            // in the initial call to smarty()
            $smarty->assign('sitelogo', $THEME->header_logo($skindata['header_logo_image']));
        }
    }
418
419
}

420
421
422
423
424
425
426
// Provide a link for roaming teachers to return
if ($mnetviewlist = $SESSION->get('mnetviewaccess')) {
    if (isset($mnetviewlist[$view->get('id')])) {
        $returnurl = $SESSION->get('mnetuserfrom');
        require_once(get_config('docroot') . 'api/xmlrpc/lib.php');
        if ($peer = get_peer_from_instanceid($SESSION->get('authinstance'))) {
            $smarty->assign('mnethost', array(
427
                'name'      => $peer->name,
428
429
430
431
432
                'url'       => $returnurl ? $returnurl : $peer->wwwroot,
            ));
        }
    }
}
433

434
$smarty->assign('viewdescription', ArtefactTypeFolder::append_view_url($view->get('description'), $view->get('id')));
435
$smarty->assign('viewcontent', $viewcontent);
436
$smarty->assign('releaseform', $releaseform);
437
if (isset($addfeedbackform)) {
438
    $smarty->assign('enablecomments', 1);
439
    $smarty->assign('addfeedbackform', $addfeedbackform);
440
}
441
442
if (isset($objectionform)) {
    $smarty->assign('objectionform', $objectionform);
443
    $smarty->assign('notrudeform', $notrudeform);
444
}
445
$smarty->assign('viewbeingwatched', $viewbeingwatched);
446

447
448
if ($viewgroupform) {
    $smarty->assign('view_group_submission_form', $viewgroupform);
449
450
}

451
452
$smarty->display('view/view.tpl');

453
mahara_log('views', "$viewid"); // Log view visits