Various improvements to Examview input.
[moodle-linuxchix.git] / blog / lib.php
blob55fbe953922973a9a06a8a1e76ef07c25e7e3dd3
1 <?php //$Id$
3 /**
4 * Library of functions and constants for blog
5 */
6 require_once($CFG->libdir .'/blocklib.php');
7 require_once($CFG->libdir .'/pagelib.php');
8 require_once($CFG->dirroot .'/blog/rsslib.php');
9 require_once($CFG->dirroot .'/blog/blogpage.php');
12 /**
13 * Blog access level constant declaration
15 define ('BLOG_USER_LEVEL', 1);
16 define ('BLOG_GROUP_LEVEL', 2);
17 define ('BLOG_COURSE_LEVEL', 3);
18 define ('BLOG_SITE_LEVEL', 4);
19 define ('BLOG_GLOBAL_LEVEL', 5);
22 /**
23 * Definition of blogcourse page type (blog page with course id present).
25 //not used at the moment, and may not need to be
26 define('PAGE_BLOG_COURSE_VIEW', 'blog_course-view');
29 /**
30 * Checks to see if user has visited blogpages before, if not, install 2
31 * default blocks (blog_menu and blog_tags).
33 function blog_check_and_install_blocks() {
34 global $USER;
35 if (isloggedin() && !isguest()) {
36 // if this user has not visited this page before
37 if (!get_user_preferences('blogpagesize')) {
38 // find the correct ids for blog_menu and blog_from blocks
39 $menublock = get_record('block','name','blog_menu');
40 $tagsblock = get_record('block','name','blog_tags');
41 // add those 2 into block_instance page
43 // add blog_menu block
44 $newblock = new object();
45 $newblock -> blockid = $menublock->id;
46 $newblock -> pageid = $USER->id;
47 $newblock -> pagetype = 'blog-view';
48 $newblock -> position = 'r';
49 $newblock -> weight = 0;
50 $newblock -> visible = 1;
51 insert_record('block_instance', $newblock);
53 // add blog_tags menu
54 $newblock -> blockid = $tagsblock->id;
55 $newblock -> weight = 1;
56 insert_record('block_instance', $newblock);
58 // finally we set the page size pref
59 set_user_preference('blogpagesize', 10);
65 /**
66 * Adaptation of isediting in moodlelib.php for blog module
67 * @return bool
69 function blog_isediting() {
70 global $SESSION;
72 return !empty($SESSION->blog_editing_enabled);
76 /**
77 * This function is in lib and not in BlogInfo because entries being searched
78 * might be found in any number of blogs rather than just one.
80 * $@param ...
82 function blog_print_html_formatted_entries($postid, $filtertype, $filterselect, $tagid, $tag) {
84 global $CFG, $USER;
86 $blogpage = optional_param('blogpage', 0, PARAM_INT);
87 $bloglimit = optional_param('limit', get_user_preferences('blogpagesize', 10), PARAM_INT);
88 $start = $blogpage * $bloglimit;
90 $sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
92 $morelink = '<br />&nbsp;&nbsp;';
94 $totalentries = get_viewable_entry_count($postid, $bloglimit, $start, $filtertype, $filterselect, $tagid, $tag, $sort='lastmodified DESC');
95 $blogEntries = fetch_entries($postid, $bloglimit, $start, $filtertype, $filterselect, $tagid, $tag, $sort='lastmodified DESC', true);
97 print_paging_bar($totalentries, $blogpage, $bloglimit, get_baseurl($filtertype, $filterselect), 'blogpage');
99 if ($CFG->enablerssfeeds) {
100 blog_rss_print_link($filtertype, $filterselect, $tag);
103 if (has_capability('moodle/blog:create', $sitecontext)) {
104 //the user's blog is enabled and they are viewing their own blog
105 $addlink = '<div align="center">';
106 $addlink .= '<a href="'.$CFG->wwwroot .'/blog/edit.php?action=add'.'">'. get_string('addnewentry', 'blog').'</a>';
107 $addlink .= '</div>';
108 echo $addlink;
111 if ($blogEntries) {
113 $count = 0;
114 foreach ($blogEntries as $blogEntry) {
115 blog_print_entry($blogEntry, 'list', $filtertype, $filterselect); //print this entry.
116 $count++;
119 print_paging_bar($totalentries, $blogpage, $bloglimit, get_baseurl($filtertype, $filterselect), 'blogpage');
121 if (!$count) {
122 print '<br /><center>'. get_string('noentriesyet', 'blog') .'</center><br />';
126 print $morelink.'<br />'."\n";
127 return;
130 $output = '<br /><center>'. get_string('noentriesyet', 'blog') .'</center><br />';
132 print $output;
138 * This function is in lib and not in BlogInfo because entries being searched
139 * might be found in any number of blogs rather than just one.
141 * This function builds an array which can be used by the included
142 * template file, making predefined and nicely formatted variables available
143 * to the template. Template creators will not need to become intimate
144 * with the internal objects and vars of moodle blog nor will they need to worry
145 * about properly formatting their data
147 * @param BlogEntry blogEntry - a hopefully fully populated BlogEntry object
148 * @param string viewtype Default is 'full'. If 'full' then display this blog entry
149 * in its complete form (eg. archive page). If anything other than 'full'
150 * display the entry in its abbreviated format (eg. index page)
152 function blog_print_entry($blogEntry, $viewtype='full', $filtertype='', $filterselect='', $mode='loud') {
154 global $USER, $CFG, $COURSE, $ME;
156 $template['body'] = format_text($blogEntry->summary, $blogEntry->format);
157 $template['title'] = '<a name="'. $blogEntry->subject .'"></a>';
158 //enclose the title in nolink tags so that moodle formatting doesn't autolink the text
159 $template['title'] .= '<span class="nolink">'.$blogEntry->subject.'</span>';
160 $template['userid'] = $blogEntry->userid;
161 $template['author'] = fullname(get_record('user','id',$blogEntry->userid));
162 $template['lastmod'] = userdate($blogEntry->lastmodified);
163 $template['created'] = userdate($blogEntry->created);
164 $template['publishstate'] = $blogEntry->publishstate;
166 /// preventing user to browse blogs that they aren't supposed to see
167 /// This might not be too good since there are multiple calls per page
170 if (!blog_user_can_view_user_post($template['userid'])) {
171 error ('you can not view this post');
174 $stredit = get_string('edit');
175 $strdelete = get_string('delete');
177 $user = get_record('user','id',$template['userid']);
179 /// Start printing of the blog
181 echo '<table cellspacing="0" class="forumpost blogpost blog'.$template['publishstate'].'" width="100%">';
183 echo '<tr class="header"><td class="picture left">';
184 print_user_picture($template['userid'], SITEID, $user->picture);
185 echo '</td>';
187 echo '<td class="topic starter"><div class="subject">'.$template['title'].'</div><div class="author">';
188 $fullname = fullname($user, $template['userid']);
189 $by = new object();
190 $by->name = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.
191 $user->id.'&amp;course='.$COURSE->id.'">'.$fullname.'</a>';
192 $by->date = $template['lastmod'];
193 print_string('bynameondate', 'forum', $by);
194 echo '</div></td></tr>';
196 echo '<tr><td class="left side">';
198 /// Actual content
200 echo '</td><td class="content">'."\n";
202 if ($blogEntry->attachment) {
203 echo '<div class="attachments">';
204 $attachedimages = blog_print_attachments($blogEntry);
205 echo '</div>';
206 } else {
207 $attachedimages = '';
210 switch ($template['publishstate']) {
211 case 'draft':
212 $blogtype = get_string('publishtonoone', 'blog');
213 break;
214 case 'site':
215 $blogtype = get_string('publishtosite', 'blog');
216 break;
217 case 'public':
218 $blogtype = get_string('publishtoworld', 'blog');
219 break;
220 default:
221 $blogtype = '';
222 break;
226 echo '<div class="audience">'.$blogtype.'</div>';
228 // Print whole message
229 echo format_text($template['body']);
231 /// Print attachments
232 echo $attachedimages;
233 /// Links to tags
235 if ($blogtags = get_records_sql('SELECT t.* FROM '.$CFG->prefix.'tags t, '.$CFG->prefix.'blog_tag_instance ti
236 WHERE t.id = ti.tagid
237 AND ti.entryid = '.$blogEntry->id)) {
238 echo '<div class="tags">';
239 if ($blogtags) {
240 print_string('tags');
241 echo ': ';
242 foreach ($blogtags as $key => $blogtag) {
243 $taglist[] = '<a href="index.php?filtertype='.$filtertype.'&amp;filterselect='.$filterselect.'&amp;tagid='.$blogtag->id.'">'.$blogtag->text.'</a>';
245 echo implode(', ', $taglist);
247 echo '</div>';
250 /// Commands
252 echo '<div class="commands">';
254 if (blog_user_can_edit_post($blogEntry)) {
255 echo '<a href="'.$CFG->wwwroot.'/blog/edit.php?action=edit&amp;id='.$blogEntry->id.'">'.$stredit.'</a>';
256 echo '| <a href="'.$CFG->wwwroot.'/blog/edit.php?action=delete&amp;id='.$blogEntry->id.'">'.$strdelete.'</a>';
259 echo '</div>';
261 echo '</td></tr></table>'."\n\n";
265 function blog_file_area_name($blogentry) {
266 // Creates a directory file name, suitable for make_upload_directory()
267 global $CFG;
268 // $CFG->dataroot/blog/attachments/xxxx/file.jpg
269 return "blog/attachments/$blogentry->id";
272 function blog_file_area($blogentry) {
273 return make_upload_directory( blog_file_area_name($blogentry) );
277 function blog_print_attachments($blogentry, $return=NULL) {
278 // if return=html, then return a html string.
279 // if return=text, then return a text-only string.
280 // otherwise, print HTML for non-images, and return image HTML
282 global $CFG;
284 $filearea = blog_file_area_name($blogentry);
286 $imagereturn = "";
287 $output = "";
289 if ($basedir = blog_file_area($blogentry)) {
290 if ($files = get_directory_list($basedir)) {
291 $strattachment = get_string("attachment", "forum");
292 foreach ($files as $file) {
293 include_once($CFG->libdir.'/filelib.php');
294 $icon = mimeinfo("icon", $file);
295 if ($CFG->slasharguments) {
296 $ffurl = "$CFG->wwwroot/file.php/$filearea/$file";
297 } else {
298 $ffurl = "$CFG->wwwroot/file.php?file=/$filearea/$file";
300 $image = "<img border=\"0\" src=\"$CFG->pixpath/f/$icon\" height=\"16\" width=\"16\" alt=\"\" />";
302 if ($return == "html") {
303 $output .= "<a href=\"$ffurl\">$image</a> ";
304 $output .= "<a href=\"$ffurl\">$file</a><br />";
306 } else if ($return == "text") {
307 $output .= "$strattachment $file:\n$ffurl\n";
309 } else {
310 if ($icon == "image.gif") { // Image attachments don't get printed as links
311 $imagereturn .= "<br /><img src=\"$ffurl\" alt=\"\" />";
312 } else {
313 echo "<a href=\"$ffurl\">$image</a> ";
314 echo filter_text("<a href=\"$ffurl\">$file</a><br />");
321 if ($return) {
322 return $output;
325 return $imagereturn;
329 * If successful, this function returns the name of the file
330 * @param $post is a full post record, including course and forum
331 * @param $newfile is a full upload array from $_FILES
332 * @param $message is a string to hold the messages.
335 function blog_add_attachment($blogentry, $inputname, &$message) {
337 global $CFG;
339 require_once($CFG->dirroot.'/lib/uploadlib.php');
340 $um = new upload_manager($inputname,true,false,null,false,$CFG->maxbytes,true,true);
341 $dir = blog_file_area_name($blogentry);
342 if ($um->process_file_uploads($dir)) {
343 $message .= $um->get_errors();
344 return $um->get_new_filename();
346 $message .= $um->get_errors();
347 echo $message;
351 * Use this function to retrieve a list of publish states available for
352 * the currently logged in user.
354 * @return array This function returns an array ideal for sending to moodles'
355 * choose_from_menu function.
357 function blog_applicable_publish_states($courseid='') {
359 global $CFG;
361 // everyone gets draft access
362 if ($CFG->bloglevel >= BLOG_USER_LEVEL) {
363 $options = array ( 'draft' => get_string('publishtonoone', 'blog') );
366 if ($CFG->bloglevel > BLOG_USER_LEVEL) {
367 $options['site'] = get_string('publishtosite', 'blog');
370 if ($CFG->bloglevel >= BLOG_GLOBAL_LEVEL) {
371 $options['public'] = get_string('publishtoworld', 'blog');
374 return $options;
379 * User can edit a blog entry if this is their own blog post and they have
380 * the capability moodle/blog:create, or if they have the capability
381 * moodle/blog:manageentries.
383 * This also applies to deleting of posts.
385 function blog_user_can_edit_post($blogEntry) {
387 global $CFG, $USER;
389 $sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
391 if (has_capability('moodle/blog:manageentries', $sitecontext)) {
392 return true; // can edit any blog post
395 if ($blogEntry->userid == $USER->id
396 and has_capability('moodle/blog:create', $sitecontext)) {
397 return true; // can edit own when having blog:create capability
400 return false;
405 * Checks to see if a user can view the blogs of another user.
406 * Only blog level is checked here, the capabilities are enforced
407 * in blog/index.php
409 function blog_user_can_view_user_post($targetuserid, $blogEntry=null) {
410 global $CFG, $USER;
412 if (empty($CFG->bloglevel)) {
413 return false; // blog system disabled
416 if (!empty($USER->id) and $USER->id == $targetuserid) {
417 return true; // can view own posts in any case
420 $sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
421 if (has_capability('moodle/blog:manageentries', $sitecontext)) {
422 return true; // can manage all posts
425 if ($blogEntry and $blogEntry->publishstate == 'draft') {
426 return false; // can not view draft of others
429 switch ($CFG->bloglevel) {
430 case BLOG_GLOBAL_LEVEL:
431 return true;
432 break;
434 case BLOG_SITE_LEVEL:
435 if (!empty($USER->id)) { // not logged in viewers forbidden
436 return true;
438 return false;
439 break;
441 case BLOG_COURSE_LEVEL:
442 $mycourses = array_keys(get_my_courses($targetuserid));
443 $usercourses = array_keys(get_my_courses($targetuserid));
444 $shared = array_intersect($mycourses, $usercourses);
445 if (!empty($shared)) {
446 return true;
448 return false;
449 break;
451 case BLOG_GROUP_LEVEL:
452 $mycourses = array_keys(get_my_courses($targetuserid));
453 $usercourses = array_keys(get_my_courses($targetuserid));
454 $shared = array_intersect($mycourses, $usercourses);
455 foreach ($shared as $courseid) {
456 $coursecontext = get_context_instance(CONTEXT_COURSE, $courseid);
457 if (has_capability('moodle/site:accessallgroups', $coursecontext)
458 or groupmode($courseid) != SEPARATEGROUPS) {
459 return true;
460 } else {
461 if ($usergroups = user_group($courseid, $targetuserid)) {
462 foreach ($usergroups as $usergroup) {
463 if (ismember($usergroup->id)) {
464 return true;
470 return false;
471 break;
473 case BLOG_USER_LEVEL:
474 default:
475 $personalcontext = get_context_instance(CONTEXT_USER, $targetuserid);
476 return has_capability('moodle/user:readuserblogs', $personalcontext);
477 break;
484 * Main filter function.
486 function fetch_entries($postid='', $fetchlimit=10, $fetchstart='', $filtertype='', $filterselect='', $tagid='', $tag ='', $sort='lastmodified DESC', $limit=true) {
488 global $CFG, $USER;
490 /// set the tag id for searching
491 if ($tagid) {
492 $tag = $tagid;
493 } else if ($tag) {
494 if ($tagrec = get_record_sql('SELECT * FROM '.$CFG->prefix.'tags WHERE text LIKE "'.$tag.'"')) {
495 $tag = $tagrec->id;
496 } else {
497 $tag = -1; //no records found
501 // If we have specified an ID
502 // Just return 1 entry
504 if ($postid) {
506 if ($post = get_record('post', 'id', $postid)) {
508 if (blog_user_can_view_user_post($post->userid)) {
510 if ($user = get_record('user', 'id', $post->userid)) {
511 $post->email = $user->email;
512 $post->firstname = $user->firstname;
513 $post->lastname = $user->lastname;
515 $retarray[] = $post;
516 return $retarray;
517 } else {
518 return null;
521 } else { // bad postid
522 return null;
526 if ($tag) {
527 $tagtablesql = $CFG->prefix.'blog_tag_instance bt, ';
528 $tagquerysql = ' AND bt.entryid = p.id AND bt.tagid = '.$tag.' ';
529 } else {
530 $tagtablesql = '';
531 $tagquerysql = '';
534 if (isloggedin()) {
535 $permissionsql = '(p.publishstate = \'site\' OR p.publishstate = \'public\' OR p.userid = '.$USER->id.')';
536 } else {
537 $permissionsql = 'p.publishstate = \'public\'';
541 /****************************************
542 * depending on the type, there are 4 *
543 * different possible sqls *
544 ****************************************/
546 $requiredfields = 'p.*, u.firstname,u.lastname,u.email';
548 if ($filtertype == 'course' && $filterselect == SITEID) { // Really a site
549 $filtertype = 'site';
552 switch ($filtertype) {
554 case 'site':
556 $SQL = 'SELECT '.$requiredfields.' FROM '.$CFG->prefix.'post p, '.$tagtablesql
557 .$CFG->prefix.'user u
558 WHERE p.userid = u.id '.$tagquerysql.'
559 AND u.deleted = 0
560 AND '.$permissionsql;
562 break;
564 case 'course':
565 // all users with a role assigned
566 $context = get_context_instance(CONTEXT_COURSE, $filterselect);
568 $SQL = 'SELECT '.$requiredfields.' FROM '.$CFG->prefix.'post p, '.$tagtablesql
569 .$CFG->prefix.'role_assignments ra, '.$CFG->prefix.'user u
570 WHERE p.userid = ra.userid '.$tagquerysql.'
571 AND ra.contextid '.get_related_contexts_string($context).'
572 AND u.id = p.userid
573 AND u.deleted = 0
574 AND '.$permissionsql;
576 break;
578 case 'group':
580 $SQL = 'SELECT '.$requiredfields.' FROM '.$CFG->prefix.'post p, '.$tagtablesql
581 .$CFG->prefix.'groups_members m, '.$CFG->prefix.'user u
582 WHERE p.userid = m.userid '.$tagquerysql.'
583 AND u.id = p.userid
584 AND m.groupid = '.$filterselect.'
585 AND u.deleted = 0
586 AND '.$permissionsql;
588 break;
590 case 'user':
592 $SQL = 'SELECT '.$requiredfields.' FROM '.$CFG->prefix.'post p, '.$tagtablesql
593 .$CFG->prefix.'user u
594 WHERE p.userid = u.id '.$tagquerysql.'
595 AND u.id = '.$filterselect.'
596 AND u.deleted = 0
597 AND '.$permissionsql;
598 break;
601 $limitfrom = 0;
602 $limitnum = 0;
604 if ($fetchstart !== '' && $limit) {
605 $limitfrom = $fetchstart;
606 $limitnum = $fetchlimit;
609 $orderby = ' ORDER BY '. $sort .' ';
611 //global $db; $db->debug = true;
612 $records = get_records_sql($SQL . $orderby, $limitfrom, $limitnum);
613 //$db->debug = false;
615 if (empty($records)) {
616 return array();
619 return $records;
624 * get the count of viewable entries, easiest way is to count fetch_entries
625 * this is used for print_paging_bar
626 * this is not ideal, but because of the UNION in the sql in fetch_entries,
627 * it is hard to use count_records_sql
629 function get_viewable_entry_count($postid='', $fetchlimit=10,
630 $fetchstart='', $filtertype='', $filterselect='', $tagid='',
631 $tag ='', $sort='lastmodified DESC') {
633 $blogEntries = fetch_entries($postid, $fetchlimit,
634 $fetchstart, $filtertype, $filterselect, $tagid, $tag,
635 $sort='lastmodified DESC', false);
637 return count($blogEntries);
641 /// Find the base url from $_GET variables, for print_paging_bar
642 function get_baseurl($filtertype, $filterselect) {
644 $getcopy = $_GET;
646 unset($getcopy['blogpage']);
648 $strippedurl = strip_querystring(qualified_me());
649 if(!empty($getcopy)) {
650 $first = false;
651 $querystring = '';
652 foreach($getcopy as $var => $val) {
653 if(!$first) {
654 $first = true;
655 if ($var != 'filterselect' && $var != 'filtertype') {
656 $querystring .= '?'.$var.'='.$val;
657 $hasparam = true;
658 } else {
659 $querystring .= '?';
661 } else {
662 if ($var != 'filterselect' && $var != 'filtertype') {
663 $querystring .= '&amp;'.$var.'='.$val;
664 $hasparam = true;
668 if (isset($hasparam)) {
669 $querystring .= '&amp;';
670 } else {
671 $querystring = '?';
673 } else {
674 $querystring = '?';
677 return strip_querystring(qualified_me()) . $querystring. 'filtertype='.
678 $filtertype.'&amp;filterselect='.$filterselect.'&amp;';