Commit | Line | Data |
---|---|---|
cae83708 | 1 | <?php |
2 | ||
3 | // This file is part of Moodle - http://moodle.org/ | |
4 | // | |
5 | // Moodle is free software: you can redistribute it and/or modify | |
6 | // it under the terms of the GNU General Public License as published by | |
7 | // the Free Software Foundation, either version 3 of the License, or | |
8 | // (at your option) any later version. | |
9 | // | |
10 | // Moodle is distributed in the hope that it will be useful, | |
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | // GNU General Public License for more details. | |
14 | // | |
15 | // You should have received a copy of the GNU General Public License | |
16 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
17 | ||
cae83708 | 18 | /** |
19 | * Core global functions for Blog. | |
20 | * | |
21 | * @package moodlecore | |
22 | * @subpackage blog | |
23 | * @copyright 2009 Nicolas Connault | |
24 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
25 | */ | |
26 | ||
35716b86 PS |
27 | defined('MOODLE_INTERNAL') || die(); |
28 | ||
cae83708 | 29 | /** |
30 | * Library of functions and constants for blog | |
31 | */ | |
32 | require_once($CFG->dirroot .'/blog/rsslib.php'); | |
33 | require_once($CFG->dirroot.'/tag/lib.php'); | |
34 | ||
cae83708 | 35 | /** |
36 | * User can edit a blog entry if this is their own blog entry and they have | |
37 | * the capability moodle/blog:create, or if they have the capability | |
38 | * moodle/blog:manageentries. | |
39 | * | |
40 | * This also applies to deleting of entries. | |
41 | */ | |
1c7b8b93 NC |
42 | function blog_user_can_edit_entry($blogentry) { |
43 | global $USER; | |
6524adcf | 44 | |
cae83708 | 45 | $sitecontext = get_context_instance(CONTEXT_SYSTEM); |
4a173181 | 46 | |
cae83708 | 47 | if (has_capability('moodle/blog:manageentries', $sitecontext)) { |
48 | return true; // can edit any blog entry | |
49 | } | |
c2ee4e87 | 50 | |
1c7b8b93 | 51 | if ($blogentry->userid == $USER->id && has_capability('moodle/blog:create', $sitecontext)) { |
cae83708 | 52 | return true; // can edit own when having blog:create capability |
53 | } | |
4a173181 | 54 | |
cae83708 | 55 | return false; |
56 | } | |
d02240f3 | 57 | |
3bfcfdca | 58 | |
cae83708 | 59 | /** |
60 | * Checks to see if a user can view the blogs of another user. | |
61 | * Only blog level is checked here, the capabilities are enforced | |
62 | * in blog/index.php | |
63 | */ | |
1c7b8b93 | 64 | function blog_user_can_view_user_entry($targetuserid, $blogentry=null) { |
cae83708 | 65 | global $CFG, $USER, $DB; |
c2ee4e87 | 66 | |
cae83708 | 67 | if (empty($CFG->bloglevel)) { |
68 | return false; // blog system disabled | |
69 | } | |
70 | ||
2c27b6ae | 71 | if (isloggedin() && $USER->id == $targetuserid) { |
cae83708 | 72 | return true; // can view own entries in any case |
73 | } | |
74 | ||
75 | $sitecontext = get_context_instance(CONTEXT_SYSTEM); | |
76 | if (has_capability('moodle/blog:manageentries', $sitecontext)) { | |
77 | return true; // can manage all entries | |
78 | } | |
c2ee4e87 | 79 | |
cae83708 | 80 | // coming for 1 entry, make sure it's not a draft |
1c7b8b93 | 81 | if ($blogentry && $blogentry->publishstate == 'draft' && !has_capability('moodle/blog:viewdrafts', $sitecontext)) { |
cae83708 | 82 | return false; // can not view draft of others |
83 | } | |
84 | ||
85 | // coming for 1 entry, make sure user is logged in, if not a public blog | |
1c7b8b93 | 86 | if ($blogentry && $blogentry->publishstate != 'public' && !isloggedin()) { |
cae83708 | 87 | return false; |
88 | } | |
d02240f3 | 89 | |
cae83708 | 90 | switch ($CFG->bloglevel) { |
91 | case BLOG_GLOBAL_LEVEL: | |
92 | return true; | |
93 | break; | |
c2ee4e87 | 94 | |
cae83708 | 95 | case BLOG_SITE_LEVEL: |
4f0c2d00 | 96 | if (isloggedin()) { // not logged in viewers forbidden |
cae83708 | 97 | return true; |
c2ee4e87 | 98 | } |
cae83708 | 99 | return false; |
100 | break; | |
d02240f3 | 101 | |
cae83708 | 102 | case BLOG_USER_LEVEL: |
103 | default: | |
104 | $personalcontext = get_context_instance(CONTEXT_USER, $targetuserid); | |
105 | return has_capability('moodle/user:readuserblogs', $personalcontext); | |
106 | break; | |
4a173181 | 107 | |
cae83708 | 108 | } |
109 | } | |
110 | ||
111 | /** | |
112 | * remove all associations for the blog entries of a particular user | |
113 | * @param int userid - id of user whose blog associations will be deleted | |
114 | */ | |
115 | function blog_remove_associations_for_user($userid) { | |
1c7b8b93 | 116 | global $DB; |
d91181dc PS |
117 | throw new coding_exception('function blog_remove_associations_for_user() is not finished'); |
118 | /* | |
1c7b8b93 NC |
119 | $blogentries = blog_fetch_entries(array('user' => $userid), 'lasmodified DESC'); |
120 | foreach ($blogentries as $entry) { | |
121 | if (blog_user_can_edit_entry($entry)) { | |
122 | blog_remove_associations_for_entry($entry->id); | |
123 | } | |
b0e90a0c | 124 | } |
d91181dc | 125 | */ |
cae83708 | 126 | } |
127 | ||
128 | /** | |
1c7b8b93 NC |
129 | * remove all associations for the blog entries of a particular course |
130 | * @param int courseid - id of user whose blog associations will be deleted | |
cae83708 | 131 | */ |
1c7b8b93 NC |
132 | function blog_remove_associations_for_course($courseid) { |
133 | global $DB; | |
134 | $context = get_context_instance(CONTEXT_COURSE, $courseid); | |
135 | $DB->delete_records('blog_association', array('contextid' => $context->id)); | |
cae83708 | 136 | } |
137 | ||
cae83708 | 138 | /** |
139 | * Given a record in the {blog_external} table, checks the blog's URL | |
140 | * for new entries not yet copied into Moodle. | |
141 | * | |
1c7b8b93 NC |
142 | * @param object $externalblog |
143 | * @return boolean False if the Feed is invalid | |
cae83708 | 144 | */ |
1c7b8b93 | 145 | function blog_sync_external_entries($externalblog) { |
cae83708 | 146 | global $CFG, $DB; |
e14de6f9 | 147 | require_once($CFG->libdir . '/simplepie/moodle_simplepie.php'); |
4a173181 | 148 | |
1c7b8b93 NC |
149 | $rssfile = new moodle_simplepie_file($externalblog->url); |
150 | $filetest = new SimplePie_Locator($rssfile); | |
151 | ||
152 | if (!$filetest->is_feed($rssfile)) { | |
153 | $externalblog->failedlastsync = 1; | |
154 | $DB->update_record('blog_external', $externalblog); | |
155 | return false; | |
8397492b | 156 | } else if (!empty($externalblog->failedlastsync)) { |
1c7b8b93 NC |
157 | $externalblog->failedlastsync = 0; |
158 | $DB->update_record('blog_external', $externalblog); | |
c2ee4e87 | 159 | } |
4a173181 | 160 | |
1c7b8b93 NC |
161 | // Delete all blog entries associated with this external blog |
162 | blog_delete_external_entries($externalblog); | |
163 | ||
164 | $rss = new moodle_simplepie($externalblog->url); | |
c2ee4e87 | 165 | |
e14de6f9 | 166 | if (empty($rss->data)) { |
cae83708 | 167 | return null; |
168 | } | |
b13ee30e | 169 | |
e14de6f9 | 170 | foreach ($rss->get_items() as $entry) { |
1c7b8b93 NC |
171 | // If filtertags are defined, use them to filter the entries by RSS category |
172 | if (!empty($externalblog->filtertags)) { | |
173 | $containsfiltertag = false; | |
174 | $categories = $entry->get_categories(); | |
175 | $filtertags = explode(',', $externalblog->filtertags); | |
176 | $filtertags = array_map('trim', $filtertags); | |
177 | $filtertags = array_map('strtolower', $filtertags); | |
178 | ||
179 | foreach ($categories as $category) { | |
180 | if (in_array(trim(strtolower($category->term)), $filtertags)) { | |
181 | $containsfiltertag = true; | |
182 | } | |
183 | } | |
184 | ||
185 | if (!$containsfiltertag) { | |
186 | continue; | |
c2ee4e87 | 187 | } |
188 | } | |
1c7b8b93 | 189 | |
e463f508 | 190 | $newentry = new stdClass(); |
1c7b8b93 NC |
191 | $newentry->userid = $externalblog->userid; |
192 | $newentry->module = 'blog_external'; | |
193 | $newentry->content = $externalblog->id; | |
194 | $newentry->uniquehash = $entry->get_permalink(); | |
195 | $newentry->publishstate = 'site'; | |
196 | $newentry->format = FORMAT_HTML; | |
197 | $newentry->subject = $entry->get_title(); | |
198 | $newentry->summary = $entry->get_description(); | |
99cd408f AD |
199 | |
200 | //our DB doesnt allow null creation or modified timestamps so check the external blog didnt supply one | |
201 | $entrydate = $entry->get_date('U'); | |
202 | if (empty($entrydate)) { | |
203 | $newentry->created = time(); | |
204 | $newentry->lastmodified = time(); | |
205 | } else { | |
206 | $newentry->created = $entrydate; | |
207 | $newentry->lastmodified = $entrydate; | |
208 | } | |
1c7b8b93 | 209 | |
3b59524d | 210 | $textlib = textlib_get_instance(); |
ca824b38 | 211 | if ($textlib->strlen($newentry->uniquehash) > 255) { |
3b59524d SH |
212 | // The URL for this item is too long for the field. Rather than add |
213 | // the entry without the link we will skip straight over it. | |
214 | // RSS spec says recommended length 500, we use 255. | |
215 | debugging('External blog entry skipped because of oversized URL', DEBUG_DEVELOPER); | |
216 | continue; | |
217 | } | |
218 | ||
1c7b8b93 NC |
219 | $id = $DB->insert_record('post', $newentry); |
220 | ||
221 | // Set tags | |
222 | if ($tags = tag_get_tags_array('blog_external', $externalblog->id)) { | |
223 | tag_set('post', $id, $tags); | |
224 | } | |
cae83708 | 225 | } |
c2ee4e87 | 226 | |
1c7b8b93 NC |
227 | $DB->update_record('blog_external', array('id' => $externalblog->id, 'timefetched' => mktime())); |
228 | } | |
229 | ||
230 | /** | |
231 | * Given an external blog object, deletes all related blog entries from the post table. | |
232 | * NOTE: The external blog's id is saved as post.content, a field that is not oterhwise used by blog entries. | |
233 | * @param object $externablog | |
234 | */ | |
235 | function blog_delete_external_entries($externalblog) { | |
236 | global $DB; | |
237 | require_capability('moodle/blog:manageexternal', get_context_instance(CONTEXT_SYSTEM)); | |
a742eb1f EL |
238 | $DB->delete_records_select('post', |
239 | "module='blog_external' AND " . $DB->sql_compare_text('content') . " = ?", | |
240 | array($externalblog->id)); | |
cae83708 | 241 | } |
d02240f3 | 242 | |
cae83708 | 243 | /** |
244 | * Returns a URL based on the context of the current page. | |
245 | * This URL points to blog/index.php and includes filter parameters appropriate for the current page. | |
246 | * | |
247 | * @param stdclass $context | |
248 | * @return string | |
249 | */ | |
250 | function blog_get_context_url($context=null) { | |
251 | global $CFG; | |
c2ee4e87 | 252 | |
a6855934 | 253 | $viewblogentriesurl = new moodle_url('/blog/index.php'); |
c2ee4e87 | 254 | |
cae83708 | 255 | if (empty($context)) { |
256 | global $PAGE; | |
5515b536 | 257 | $context = $PAGE->context; |
cae83708 | 258 | } |
c2ee4e87 | 259 | |
cae83708 | 260 | // Change contextlevel to SYSTEM if viewing the site course |
261 | if ($context->contextlevel == CONTEXT_COURSE && $context->instanceid == SITEID) { | |
262 | $context->contextlevel = CONTEXT_SYSTEM; | |
263 | } | |
c2ee4e87 | 264 | |
cae83708 | 265 | $filterparam = ''; |
266 | $strlevel = ''; | |
c2ee4e87 | 267 | |
cae83708 | 268 | switch ($context->contextlevel) { |
269 | case CONTEXT_SYSTEM: | |
270 | case CONTEXT_BLOCK: | |
271 | case CONTEXT_COURSECAT: | |
c2ee4e87 | 272 | break; |
cae83708 | 273 | case CONTEXT_COURSE: |
274 | $filterparam = 'courseid'; | |
275 | $strlevel = get_string('course'); | |
c2ee4e87 | 276 | break; |
cae83708 | 277 | case CONTEXT_MODULE: |
278 | $filterparam = 'modid'; | |
279 | $strlevel = print_context_name($context); | |
c2ee4e87 | 280 | break; |
cae83708 | 281 | case CONTEXT_USER: |
282 | $filterparam = 'userid'; | |
283 | $strlevel = get_string('user'); | |
c2ee4e87 | 284 | break; |
516194d0 | 285 | } |
286 | ||
cae83708 | 287 | if (!empty($filterparam)) { |
b0e90a0c | 288 | $viewblogentriesurl->param($filterparam, $context->instanceid); |
cae83708 | 289 | } |
bbbf2d40 | 290 | |
b0e90a0c | 291 | return $viewblogentriesurl; |
cae83708 | 292 | } |
293 | ||
27bad0a6 | 294 | /** |
593270c6 | 295 | * This function checks that blogs are enabled, and that the user can see blogs at all |
27bad0a6 SH |
296 | * @return bool |
297 | */ | |
298 | function blog_is_enabled_for_user() { | |
299 | global $CFG; | |
593270c6 MD |
300 | //return (!empty($CFG->bloglevel) && $CFG->bloglevel <= BLOG_GLOBAL_LEVEL && isloggedin() && !isguestuser()); |
301 | return (!empty($CFG->bloglevel) && (isloggedin() || ($CFG->bloglevel == BLOG_GLOBAL_LEVEL))); | |
27bad0a6 SH |
302 | } |
303 | ||
304 | /** | |
305 | * This function gets all of the options available for the current user in respect | |
306 | * to blogs. | |
897aa80c | 307 | * |
27bad0a6 SH |
308 | * It loads the following if applicable: |
309 | * - Module options {@see blog_get_options_for_module} | |
310 | * - Course options {@see blog_get_options_for_course} | |
311 | * - User specific options {@see blog_get_options_for_user} | |
312 | * - General options (BLOG_LEVEL_GLOBAL) | |
313 | * | |
314 | * @param moodle_page $page The page to load for (normally $PAGE) | |
315 | * @param stdClass $userid Load for a specific user | |
316 | * @return array An array of options organised by type. | |
317 | */ | |
318 | function blog_get_all_options(moodle_page $page, stdClass $userid = null) { | |
319 | global $CFG, $DB, $USER; | |
320 | ||
321 | $options = array(); | |
322 | ||
323 | // If blogs are enabled and the user is logged in and not a guest | |
324 | if (blog_is_enabled_for_user()) { | |
325 | // If the context is the user then assume we want to load for the users context | |
326 | if (is_null($userid) && $page->context->contextlevel == CONTEXT_USER) { | |
327 | $userid = $page->context->instanceid; | |
328 | } | |
329 | // Check the userid var | |
330 | if (!is_null($userid) && $userid!==$USER->id) { | |
331 | // Load the user from the userid... it MUST EXIST throw a wobbly if it doesn't! | |
332 | $user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST); | |
333 | } else { | |
334 | $user = null; | |
335 | } | |
336 | ||
337 | if ($CFG->useblogassociations && $page->cm !== null) { | |
338 | // Load for the module associated with the page | |
339 | $options[CONTEXT_MODULE] = blog_get_options_for_module($page->cm, $user); | |
340 | } else if ($CFG->useblogassociations && $page->course->id != SITEID) { | |
341 | // Load the options for the course associated with the page | |
342 | $options[CONTEXT_COURSE] = blog_get_options_for_course($page->course, $user); | |
343 | } | |
344 | ||
345 | // Get the options for the user | |
346 | if ($user !== null) { | |
347 | // Load for the requested user | |
348 | $options[CONTEXT_USER+1] = blog_get_options_for_user($user); | |
349 | } | |
350 | // Load for the current user | |
351 | $options[CONTEXT_USER] = blog_get_options_for_user(); | |
352 | } | |
353 | ||
354 | // If blog level is global then display a link to view all site entries | |
355 | if (!empty($CFG->bloglevel) && $CFG->bloglevel >= BLOG_GLOBAL_LEVEL && has_capability('moodle/blog:view', get_context_instance(CONTEXT_SYSTEM))) { | |
356 | $options[CONTEXT_SYSTEM] = array('viewsite' => array( | |
357 | 'string' => get_string('viewsiteentries', 'blog'), | |
358 | 'link' => new moodle_url('/blog/index.php') | |
359 | )); | |
360 | } | |
361 | ||
362 | // Return the options | |
363 | return $options; | |
364 | } | |
365 | ||
366 | /** | |
367 | * Get all of the blog options that relate to the passed user. | |
368 | * | |
369 | * If no user is passed the current user is assumed. | |
370 | * | |
371 | * @staticvar array $useroptions Cache so we don't have to regenerate multiple times | |
372 | * @param stdClass $user | |
373 | * @return array The array of options for the requested user | |
374 | */ | |
375 | function blog_get_options_for_user(stdClass $user=null) { | |
376 | global $CFG, $USER; | |
377 | // Cache | |
378 | static $useroptions = array(); | |
379 | ||
380 | $options = array(); | |
381 | // Blogs must be enabled and the user must be logged in | |
382 | if (!blog_is_enabled_for_user()) { | |
383 | return $options; | |
384 | } | |
385 | ||
386 | // Sort out the user var | |
387 | if ($user === null || $user->id == $USER->id) { | |
388 | $user = $USER; | |
389 | $iscurrentuser = true; | |
390 | } else { | |
391 | $iscurrentuser = false; | |
392 | } | |
393 | ||
394 | // If we've already generated serve from the cache | |
395 | if (array_key_exists($user->id, $useroptions)) { | |
396 | return $useroptions[$user->id]; | |
397 | } | |
398 | ||
399 | $sitecontext = get_context_instance(CONTEXT_SYSTEM); | |
400 | $canview = has_capability('moodle/blog:view', $sitecontext); | |
401 | ||
402 | if (!$iscurrentuser && $canview && ($CFG->bloglevel >= BLOG_SITE_LEVEL)) { | |
403 | // Not the current user, but we can view and its blogs are enabled for SITE or GLOBAL | |
404 | $options['userentries'] = array( | |
405 | 'string' => get_string('viewuserentries', 'blog', fullname($user)), | |
406 | 'link' => new moodle_url('/blog/index.php', array('userid'=>$user->id)) | |
407 | ); | |
408 | } else { | |
409 | // It's the current user | |
410 | if ($canview) { | |
411 | // We can view our own blogs .... BIG surprise | |
412 | $options['view'] = array( | |
413 | 'string' => get_string('viewallmyentries', 'blog'), | |
414 | 'link' => new moodle_url('/blog/index.php', array('userid'=>$USER->id)) | |
415 | ); | |
416 | } | |
417 | if (has_capability('moodle/blog:create', $sitecontext)) { | |
418 | // We can add to our own blog | |
419 | $options['add'] = array( | |
420 | 'string' => get_string('addnewentry', 'blog'), | |
421 | 'link' => new moodle_url('/blog/edit.php', array('action'=>'add')) | |
422 | ); | |
423 | } | |
424 | } | |
425 | // Cache the options | |
426 | $useroptions[$user->id] = $options; | |
427 | // Return the options | |
428 | return $options; | |
429 | } | |
430 | ||
431 | /** | |
432 | * Get the blog options that relate to the given course for the given user. | |
433 | * | |
434 | * @staticvar array $courseoptions A cache so we can save regenerating multiple times | |
435 | * @param stdClass $course The course to load options for | |
436 | * @param stdClass $user The user to load options for null == current user | |
437 | * @return array The array of options | |
438 | */ | |
439 | function blog_get_options_for_course(stdClass $course, stdClass $user=null) { | |
440 | global $CFG, $USER; | |
441 | // Cache | |
442 | static $courseoptions = array(); | |
897aa80c | 443 | |
27bad0a6 SH |
444 | $options = array(); |
445 | ||
446 | // User must be logged in and blogs must be enabled | |
447 | if (!blog_is_enabled_for_user()) { | |
448 | return $options; | |
449 | } | |
450 | ||
451 | // Check that the user can associate with the course | |
452 | $sitecontext = get_context_instance(CONTEXT_SYSTEM); | |
453 | if (!has_capability('moodle/blog:associatecourse', $sitecontext)) { | |
454 | return $options; | |
455 | } | |
456 | // Generate the cache key | |
457 | $key = $course->id.':'; | |
458 | if (!empty($user)) { | |
459 | $key .= $user->id; | |
460 | } else { | |
461 | $key .= $USER->id; | |
462 | } | |
463 | // Serve from the cache if we've already generated for this course | |
464 | if (array_key_exists($key, $courseoptions)) { | |
af8fe217 | 465 | return $courseoptions[$key]; |
27bad0a6 | 466 | } |
897aa80c | 467 | |
27bad0a6 SH |
468 | if (has_capability('moodle/blog:view', get_context_instance(CONTEXT_COURSE, $course->id))) { |
469 | // We can view! | |
470 | if ($CFG->bloglevel >= BLOG_SITE_LEVEL) { | |
471 | // View entries about this course | |
472 | $options['courseview'] = array( | |
473 | 'string' => get_string('viewcourseblogs', 'blog'), | |
474 | 'link' => new moodle_url('/blog/index.php', array('courseid'=>$course->id)) | |
475 | ); | |
476 | } | |
477 | // View MY entries about this course | |
478 | $options['courseviewmine'] = array( | |
479 | 'string' => get_string('viewmyentriesaboutcourse', 'blog'), | |
480 | 'link' => new moodle_url('/blog/index.php', array('courseid'=>$course->id, 'userid'=>$USER->id)) | |
481 | ); | |
482 | if (!empty($user) && ($CFG->bloglevel >= BLOG_SITE_LEVEL)) { | |
483 | // View the provided users entries about this course | |
484 | $options['courseviewuser'] = array( | |
485 | 'string' => get_string('viewentriesbyuseraboutcourse', 'blog', fullname($user)), | |
486 | 'link' => new moodle_url('/blog/index.php', array('courseid'=>$course->id, 'userid'=>$user->id)) | |
487 | ); | |
488 | } | |
489 | } | |
490 | ||
491 | if (has_capability('moodle/blog:create', $sitecontext)) { | |
492 | // We can blog about this course | |
493 | $options['courseadd'] = array( | |
cfa11fd6 | 494 | 'string' => get_string('blogaboutthiscourse', 'blog'), |
27bad0a6 SH |
495 | 'link' => new moodle_url('/blog/edit.php', array('action'=>'add', 'courseid'=>$course->id)) |
496 | ); | |
497 | } | |
498 | ||
499 | ||
500 | // Cache the options for this course | |
501 | $courseoptions[$key] = $options; | |
502 | // Return the options | |
503 | return $options; | |
504 | } | |
505 | ||
506 | /** | |
507 | * Get the blog options relating to the given module for the given user | |
508 | * | |
509 | * @staticvar array $moduleoptions Cache | |
510 | * @param stdClass $module The module to get options for | |
511 | * @param stdClass $user The user to get options for null == currentuser | |
512 | * @return array | |
513 | */ | |
514 | function blog_get_options_for_module(stdClass $module, stdClass $user=null) { | |
515 | global $CFG, $USER; | |
516 | // Cache | |
517 | static $moduleoptions = array(); | |
518 | ||
519 | $options = array(); | |
520 | // User must be logged in, blogs must be enabled | |
521 | if (!blog_is_enabled_for_user()) { | |
522 | return $options; | |
523 | } | |
524 | ||
525 | // Check the user can associate with the module | |
526 | $sitecontext = get_context_instance(CONTEXT_SYSTEM); | |
527 | if (!has_capability('moodle/blog:associatemodule', $sitecontext)) { | |
528 | return $options; | |
529 | } | |
530 | ||
531 | // Generate the cache key | |
532 | $key = $module->id.':'; | |
533 | if (!empty($user)) { | |
534 | $key .= $user->id; | |
535 | } else { | |
536 | $key .= $USER->id; | |
537 | } | |
538 | if (array_key_exists($key, $moduleoptions)) { | |
539 | // Serve from the cache so we don't have to regenerate | |
540 | return $moduleoptions[$module->id]; | |
541 | } | |
542 | ||
543 | if (has_capability('moodle/blog:view', get_context_instance(CONTEXT_MODULE, $module->id))) { | |
544 | // We can view! | |
545 | if ($CFG->bloglevel >= BLOG_SITE_LEVEL) { | |
546 | // View all entries about this module | |
547 | $a = new stdClass; | |
548 | $a->type = $module->modname; | |
549 | $options['moduleview'] = array( | |
550 | 'string' => get_string('viewallmodentries', 'blog', $a), | |
551 | 'link' => new moodle_url('/blog/index.php', array('modid'=>$module->id)) | |
552 | ); | |
553 | } | |
554 | // View MY entries about this module | |
555 | $options['moduleviewmine'] = array( | |
556 | 'string' => get_string('viewmyentriesaboutmodule', 'blog', $module->modname), | |
557 | 'link' => new moodle_url('/blog/index.php', array('modid'=>$module->id, 'userid'=>$USER->id)) | |
558 | ); | |
559 | if (!empty($user) && ($CFG->bloglevel >= BLOG_SITE_LEVEL)) { | |
560 | // View the given users entries about this module | |
561 | $a = new stdClass; | |
562 | $a->mod = $module->modname; | |
563 | $a->user = fullname($user); | |
564 | $options['moduleviewuser'] = array( | |
565 | 'string' => get_string('blogentriesbyuseraboutmodule', 'blog', $a), | |
566 | 'link' => new moodle_url('/blog/index.php', array('modid'=>$module->id, 'userid'=>$user->id)) | |
567 | ); | |
568 | } | |
569 | } | |
570 | ||
571 | if (has_capability('moodle/blog:create', $sitecontext)) { | |
572 | // The user can blog about this module | |
573 | $options['moduleadd'] = array( | |
574 | 'string' => get_string('blogaboutthismodule', 'blog', $module->modname), | |
575 | 'link' => new moodle_url('/blog/edit.php', array('action'=>'add', 'modid'=>$module->id)) | |
576 | ); | |
577 | } | |
578 | // Cache the options | |
579 | $moduleoptions[$key] = $options; | |
580 | // Return the options | |
581 | return $options; | |
582 | } | |
583 | ||
cae83708 | 584 | /** |
585 | * This function encapsulates all the logic behind the complex | |
586 | * navigation, titles and headings of the blog listing page, depending | |
1c7b8b93 NC |
587 | * on URL params. It looks at URL params and at the current context level. |
588 | * It builds and returns an array containing: | |
589 | * | |
590 | * 1. heading: The heading displayed above the blog entries | |
591 | * 2. stradd: The text to be used as the "Add entry" link | |
592 | * 3. strview: The text to be used as the "View entries" link | |
593 | * 4. url: The moodle_url object used as the base for add and view links | |
594 | * 5. filters: An array of parameters used to filter blog listings. Used by index.php and the Recent blogs block | |
cae83708 | 595 | * |
c5dc10ee | 596 | * All other variables are set directly in $PAGE |
cae83708 | 597 | * |
598 | * It uses the current URL to build these variables. | |
599 | * A number of mutually exclusive use cases are used to structure this function. | |
600 | * | |
601 | * @return array | |
602 | */ | |
451f1e38 | 603 | function blog_get_headers($courseid=null, $groupid=null, $userid=null, $tagid=null) { |
cae83708 | 604 | global $CFG, $PAGE, $DB, $USER; |
605 | ||
9366362a | 606 | $id = optional_param('id', null, PARAM_INT); |
cae83708 | 607 | $tag = optional_param('tag', null, PARAM_NOTAGS); |
451f1e38 AD |
608 | $tagid = optional_param('tagid', $tagid, PARAM_INT); |
609 | $userid = optional_param('userid', $userid, PARAM_INT); | |
cae83708 | 610 | $modid = optional_param('modid', null, PARAM_INT); |
611 | $entryid = optional_param('entryid', null, PARAM_INT); | |
451f1e38 AD |
612 | $groupid = optional_param('groupid', $groupid, PARAM_INT); |
613 | $courseid = optional_param('courseid', $courseid, PARAM_INT); | |
cae83708 | 614 | $search = optional_param('search', null, PARAM_RAW); |
615 | $action = optional_param('action', null, PARAM_ALPHA); | |
616 | $confirm = optional_param('confirm', false, PARAM_BOOL); | |
617 | ||
1c7b8b93 NC |
618 | // Ignore userid when action == add |
619 | if ($action == 'add' && $userid) { | |
620 | unset($userid); | |
621 | $PAGE->url->remove_params(array('userid')); | |
622 | } else if ($action == 'add' && $entryid) { | |
623 | unset($entryid); | |
624 | $PAGE->url->remove_params(array('entryid')); | |
625 | } | |
626 | ||
627 | $headers = array('title' => '', 'heading' => '', 'cm' => null, 'filters' => array()); | |
cae83708 | 628 | |
a6855934 | 629 | $blogurl = new moodle_url('/blog/index.php'); |
1c7b8b93 NC |
630 | |
631 | // If the title is not yet set, it's likely that the context isn't set either, so skip this part | |
6f5e0852 | 632 | $pagetitle = $PAGE->title; |
1c7b8b93 NC |
633 | if (!empty($pagetitle)) { |
634 | $contexturl = blog_get_context_url(); | |
635 | ||
636 | // Look at the context URL, it may have additional params that are not in the current URL | |
637 | if (!$blogurl->compare($contexturl)) { | |
638 | $blogurl = $contexturl; | |
639 | if (empty($courseid)) { | |
640 | $courseid = $blogurl->param('courseid'); | |
641 | } | |
642 | if (empty($modid)) { | |
643 | $modid = $blogurl->param('modid'); | |
644 | } | |
645 | } | |
646 | } | |
647 | ||
648 | $headers['stradd'] = get_string('addnewentry', 'blog'); | |
649 | $headers['strview'] = null; | |
cae83708 | 650 | |
1c7b8b93 NC |
651 | $site = $DB->get_record('course', array('id' => SITEID)); |
652 | $sitecontext = get_context_instance(CONTEXT_SYSTEM); | |
cae83708 | 653 | // Common Lang strings |
654 | $strparticipants = get_string("participants"); | |
655 | $strblogentries = get_string("blogentries", 'blog'); | |
656 | ||
657 | // Prepare record objects as needed | |
658 | if (!empty($courseid)) { | |
1c7b8b93 | 659 | $headers['filters']['course'] = $courseid; |
cae83708 | 660 | $course = $DB->get_record('course', array('id' => $courseid)); |
661 | } | |
e96f2a77 | 662 | |
cae83708 | 663 | if (!empty($userid)) { |
1c7b8b93 | 664 | $headers['filters']['user'] = $userid; |
cae83708 | 665 | $user = $DB->get_record('user', array('id' => $userid)); |
516194d0 | 666 | } |
bbbf2d40 | 667 | |
cae83708 | 668 | if (!empty($groupid)) { // groupid always overrides courseid |
1c7b8b93 | 669 | $headers['filters']['group'] = $groupid; |
cae83708 | 670 | $group = $DB->get_record('groups', array('id' => $groupid)); |
671 | $course = $DB->get_record('course', array('id' => $group->courseid)); | |
672 | } | |
bbbf2d40 | 673 | |
897aa80c | 674 | $PAGE->set_pagelayout('standard'); |
27bad0a6 | 675 | |
1c7b8b93 NC |
676 | if (!empty($modid) && $CFG->useblogassociations && has_capability('moodle/blog:associatemodule', $sitecontext)) { // modid always overrides courseid, so the $course object may be reset here |
677 | $headers['filters']['module'] = $modid; | |
cae83708 | 678 | // A groupid param may conflict with this coursemod's courseid. Ignore groupid in that case |
1c7b8b93 NC |
679 | $courseid = $DB->get_field('course_modules', 'course', array('id'=>$modid)); |
680 | $course = $DB->get_record('course', array('id' => $courseid)); | |
cae83708 | 681 | $cm = $DB->get_record('course_modules', array('id' => $modid)); |
682 | $cm->modname = $DB->get_field('modules', 'name', array('id' => $cm->module)); | |
683 | $cm->name = $DB->get_field($cm->modname, 'name', array('id' => $cm->instance)); | |
e463f508 | 684 | $a = new stdClass(); |
1c7b8b93 | 685 | $a->type = get_string('modulename', $cm->modname); |
c5dc10ee | 686 | $PAGE->set_cm($cm, $course); |
1c7b8b93 NC |
687 | $headers['stradd'] = get_string('blogaboutthis', 'blog', $a); |
688 | $headers['strview'] = get_string('viewallmodentries', 'blog', $a); | |
cae83708 | 689 | } |
b73d1ca4 | 690 | |
1c7b8b93 NC |
691 | // Case 1: No entry, mod, course or user params: all site entries to be shown (filtered by search and tag/tagid) |
692 | // Note: if action is set to 'add' or 'edit', we do this at the end | |
693 | if (empty($entryid) && empty($modid) && empty($courseid) && empty($userid) && !in_array($action, array('edit', 'add'))) { | |
694 | $PAGE->navbar->add($strblogentries, $blogurl); | |
4a8b890a | 695 | $PAGE->set_title("$site->shortname: " . get_string('blog', 'blog')); |
696 | $PAGE->set_heading("$site->shortname: " . get_string('blog', 'blog')); | |
57513281 | 697 | $headers['heading'] = get_string('siteblog', 'blog', $site->shortname); |
1c7b8b93 | 698 | // $headers['strview'] = get_string('viewsiteentries', 'blog'); |
4a8b890a | 699 | } |
c2ee4e87 | 700 | |
1c7b8b93 | 701 | // Case 2: only entryid is requested, ignore all other filters. courseid is used to give more contextual information |
cae83708 | 702 | if (!empty($entryid)) { |
1c7b8b93 NC |
703 | $headers['filters']['entry'] = $entryid; |
704 | $sql = 'SELECT u.* FROM {user} u, {post} p WHERE p.id = ? AND p.userid = u.id'; | |
cae83708 | 705 | $user = $DB->get_record_sql($sql, array($entryid)); |
1c7b8b93 | 706 | $entry = $DB->get_record('post', array('id' => $entryid)); |
c2ee4e87 | 707 | |
1c7b8b93 | 708 | $blogurl->param('userid', $user->id); |
c2ee4e87 | 709 | |
cae83708 | 710 | if (!empty($course)) { |
9366362a | 711 | $mycourseid = $course->id; |
1c7b8b93 | 712 | $blogurl->param('courseid', $mycourseid); |
c2ee4e87 | 713 | } else { |
9366362a | 714 | $mycourseid = $site->id; |
c2ee4e87 | 715 | } |
e14de6f9 | 716 | |
1c7b8b93 NC |
717 | $PAGE->navbar->add($strblogentries, $blogurl); |
718 | ||
719 | $blogurl->remove_params('userid'); | |
720 | $PAGE->navbar->add($entry->subject, $blogurl); | |
c5dc10ee | 721 | |
722 | $PAGE->set_title("$site->shortname: " . fullname($user) . ": $entry->subject"); | |
723 | $PAGE->set_heading("$site->shortname: " . fullname($user) . ": $entry->subject"); | |
cae83708 | 724 | $headers['heading'] = get_string('blogentrybyuser', 'blog', fullname($user)); |
725 | ||
726 | // We ignore tag and search params | |
1c7b8b93 NC |
727 | if (empty($action) || !$CFG->useblogassociations) { |
728 | $headers['url'] = $blogurl; | |
9366362a | 729 | return $headers; |
730 | } | |
c2ee4e87 | 731 | } |
240075cd | 732 | |
1c7b8b93 NC |
733 | // Case 3: A user's blog entries |
734 | if (!empty($userid) && empty($entryid) && ((empty($courseid) && empty($modid)) || !$CFG->useblogassociations)) { | |
735 | $blogurl->param('userid', $userid); | |
c5dc10ee | 736 | $PAGE->set_title("$site->shortname: " . fullname($user) . ": " . get_string('blog', 'blog')); |
737 | $PAGE->set_heading("$site->shortname: " . fullname($user) . ": " . get_string('blog', 'blog')); | |
cae83708 | 738 | $headers['heading'] = get_string('userblog', 'blog', fullname($user)); |
27bad0a6 | 739 | $headers['strview'] = get_string('viewuserentries', 'blog', fullname($user)); |
1c7b8b93 NC |
740 | |
741 | } else | |
cae83708 | 742 | |
1c7b8b93 NC |
743 | // Case 4: No blog associations, no userid |
744 | if (!$CFG->useblogassociations && empty($userid) && !in_array($action, array('edit', 'add'))) { | |
1c7b8b93 NC |
745 | $PAGE->set_title("$site->shortname: " . get_string('blog', 'blog')); |
746 | $PAGE->set_heading("$site->shortname: " . get_string('blog', 'blog')); | |
57513281 | 747 | $headers['heading'] = get_string('siteblog', 'blog', $site->shortname); |
cae83708 | 748 | } else |
749 | ||
1c7b8b93 | 750 | // Case 5: Blog entries associated with an activity by a specific user (courseid ignored) |
9366362a | 751 | if (!empty($userid) && !empty($modid) && empty($entryid)) { |
1c7b8b93 NC |
752 | $blogurl->param('userid', $userid); |
753 | $blogurl->param('modid', $modid); | |
cae83708 | 754 | |
755 | // Course module navigation is handled by build_navigation as the second param | |
756 | $headers['cm'] = $cm; | |
c5dc10ee | 757 | $PAGE->navbar->add(fullname($user), "$CFG->wwwroot/user/view.php?id=$user->id"); |
1c7b8b93 | 758 | $PAGE->navbar->add($strblogentries, $blogurl); |
cae83708 | 759 | |
c5dc10ee | 760 | $PAGE->set_title("$site->shortname: $cm->name: " . fullname($user) . ': ' . get_string('blogentries', 'blog')); |
761 | $PAGE->set_heading("$site->shortname: $cm->name: " . fullname($user) . ': ' . get_string('blogentries', 'blog')); | |
cae83708 | 762 | |
e463f508 | 763 | $a = new stdClass(); |
cae83708 | 764 | $a->user = fullname($user); |
765 | $a->mod = $cm->name; | |
1c7b8b93 | 766 | $a->type = get_string('modulename', $cm->modname); |
cae83708 | 767 | $headers['heading'] = get_string('blogentriesbyuseraboutmodule', 'blog', $a); |
1c7b8b93 NC |
768 | $headers['stradd'] = get_string('blogaboutthis', 'blog', $a); |
769 | $headers['strview'] = get_string('viewallmodentries', 'blog', $a); | |
cae83708 | 770 | } else |
771 | ||
1c7b8b93 | 772 | // Case 6: Blog entries associated with a course by a specific user |
9366362a | 773 | if (!empty($userid) && !empty($courseid) && empty($modid) && empty($entryid)) { |
1c7b8b93 NC |
774 | $blogurl->param('userid', $userid); |
775 | $blogurl->param('courseid', $courseid); | |
2c27b6ae | 776 | |
1c7b8b93 | 777 | $PAGE->navbar->add($strblogentries, $blogurl); |
cae83708 | 778 | |
c5dc10ee | 779 | $PAGE->set_title("$site->shortname: $course->shortname: " . fullname($user) . ': ' . get_string('blogentries', 'blog')); |
780 | $PAGE->set_heading("$site->shortname: $course->shortname: " . fullname($user) . ': ' . get_string('blogentries', 'blog')); | |
cae83708 | 781 | |
e463f508 | 782 | $a = new stdClass(); |
cae83708 | 783 | $a->user = fullname($user); |
784 | $a->course = $course->fullname; | |
1c7b8b93 | 785 | $a->type = get_string('course'); |
cae83708 | 786 | $headers['heading'] = get_string('blogentriesbyuseraboutcourse', 'blog', $a); |
1c7b8b93 NC |
787 | $headers['stradd'] = get_string('blogaboutthis', 'blog', $a); |
788 | $headers['strview'] = get_string('viewblogentries', 'blog', $a); | |
789 | ||
790 | // Remove the userid from the URL to inform the blog_menu block correctly | |
791 | $blogurl->remove_params(array('userid')); | |
cae83708 | 792 | } else |
793 | ||
1c7b8b93 | 794 | // Case 7: Blog entries by members of a group, associated with that group's course |
9366362a | 795 | if (!empty($groupid) && empty($modid) && empty($entryid)) { |
1c7b8b93 | 796 | $blogurl->param('courseid', $course->id); |
e14de6f9 | 797 | |
1c7b8b93 NC |
798 | $PAGE->navbar->add($strblogentries, $blogurl); |
799 | $blogurl->remove_params(array('courseid')); | |
800 | $blogurl->param('groupid', $groupid); | |
801 | $PAGE->navbar->add($group->name, $blogurl); | |
cae83708 | 802 | |
c5dc10ee | 803 | $PAGE->set_title("$site->shortname: $course->shortname: " . get_string('blogentries', 'blog') . ": $group->name"); |
804 | $PAGE->set_heading("$site->shortname: $course->shortname: " . get_string('blogentries', 'blog') . ": $group->name"); | |
cae83708 | 805 | |
e463f508 | 806 | $a = new stdClass(); |
cae83708 | 807 | $a->group = $group->name; |
808 | $a->course = $course->fullname; | |
1c7b8b93 | 809 | $a->type = get_string('course'); |
cae83708 | 810 | $headers['heading'] = get_string('blogentriesbygroupaboutcourse', 'blog', $a); |
1c7b8b93 NC |
811 | $headers['stradd'] = get_string('blogaboutthis', 'blog', $a); |
812 | $headers['strview'] = get_string('viewblogentries', 'blog', $a); | |
cae83708 | 813 | } else |
814 | ||
1c7b8b93 | 815 | // Case 8: Blog entries by members of a group, associated with an activity in that course |
9366362a | 816 | if (!empty($groupid) && !empty($modid) && empty($entryid)) { |
cae83708 | 817 | $headers['cm'] = $cm; |
1c7b8b93 NC |
818 | $blogurl->param('modid', $modid); |
819 | $PAGE->navbar->add($strblogentries, $blogurl); | |
cae83708 | 820 | |
1c7b8b93 NC |
821 | $blogurl->param('groupid', $groupid); |
822 | $PAGE->navbar->add($group->name, $blogurl); | |
cae83708 | 823 | |
c5dc10ee | 824 | $PAGE->set_title("$site->shortname: $course->shortname: $cm->name: " . get_string('blogentries', 'blog') . ": $group->name"); |
825 | $PAGE->set_heading("$site->shortname: $course->shortname: $cm->name: " . get_string('blogentries', 'blog') . ": $group->name"); | |
cae83708 | 826 | |
e463f508 | 827 | $a = new stdClass(); |
cae83708 | 828 | $a->group = $group->name; |
829 | $a->mod = $cm->name; | |
1c7b8b93 | 830 | $a->type = get_string('modulename', $cm->modname); |
cae83708 | 831 | $headers['heading'] = get_string('blogentriesbygroupaboutmodule', 'blog', $a); |
1c7b8b93 NC |
832 | $headers['stradd'] = get_string('blogaboutthis', 'blog', $a); |
833 | $headers['strview'] = get_string('viewallmodentries', 'blog', $a); | |
cae83708 | 834 | |
835 | } else | |
836 | ||
1c7b8b93 | 837 | // Case 9: All blog entries associated with an activity |
9366362a | 838 | if (!empty($modid) && empty($userid) && empty($groupid) && empty($entryid)) { |
c5dc10ee | 839 | $PAGE->set_cm($cm, $course); |
1c7b8b93 NC |
840 | $blogurl->param('modid', $modid); |
841 | $PAGE->navbar->add($strblogentries, $blogurl); | |
c5dc10ee | 842 | $PAGE->set_title("$site->shortname: $course->shortname: $cm->name: " . get_string('blogentries', 'blog')); |
843 | $PAGE->set_heading("$site->shortname: $course->shortname: $cm->name: " . get_string('blogentries', 'blog')); | |
cae83708 | 844 | $headers['heading'] = get_string('blogentriesabout', 'blog', $cm->name); |
e463f508 | 845 | $a = new stdClass(); |
1c7b8b93 NC |
846 | $a->type = get_string('modulename', $cm->modname); |
847 | $headers['stradd'] = get_string('blogaboutthis', 'blog', $a); | |
848 | $headers['strview'] = get_string('viewallmodentries', 'blog', $a); | |
cae83708 | 849 | } else |
850 | ||
1c7b8b93 | 851 | // Case 10: All blog entries associated with a course |
9366362a | 852 | if (!empty($courseid) && empty($userid) && empty($groupid) && empty($modid) && empty($entryid)) { |
1c7b8b93 NC |
853 | $blogurl->param('courseid', $courseid); |
854 | $PAGE->navbar->add($strblogentries, $blogurl); | |
c5dc10ee | 855 | $PAGE->set_title("$site->shortname: $course->shortname: " . get_string('blogentries', 'blog')); |
856 | $PAGE->set_heading("$site->shortname: $course->shortname: " . get_string('blogentries', 'blog')); | |
e463f508 | 857 | $a = new stdClass(); |
1c7b8b93 | 858 | $a->type = get_string('course'); |
cae83708 | 859 | $headers['heading'] = get_string('blogentriesabout', 'blog', $course->fullname); |
1c7b8b93 NC |
860 | $headers['stradd'] = get_string('blogaboutthis', 'blog', $a); |
861 | $headers['strview'] = get_string('viewblogentries', 'blog', $a); | |
862 | $blogurl->remove_params(array('userid')); | |
863 | } | |
864 | ||
865 | if (!in_array($action, array('edit', 'add'))) { | |
866 | // Append Tag info | |
867 | if (!empty($tagid)) { | |
868 | $headers['filters']['tag'] = $tagid; | |
869 | $blogurl->param('tagid', $tagid); | |
870 | $tagrec = $DB->get_record('tag', array('id'=>$tagid)); | |
871 | $PAGE->navbar->add($tagrec->name, $blogurl); | |
872 | } elseif (!empty($tag)) { | |
873 | $blogurl->param('tag', $tag); | |
874 | $PAGE->navbar->add(get_string('tagparam', 'blog', $tag), $blogurl); | |
875 | } | |
240075cd | 876 | |
1c7b8b93 NC |
877 | // Append Search info |
878 | if (!empty($search)) { | |
879 | $headers['filters']['search'] = $search; | |
880 | $blogurl->param('search', $search); | |
881 | $PAGE->navbar->add(get_string('searchterm', 'blog', $search), $blogurl->out()); | |
882 | } | |
ee00eb8c | 883 | } |
884 | ||
cae83708 | 885 | // Append edit mode info |
886 | if (!empty($action) && $action == 'add') { | |
f36b47ef | 887 | |
cae83708 | 888 | } else if (!empty($action) && $action == 'edit') { |
c5dc10ee | 889 | $PAGE->navbar->add(get_string('editentry', 'blog')); |
240075cd | 890 | } |
ee00eb8c | 891 | |
1c7b8b93 NC |
892 | if (empty($headers['url'])) { |
893 | $headers['url'] = $blogurl; | |
894 | } | |
cae83708 | 895 | return $headers; |
896 | } | |
23677261 | 897 | |
1c7b8b93 NC |
898 | /** |
899 | * Shortcut function for getting a count of blog entries associated with a course or a module | |
900 | * @param int $courseid The ID of the course | |
901 | * @param int $cmid The ID of the course_modules | |
902 | * @return string The number of associated entries | |
903 | */ | |
904 | function blog_get_associated_count($courseid, $cmid=null) { | |
905 | global $DB; | |
906 | $context = get_context_instance(CONTEXT_COURSE, $courseid); | |
907 | if ($cmid) { | |
908 | $context = get_context_instance(CONTEXT_MODULE, $cmid); | |
909 | } | |
910 | return $DB->count_records('blog_association', array('contextid' => $context->id)); | |
593270c6 | 911 | } |