| [ Index ] |
PHP Cross Reference of Moodle 1.9.3 [Build 15-Oct-2008] |
[Summary view] [Print] [Text view]
1 <?php //$Id: lib.php,v 1.80.2.16 2008/07/10 09:48:43 scyrma Exp $ 2 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'); 10 require_once($CFG->dirroot.'/tag/lib.php'); 11 12 /** 13 * Definition of blogcourse page type (blog page with course id present). 14 */ 15 //not used at the moment, and may not need to be 16 define('PAGE_BLOG_COURSE_VIEW', 'blog_course-view'); 17 18 19 /** 20 * Checks to see if user has visited blogpages before, if not, install 2 21 * default blocks (blog_menu and blog_tags). 22 */ 23 function blog_check_and_install_blocks() { 24 global $USER; 25 if (isloggedin() && !isguest()) { 26 // if this user has not visited this page before 27 if (!get_user_preferences('blogpagesize')) { 28 // find the correct ids for blog_menu and blog_from blocks 29 $menublock = get_record('block','name','blog_menu'); 30 $tagsblock = get_record('block','name','blog_tags'); 31 // add those 2 into block_instance page 32 33 // add blog_menu block 34 $newblock = new object(); 35 $newblock->blockid = $menublock->id; 36 $newblock->pageid = $USER->id; 37 $newblock->pagetype = 'blog-view'; 38 $newblock->position = 'r'; 39 $newblock->weight = 0; 40 $newblock->visible = 1; 41 insert_record('block_instance', $newblock); 42 43 // add blog_tags menu 44 $newblock -> blockid = $tagsblock->id; 45 $newblock -> weight = 1; 46 insert_record('block_instance', $newblock); 47 48 // finally we set the page size pref 49 set_user_preference('blogpagesize', 10); 50 } 51 } 52 } 53 54 55 /** 56 * Adaptation of isediting in moodlelib.php for blog module 57 * @return bool 58 */ 59 function blog_isediting() { 60 global $SESSION; 61 62 return !empty($SESSION->blog_editing_enabled); 63 } 64 65 66 /** 67 * This function is in lib and not in BlogInfo because entries being searched 68 * might be found in any number of blogs rather than just one. 69 * 70 * $@param ... 71 */ 72 function blog_print_html_formatted_entries($postid, $filtertype, $filterselect, $tagid, $tag) { 73 74 global $CFG, $USER; 75 76 $blogpage = optional_param('blogpage', 0, PARAM_INT); 77 $bloglimit = optional_param('limit', get_user_preferences('blogpagesize', 10), PARAM_INT); 78 $start = $blogpage * $bloglimit; 79 80 $sitecontext = get_context_instance(CONTEXT_SYSTEM); 81 82 $morelink = '<br /> '; 83 84 $totalentries = get_viewable_entry_count($postid, $bloglimit, $start, $filtertype, $filterselect, $tagid, $tag, $sort='created DESC'); 85 $blogEntries = blog_fetch_entries($postid, $bloglimit, $start, $filtertype, $filterselect, $tagid, $tag, $sort='created DESC', true); 86 87 print_paging_bar($totalentries, $blogpage, $bloglimit, get_baseurl($filtertype, $filterselect), 'blogpage'); 88 89 if ($CFG->enablerssfeeds) { 90 blog_rss_print_link($filtertype, $filterselect, $tag); 91 } 92 93 if (has_capability('moodle/blog:create', $sitecontext)) { 94 //the user's blog is enabled and they are viewing their own blog 95 $addlink = '<div class="addbloglink">'; 96 $addlink .= '<a href="'.$CFG->wwwroot .'/blog/edit.php?action=add'.'">'. get_string('addnewentry', 'blog').'</a>'; 97 $addlink .= '</div>'; 98 echo $addlink; 99 } 100 101 if ($blogEntries) { 102 103 $count = 0; 104 foreach ($blogEntries as $blogEntry) { 105 blog_print_entry($blogEntry, 'list', $filtertype, $filterselect); //print this entry. 106 $count++; 107 } 108 109 print_paging_bar($totalentries, $blogpage, $bloglimit, get_baseurl($filtertype, $filterselect), 'blogpage'); 110 111 if (!$count) { 112 print '<br /><div style="text-align:center">'. get_string('noentriesyet', 'blog') .'</div><br />'; 113 114 } 115 116 print $morelink.'<br />'."\n"; 117 return; 118 } 119 120 $output = '<br /><div style="text-align:center">'. get_string('noentriesyet', 'blog') .'</div><br />'; 121 122 print $output; 123 124 } 125 126 127 /** 128 * This function is in lib and not in BlogInfo because entries being searched 129 * might be found in any number of blogs rather than just one. 130 * 131 * This function builds an array which can be used by the included 132 * template file, making predefined and nicely formatted variables available 133 * to the template. Template creators will not need to become intimate 134 * with the internal objects and vars of moodle blog nor will they need to worry 135 * about properly formatting their data 136 * 137 * @param BlogEntry blogEntry - a hopefully fully populated BlogEntry object 138 * @param string viewtype Default is 'full'. If 'full' then display this blog entry 139 * in its complete form (eg. archive page). If anything other than 'full' 140 * display the entry in its abbreviated format (eg. index page) 141 */ 142 function blog_print_entry($blogEntry, $viewtype='full', $filtertype='', $filterselect='', $mode='loud') { 143 144 global $USER, $CFG, $COURSE, $ME; 145 146 $template['body'] = format_text($blogEntry->summary, $blogEntry->format); 147 $template['title'] = '<a id=b"'. s($blogEntry->id) .' /">'; 148 //enclose the title in nolink tags so that moodle formatting doesn't autolink the text 149 $template['title'] .= '<span class="nolink">'. format_string($blogEntry->subject) .'</span>'; 150 $template['userid'] = $blogEntry->userid; 151 $template['author'] = fullname(get_record('user','id',$blogEntry->userid)); 152 $template['created'] = userdate($blogEntry->created); 153 154 if($blogEntry->created != $blogEntry->lastmodified){ 155 $template['lastmod'] = userdate($blogEntry->lastmodified); 156 } 157 158 $template['publishstate'] = $blogEntry->publishstate; 159 160 /// preventing user to browse blogs that they aren't supposed to see 161 /// This might not be too good since there are multiple calls per page 162 163 /* 164 if (!blog_user_can_view_user_post($template['userid'])) { 165 error ('you can not view this post'); 166 }*/ 167 168 $stredit = get_string('edit'); 169 $strdelete = get_string('delete'); 170 171 $user = get_record('user','id',$template['userid']); 172 173 /// Start printing of the blog 174 175 echo '<table cellspacing="0" class="forumpost blogpost blog'.$template['publishstate'].'" width="100%">'; 176 177 echo '<tr class="header"><td class="picture left">'; 178 print_user_picture($user, SITEID, $user->picture); 179 echo '</td>'; 180 181 echo '<td class="topic starter"><div class="subject">'.$template['title'].'</div><div class="author">'; 182 $fullname = fullname($user, $template['userid']); 183 $by = new object(); 184 $by->name = '<a href="'.$CFG->wwwroot.'/user/view.php?id='. 185 $user->id.'&course='.$COURSE->id.'">'.$fullname.'</a>'; 186 $by->date = $template['created']; 187 print_string('bynameondate', 'forum', $by); 188 echo '</div></td></tr>'; 189 190 echo '<tr><td class="left side">'; 191 192 /// Actual content 193 194 echo '</td><td class="content">'."\n"; 195 196 if ($blogEntry->attachment) { 197 echo '<div class="attachments">'; 198 $attachedimages = blog_print_attachments($blogEntry); 199 echo '</div>'; 200 } else { 201 $attachedimages = ''; 202 } 203 204 switch ($template['publishstate']) { 205 case 'draft': 206 $blogtype = get_string('publishtonoone', 'blog'); 207 break; 208 case 'site': 209 $blogtype = get_string('publishtosite', 'blog'); 210 break; 211 case 'public': 212 $blogtype = get_string('publishtoworld', 'blog'); 213 break; 214 default: 215 $blogtype = ''; 216 break; 217 218 } 219 220 echo '<div class="audience">'.$blogtype.'</div>'; 221 222 // Print whole message 223 echo format_text($template['body']); 224 225 /// Print attachments 226 echo $attachedimages; 227 /// Links to tags 228 229 if ( !empty($CFG->usetags) && ($blogtags = tag_get_tags_csv('post', $blogEntry->id)) ) { 230 echo '<div class="tags">'; 231 if ($blogtags) { 232 print(get_string('tags', 'tag') .': '. $blogtags); 233 } 234 echo '</div>'; 235 } 236 237 /// Commands 238 239 echo '<div class="commands">'; 240 241 if (blog_user_can_edit_post($blogEntry)) { 242 echo '<a href="'.$CFG->wwwroot.'/blog/edit.php?action=edit&id='.$blogEntry->id.'">'.$stredit.'</a>'; 243 echo '| <a href="'.$CFG->wwwroot.'/blog/edit.php?action=delete&id='.$blogEntry->id.'">'.$strdelete.'</a> | '; 244 } 245 246 echo '<a href="'.$CFG->wwwroot.'/blog/index.php?postid='.$blogEntry->id.'">'.get_string('permalink', 'blog').'</a>'; 247 248 echo '</div>'; 249 250 if( isset($template['lastmod']) ){ 251 echo '<div style="font-size: 55%;">'; 252 echo ' [ '.get_string('modified').': '.$template['lastmod'].' ]'; 253 echo '</div>'; 254 } 255 256 echo '</td></tr></table>'."\n\n"; 257 258 } 259 260 function blog_file_area_name($blogentry) { 261 // Creates a directory file name, suitable for make_upload_directory() 262 global $CFG; 263 // $CFG->dataroot/blog/attachments/xxxx/file.jpg 264 return "blog/attachments/$blogentry->id"; 265 } 266 267 function blog_file_area($blogentry) { 268 return make_upload_directory( blog_file_area_name($blogentry) ); 269 } 270 271 function blog_delete_old_attachments($post, $exception="") { 272 // Deletes all the user files in the attachments area for a post 273 // EXCEPT for any file named $exception 274 275 if ($basedir = blog_file_area($post)) { 276 if ($files = get_directory_list($basedir)) { 277 foreach ($files as $file) { 278 if ($file != $exception) { 279 unlink("$basedir/$file"); 280 notify("Existing file '$file' has been deleted!"); 281 } 282 } 283 } 284 if (!$exception) { // Delete directory as well, if empty 285 rmdir("$basedir"); 286 } 287 } 288 } 289 290 function blog_print_attachments($blogentry, $return=NULL) { 291 // if return=html, then return a html string. 292 // if return=text, then return a text-only string. 293 // otherwise, print HTML for non-images, and return image HTML 294 295 global $CFG; 296 297 $filearea = blog_file_area_name($blogentry); 298 299 $imagereturn = ""; 300 $output = ""; 301 302 if ($basedir = blog_file_area($blogentry)) { 303 if ($files = get_directory_list($basedir)) { 304 $strattachment = get_string("attachment", "forum"); 305 foreach ($files as $file) { 306 include_once($CFG->libdir.'/filelib.php'); 307 $icon = mimeinfo("icon", $file); 308 $type = mimeinfo("type", $file); 309 $ffurl = get_file_url("$filearea/$file"); 310 $image = "<img src=\"$CFG->pixpath/f/$icon\" class=\"icon\" alt=\"\" />"; 311 312 if ($return == "html") { 313 $output .= "<a href=\"$ffurl\">$image</a> "; 314 $output .= "<a href=\"$ffurl\">$file</a><br />"; 315 316 } else if ($return == "text") { 317 $output .= "$strattachment $file:\n$ffurl\n"; 318 319 } else { 320 if (in_array($type, array('image/gif', 'image/jpeg', 'image/png'))) { // Image attachments don't get printed as links 321 $imagereturn .= "<br /><img src=\"$ffurl\" alt=\"\" />"; 322 } else { 323 echo "<a href=\"$ffurl\">$image</a> "; 324 echo filter_text("<a href=\"$ffurl\">$file</a><br />"); 325 } 326 } 327 } 328 } 329 } 330 331 if ($return) { 332 return $output; 333 } 334 335 return $imagereturn; 336 } 337 338 339 /** 340 * Use this function to retrieve a list of publish states available for 341 * the currently logged in user. 342 * 343 * @return array This function returns an array ideal for sending to moodles' 344 * choose_from_menu function. 345 */ 346 function blog_applicable_publish_states($courseid='') { 347 348 global $CFG; 349 350 // everyone gets draft access 351 if ($CFG->bloglevel >= BLOG_USER_LEVEL) { 352 $options = array ( 'draft' => get_string('publishtonoone', 'blog') ); 353 } 354 355 if ($CFG->bloglevel > BLOG_USER_LEVEL) { 356 $options['site'] = get_string('publishtosite', 'blog'); 357 } 358 359 if ($CFG->bloglevel >= BLOG_GLOBAL_LEVEL) { 360 $options['public'] = get_string('publishtoworld', 'blog'); 361 } 362 363 return $options; 364 } 365 366 367 /** 368 * User can edit a blog entry if this is their own blog post and they have 369 * the capability moodle/blog:create, or if they have the capability 370 * moodle/blog:manageentries. 371 * 372 * This also applies to deleting of posts. 373 */ 374 function blog_user_can_edit_post($blogEntry) { 375 376 global $CFG, $USER; 377 378 $sitecontext = get_context_instance(CONTEXT_SYSTEM); 379 380 if (has_capability('moodle/blog:manageentries', $sitecontext)) { 381 return true; // can edit any blog post 382 } 383 384 if ($blogEntry->userid == $USER->id 385 and has_capability('moodle/blog:create', $sitecontext)) { 386 return true; // can edit own when having blog:create capability 387 } 388 389 return false; 390 } 391 392 393 /** 394 * Checks to see if a user can view the blogs of another user. 395 * Only blog level is checked here, the capabilities are enforced 396 * in blog/index.php 397 */ 398 function blog_user_can_view_user_post($targetuserid, $blogEntry=null) { 399 global $CFG, $USER; 400 401 if (empty($CFG->bloglevel)) { 402 return false; // blog system disabled 403 } 404 405 if (!empty($USER->id) and $USER->id == $targetuserid) { 406 return true; // can view own posts in any case 407 } 408 409 $sitecontext = get_context_instance(CONTEXT_SYSTEM); 410 if (has_capability('moodle/blog:manageentries', $sitecontext)) { 411 return true; // can manage all posts 412 } 413 414 // coming for 1 post, make sure it's not a draft 415 if ($blogEntry and $blogEntry->publishstate == 'draft') { 416 return false; // can not view draft of others 417 } 418 419 // coming for 1 post, make sure user is logged in, if not a public blog 420 if ($blogEntry && $blogEntry->publishstate != 'public' && !isloggedin()) { 421 return false; 422 } 423 424 switch ($CFG->bloglevel) { 425 case BLOG_GLOBAL_LEVEL: 426 return true; 427 break; 428 429 case BLOG_SITE_LEVEL: 430 if (!empty($USER->id)) { // not logged in viewers forbidden 431 return true; 432 } 433 return false; 434 break; 435 436 case BLOG_COURSE_LEVEL: 437 $mycourses = array_keys(get_my_courses($USER->id)); 438 $usercourses = array_keys(get_my_courses($targetuserid)); 439 $shared = array_intersect($mycourses, $usercourses); 440 if (!empty($shared)) { 441 return true; 442 } 443 return false; 444 break; 445 446 case BLOG_GROUP_LEVEL: 447 $mycourses = array_keys(get_my_courses($USER->id)); 448 $usercourses = array_keys(get_my_courses($targetuserid)); 449 $shared = array_intersect($mycourses, $usercourses); 450 foreach ($shared as $courseid) { 451 $course = get_record('course', 'id', $courseid); 452 $coursecontext = get_context_instance(CONTEXT_COURSE, $courseid); 453 if (has_capability('moodle/site:accessallgroups', $coursecontext) 454 or groups_get_course_groupmode($course) != SEPARATEGROUPS) { 455 return true; 456 } else { 457 if ($usergroups = groups_get_all_groups($courseid, $targetuserid)) { 458 foreach ($usergroups as $usergroup) { 459 if (groups_is_member($usergroup->id)) { 460 return true; 461 } 462 } 463 } 464 } 465 } 466 return false; 467 break; 468 469 case BLOG_USER_LEVEL: 470 default: 471 $personalcontext = get_context_instance(CONTEXT_USER, $targetuserid); 472 return has_capability('moodle/user:readuserblogs', $personalcontext); 473 break; 474 475 } 476 } 477 478 479 /** 480 * Main filter function. 481 */ 482 function blog_fetch_entries($postid='', $fetchlimit=10, $fetchstart='', $filtertype='', $filterselect='', $tagid='', $tag ='', $sort='lastmodified DESC', $limit=true) { 483 484 global $CFG, $USER; 485 486 /// the post table will be used for other things too 487 $typesql = " AND p.module = 'blog' "; 488 489 /// set the tag id for searching 490 if ($tagid) { 491 $tag = $tagid; 492 } else if ($tag) { 493 if ($tagrec = get_record_sql('SELECT * FROM '.$CFG->prefix.'tag WHERE name LIKE "'.$tag.'"')) { 494 $tag = $tagrec->id; 495 } else { 496 $tag = -1; //no records found 497 } 498 } 499 500 // If we have specified an ID 501 // Just return 1 entry 502 503 if ($postid) { 504 505 if ($post = get_record('post', 'id', $postid)) { 506 507 if (blog_user_can_view_user_post($post->userid, $post)) { 508 509 if ($user = get_record('user', 'id', $post->userid)) { 510 $post->email = $user->email; 511 $post->firstname = $user->firstname; 512 $post->lastname = $user->lastname; 513 } 514 $retarray[] = $post; 515 return $retarray; 516 } else { 517 return null; 518 } 519 520 } else { // bad postid 521 return null; 522 } 523 } 524 525 if ($tag) { 526 $tagtablesql = $CFG->prefix.'tag_instance ti, '; 527 $tagquerysql = ' AND ti.itemid = p.id AND ti.tagid = '.$tag.' AND ti.itemtype = \'post\' '; 528 } else { 529 $tagtablesql = ''; 530 $tagquerysql = ''; 531 } 532 533 if (isloggedin() && !has_capability('moodle/legacy:guest', get_context_instance(CONTEXT_SYSTEM), $USER->id, false)) { 534 $permissionsql = 'AND (p.publishstate = \'site\' OR p.publishstate = \'public\' OR p.userid = '.$USER->id.')'; 535 } else { 536 $permissionsql = 'AND p.publishstate = \'public\''; 537 } 538 539 // fix for MDL-9165, use with readuserblogs capability in a user context can read that user's private blogs 540 // admins can see all blogs regardless of publish states, as described on the help page 541 if (has_capability('moodle/user:readuserblogs', get_context_instance(CONTEXT_SYSTEM))) { 542 $permissionsql = ''; 543 } else if ($filtertype=='user' && has_capability('moodle/user:readuserblogs', get_context_instance(CONTEXT_USER, $filterselect))) { 544 $permissionsql = ''; 545 } 546 /**************************************** 547 * depending on the type, there are 4 * 548 * different possible sqls * 549 ****************************************/ 550 551 $requiredfields = 'p.*, u.firstname,u.lastname,u.email'; 552 553 if ($filtertype == 'course' && $filterselect == SITEID) { // Really a site 554 $filtertype = 'site'; 555 } 556 557 switch ($filtertype) { 558 559 case 'site': 560 561 $SQL = 'SELECT '.$requiredfields.' FROM '.$CFG->prefix.'post p, '.$tagtablesql 562 .$CFG->prefix.'user u 563 WHERE p.userid = u.id '.$tagquerysql.' 564 AND u.deleted = 0 565 '.$permissionsql.$typesql; 566 567 break; 568 569 case 'course': 570 // all users with a role assigned 571 $context = get_context_instance(CONTEXT_COURSE, $filterselect); 572 573 // MDL-10037, hidden users' blogs should not appear 574 if (has_capability('moodle/role:viewhiddenassigns', $context)) { 575 $hiddensql = ''; 576 } else { 577 $hiddensql = ' AND ra.hidden = 0 '; 578 } 579 580 $SQL = 'SELECT '.$requiredfields.' FROM '.$CFG->prefix.'post p, '.$tagtablesql 581 .$CFG->prefix.'role_assignments ra, '.$CFG->prefix.'user u 582 WHERE p.userid = ra.userid '.$tagquerysql.' 583 AND ra.contextid '.get_related_contexts_string($context).' 584 AND u.id = p.userid 585 AND u.deleted = 0 586 '.$hiddensql.$permissionsql.$typesql; 587 588 break; 589 590 case 'group': 591 592 $SQL = 'SELECT '.$requiredfields.' FROM '.$CFG->prefix.'post p, '.$tagtablesql 593 .$CFG->prefix.'groups_members gm, '.$CFG->prefix.'user u 594 WHERE p.userid = gm.userid AND u.id = p.userid '.$tagquerysql.' 595 AND gm.groupid = '.$filterselect.' 596 AND u.deleted = 0 597 '.$permissionsql.$typesql; 598 break; 599 600 case 'user': 601 602 $SQL = 'SELECT '.$requiredfields.' FROM '.$CFG->prefix.'post p, '.$tagtablesql 603 .$CFG->prefix.'user u 604 WHERE p.userid = u.id '.$tagquerysql.' 605 AND u.id = '.$filterselect.' 606 AND u.deleted = 0 607 '.$permissionsql.$typesql; 608 break; 609 } 610 611 $limitfrom = 0; 612 $limitnum = 0; 613 614 if ($fetchstart !== '' && $limit) { 615 $limitfrom = $fetchstart; 616 $limitnum = $fetchlimit; 617 } 618 619 $orderby = ' ORDER BY '. $sort .' '; 620 621 //global $db; $db->debug = true; 622 $records = get_records_sql($SQL . $orderby, $limitfrom, $limitnum); 623 //$db->debug = false; 624 625 if (empty($records)) { 626 return array(); 627 } 628 629 return $records; 630 } 631 632 633 /** 634 * get the count of viewable entries, easiest way is to count blog_fetch_entries 635 * this is used for print_paging_bar 636 * this is not ideal, but because of the UNION in the sql in blog_fetch_entries, 637 * it is hard to use count_records_sql 638 */ 639 function get_viewable_entry_count($postid='', $fetchlimit=10, 640 $fetchstart='', $filtertype='', $filterselect='', $tagid='', 641 $tag ='', $sort='lastmodified DESC') { 642 643 $blogEntries = blog_fetch_entries($postid, $fetchlimit, 644 $fetchstart, $filtertype, $filterselect, $tagid, $tag, 645 $sort='lastmodified DESC', false); 646 647 return count($blogEntries); 648 } 649 650 651 /// Find the base url from $_GET variables, for print_paging_bar 652 function get_baseurl($filtertype, $filterselect) { 653 654 $getcopy = $_GET; 655 656 unset($getcopy['blogpage']); 657 658 $strippedurl = strip_querystring(qualified_me()); 659 if(!empty($getcopy)) { 660 $first = false; 661 $querystring = ''; 662 foreach($getcopy as $var => $val) { 663 if(!$first) { 664 $first = true; 665 if ($var != 'filterselect' && $var != 'filtertype') { 666 $querystring .= '?'.$var.'='.$val; 667 $hasparam = true; 668 } else { 669 $querystring .= '?'; 670 } 671 } else { 672 if ($var != 'filterselect' && $var != 'filtertype') { 673 $querystring .= '&'.$var.'='.$val; 674 $hasparam = true; 675 } 676 } 677 } 678 if (isset($hasparam)) { 679 $querystring .= '&'; 680 } else { 681 $querystring = '?'; 682 } 683 } else { 684 $querystring = '?'; 685 } 686 687 return strip_querystring(qualified_me()) . $querystring. 'filtertype='. 688 $filtertype.'&filterselect='.$filterselect.'&'; 689 690 } 691 692 /** 693 * Returns a list of all user ids who have used blogs in the site 694 * Used in backup of site courses. 695 */ 696 function blog_get_participants() { 697 698 global $CFG; 699 700 return get_records_sql("SELECT userid as id 701 FROM {$CFG->prefix}post 702 WHERE module = 'blog' 703 AND courseid = 0"); 704 } 705 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Jan 14 11:33:29 2009 | Cross-referenced by PHPXref 0.7 |