3836845009e72fe774306a8e9e729544f713ccb5
[moodle.git] / blog / lib.php
1 <?php //$Id$
3 /**
4  * Library of functions and constants for blog
5  */
6  
7 require_once($CFG->dirroot .'/blog/class.BlogInfo.php');
8 require_once($CFG->dirroot .'/blog/class.BlogEntry.php');
9 require_once($CFG->dirroot .'/blog/class.BlogFilter.php');
10 require_once($CFG->libdir .'/blocklib.php');
11 require_once($CFG->libdir .'/pagelib.php');
12 require_once($CFG->dirroot .'/blog/blogpage.php');
14 /* 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);
21 /**
22  * Definition of blogcourse page type (blog page with course id present).
23  */
24 //not used at the moment, and may not need to be
25 define('PAGE_BLOG_COURSE_VIEW', 'blog_course-view');
27 $BLOG_YES_NO_MODES = array ( '0'  => get_string('no'),
28                              '1' => get_string('yes') );
30 //set default setting for $CFG->blog_* vars used by blog's blocks
31 //if they are not already. Otherwise errors are thrown
32 //when an attempt is made to use an empty var.
33 if (empty($SESSION->blog_editing_enabled)) {
34     $SESSION->blog_editing_enabled = false;
35 }
36 if (!(isset($CFG->blog_enable_trackback_in) )) {
37     $CFG->blog_enable_trackback_in = 0; //default is 0 == do not allow for site
38 }
39 if (!(isset($CFG->blog_enable_moderation) )) {
40     $CFG->blog_enable_moderation = 0; //default is 0 == do not enable blog moderation on this site
41 }
42 if (!(isset($CFG->blog_enable_pingback_in) )) {
43     $CFG->blog_enable_pingback_in = 0; //default is 0 == do not allow for site
44 }
45 if (!(isset($CFG->blog_enable_trackback_out) )) {
46     $CFG->blog_enable_trackback_out = 0; //default is 0 == do not allow for site
47 }
48 if (!(isset($CFG->blog_enable_pingback_out) )) {
49     $CFG->blog_enable_pingback_out = 0; //default is 0 == do not allow for site
50 }
51 if (!(isset($CFG->blog_enable_moderation) )) {
52     $CFG->blog_enable_moderation = 0; //default is 0 == do not turn on moderation for site
53 }
54 if (!(isset($CFG->blog_useweblog_rpc) )) {
55     $CFG->blog_useweblog_rpc = 0;//default is 0 == do not publish to weblogs.com
56 }
57 if (empty($CFG->blog_ratename) ) {
58     $CFG->blog_ratename = 'Rating'; //default name for entry ratings
59 }
60 if (empty($CFG->blog_default_title) ) {
61     $CFG->blog_default_title = 'Moodle Blog'; //default blog title
62 }
63 if (empty($CFG->blog_blogurl) ) {
64     $CFG->blog_blogurl = $CFG->wwwroot.'/blog/index.php';
65 }
66 if (!(isset($CFG->blog_enable_trackback) )) {
67     $CFG->blog_enable_trackback = 0;
68 }
69 if (!(isset($CFG->blog_enable_pingback) )) {
70     $CFG->blog_enable_pingback = 0;
71 }
72 if (empty($CFG->blog_default_fetch_num_entries) ) {
73     $CFG->blog_default_fetch_num_entries = 8;
74 }
76 /**
77  * blog_user_bloginfo
78  *
79  * returns a blogInfo object if the user has a blog in the acl table
80  * This function stores the currently logged in user's bloginfo object
81  * statically - do not release/unset the returned object.
82  * added by Daryl Hawes for moodle integration
83  * $userid - if no userid specified it will attempt to use the logged in user's id
84  */
85 function blog_user_bloginfo($userid='') {
86 //Daryl Hawes note: not sure that this attempt at optimization is correct
87 //    static $bloginfosingleton; //store the logged in user's bloginfo in a static var
89     if ($userid == '') {
90         global $USER;
91         if (!isset($USER) || !isset($USER->id)) {
92             return;
93         }
94         $userid = $USER->id;
95     }
96     
97 /*    if (isset($USER) && $USER->id == $uid && !empty($bloginfosingleton)) {
98         return $bloginfosingleton;
99     }*/
101     $thisbloginfo = new BlogInfo($userid);
102 /*        if (isset($USER) && $USER->id == $userid) {
103             $bloginfosingleton = $thisbloginfo;
104         }*/
105     return $thisbloginfo;
108 /**
109  * Verify that a user is logged in based on the session
110  * @return bool True if user has a valid login session
111  */
112 function blog_isLoggedIn() {
113     global $USER;
114     if (!isguest() && isset($USER) and isset($USER->id) and $USER->id) {
115         return 1;
116     }
117     return 0;
120 /**
121  * This function upgrades the blog's tables as needed.
122  * It's called from moodle/admin/index.php
123  */
124 function blog_upgrade_blog_db($continueto) {
126     global $CFG, $db;
128     require_once($CFG->dirroot.'/blog/version.php');  // Get code versions
130     if (empty($CFG->blog_version)) { // Blog has never been installed.
131         $strdatabaseupgrades = get_string('databaseupgrades');
132         print_header($strdatabaseupgrades, $strdatabaseupgrades, $strdatabaseupgrades,
133                      '', '', false, '&nbsp;', '&nbsp;');
135         $db->debug=true;
136         if (modify_database($CFG->dirroot .'/blog/db/'. $CFG->dbtype .'.sql')) {
137             $db->debug = false;
138             if (set_config('blog_version', $blog_version)) {
139                 notify(get_string('databasesuccess'), 'green');
140                 notify(get_string('databaseupgradeblog', 'blog', $blog_version));
142                 /// Added by Daryl Hawes - since blog has to be installed the first time before blog's blocks, and on first install creating default blocks when none exist is a bad idea, just reset blocks for blog index here
143                 require_once($CFG->libdir .'/pagelib.php');
144                 require_once($CFG->dirroot .'/blog/blogpage.php');                
145                 page_map_class(PAGE_BLOG_VIEW, 'page_blog');    
146                 // Now, create our page object.
147                 $page = page_create_object(PAGE_BLOG_VIEW, 0);
148                 // Add default blocks to the new page type
149                 blocks_repopulate_page($page);
150                 
151                 print_continue($continueto);
152                 exit;
153             } else {
154                 error('Upgrade of blogging system failed! (Could not update version in config table)');
155             }
156         } else {
157             error('blog tables could NOT be set up successfully!');
158         }
159     }
162     if ($blog_version > $CFG->blog_version) {       // Upgrade tables
163         $strdatabaseupgrades = get_string('databaseupgrades');
164         print_header($strdatabaseupgrades, $strdatabaseupgrades, $strdatabaseupgrades);
166         require_once($CFG->dirroot. '/blog/db/'. $CFG->dbtype .'.php');
168         $db->debug=true;
169         if (blog_upgrade($CFG->blog_version)) {
170             $db->debug=false;
171             if (set_config('blog_version', $blog_version)) {
172                 notify(get_string('databasesuccess'), 'green');
173                 notify(get_string('databaseupgradeblocks', '', $blog_version));
174                 print_continue($continueto);
175                 exit;
176             } else {
177                 error('Upgrade of blogging system failed! (Could not update version in config table)');
178             }
179         } else {
180             $db->debug=false;
181             error('Upgrade failed!  See blog/version.php');
182         }
184     } else if ($blog_version < $CFG->blog_version) {
185         notify('WARNING!!!  The blog code you are using is OLDER than the version that made these databases! ('. $version .' < '. $CFG->blog_version .')');
186     }
189 /**
190  * course_has_blog_entries
191  *   Given a course id return true if there are blog entries from any user related to that course
192  * $courseid - the id for the course
193  * Daryl Hawes note: When forum entries start using post table this function will no longer behave as expected
194  * Since non blog posts will be associated with this course. Perhaps moduleid or another field could be wrangled 
195  * into identifying the type of post?
196  */
197 function blog_course_has_blog_entries($courseid) {
198     $entries = get_records('post', 'courseid', $courseid);
199     if (! empty($entries) ) {
200         return true;
201     }
202     return false;
205 /**
206  * Output a hidden html form used by text entry pages that require preview.php's functionality
207  */
208 function blog_print_preview_form($userid=0, $categoryelement='<input type="hidden" name="categoryid[]">', $return=false) {
210     $returnstring = "\n".'<div id="prev" style="visibility:hidden;z-index:-1;position:absolute;display:none;">';
211     $returnstring .= "\n".'<form name="prev" action="preview.php" method="post" target="preview">';
212     $returnstring .= "\n".'<input type="hidden" name="etitle" />';
213     $returnstring .= "\n".'<input type="hidden" name="body" />';
214     $returnstring .= "\n".'<input type="hidden" name="extendedbody" />';
215     $returnstring .= "\n".'<input type="hidden" name="comm" />';
216     $returnstring .= "\n".'<input type="hidden" name="tem" />';
217     $returnstring .= "\n".'<input type="hidden" name="userid" value="'. $userid .'" />';
219 //    $returnstring .= '<input type="hidden" name="categoryid[]" value="'. $categoryid .'" />';
220     $returnstring .= "\n". $categoryelement;
221     $returnstring .= "\n".'<input type="hidden" name="format" />';
222     $returnstring .= "\n".'</form>';
223     $returnstring .= "\n".'</div>'."\n";
224     
225     if ($return) {
226         return $returnstring; //return the form as a string if requested
227     }
228     print $returnstring; //else just print the string and exit the function
231 /**
232  * blog_user_has_rights - returns true if user is the blog's owner or a moodle admin.
233  *
234  * @param BlogInfo blogInfo - a BlogInfo object passed by reference. This object represents the blog being accessed.
235  * @param int uid - numeric user id of the user whose rights are being tested against this blogInfo. If no uid is specified then the uid of the currently logged in user will be used.
236  */
237 function blog_user_has_rights(&$bloginfo, $uid='') {
238     global $USER;
239     if (isset($bloginfo) && isset($bloginfo->userid)) {
240         if ($uid == '') {
241             if ( isset($USER) && isset($USER->id) ) {
242                 $uid = $USER->id;
243             }
244         }        
245         if ($uid == '') {
246             //if uid is still empty then the user is not logged in
247             return false;
248         }
249         if (blog_is_blog_admin($uid) || isadmin()) {
250             return true;
251         } 
252     }
253     return false;
255   
256 /**
257  * Determines whether a user is an admin for a blog
258  * @param int $blog_userid The id of the blog being checked
259  */
260 function blog_is_blog_admin($blog_userid) {
261     global $USER;
263     //moodle admins are admins
264     if (isadmin()) {
265         return true;
266     }
267     if ( empty($USER) || !isset($USER->id) ) {
268         return false;
269     }
270     if ( empty($blog_userid)) {
271         return true;
272     }
274     // Return true if the user is an admin for this blog
275     if ($blog_userid == $USER->id) {
276         return true;
277     } else {
278         return false;
279     }
282 /**
283  * Adaptation of isediting in moodlelib.php for blog module
284  * @return bool
285  */
286 function blog_isediting() {
287     global $SESSION;
288     if (! isset($SESSION->blog_editing_enabled)) {
289         $SESSION->blog_editing_enabled = false;
290     }
291     return ($SESSION->blog_editing_enabled);
294 /**
295  * Turns a php string into a string ready for insert into an rss xml feed
296  */
297 function blog_rss_content($str) {
298     $str = superhtmlentities($str);
299     $content = "<![CDATA[$str]]>\n";
301     return $content;
304 /**
305  * function found when searching on problem of smart quotes
306  * posted at http://daynah.php-princess.net/index.php?p=94
307  */
308 function superhtmlentities($text) {
309   $entities = array(128 => 'euro', 130 => 'sbquo', 
310   131 => 'fnof', 132 => 'bdquo', 133 => 'hellip', 
311   134 => 'dagger', 135 => 'Dagger', 136 => 'circ', 
312   137 => 'permil', 138 => 'Scaron', 139 => 'lsaquo', 
313   140 => 'OElig', 145 => 'lsquo', 146 => 'rsquo', 
314   147 => 'ldquo', 148 => 'rdquo', 149 => 'bull', 
315   150 => 'ndash', 151 => 'mdash', 152 => 'tilde', 
316   153 => 'trade', 154 => 'scaron', 155 => 'rsaquo', 
317   156 => 'oelig', 159 => 'Yuml');
319   $new_text = '';
320   for($i = 0; $i < strlen($text); $i++) {
321     $num = ord($text{$i});
322     if (array_key_exists($num, $entities)) {
323         $new_text .= '&\\'.$entities[$num].';';
324     } else if ($num < 127 || $num > 159) {
325         $new_text .= $text{$i};
326     }
327   }
328   return htmlentities($new_text);
331 /**
332  * blog_get_recent_entries_byrange
333  * not in blogInfo because entries being searched 
334  * can be found in any number of blogs rather than just one.
335  *
336  * Returns specified range of entries since a given time.
337  *
338  * In using this function be aware for your where clause that the tables being 
339  * read are post (e) and blog_categories_entries (c) and the returned values
340  * will be e.*
341  *
342  * @param int $limit .
343  * @param int $start .
344  * @param string $where .
345  * @param string $orderby .
346  * @param bool $includeCategories .
347  *
348  * @return BlogEntries 
349  */
350 function blog_get_recent_entries_byrange($limit, $start, $where='', $orderby='lastmodified DESC', $includeCategories=false) {
351     global $CFG;
353 //    echo 'Debug: where clause in blog_get_recent_entries_byrange: $where<br />'; //debug
355     if ($includeCategories) {
356         $records = get_records_select('post e, '. $CFG->prefix .'blog_categories_entries c', $where, $orderby, '*', $start, $limit);
357     } else {
358         $records = get_records_select('post', $where, $orderby, '*', $start, $limit);
359     }
360 //    print_object($records); //debug
362     if (empty($records)) {
363         return array();
364     } else {
365         $blogEntries = array();
366         foreach($records as $record) {
367             $blogEntry = new BlogEntry($record);
368             //ensure that the user has rights to view this entry
369             if ($blogEntry->user_can_view() ) {
370                 $blogEntries[] = $blogEntry;
371             }
372         }
373         return $blogEntries;
374     }
377 /**
378  * returns a unix time stamp from year month and day
379  * used to get start and end dates for comparing against timestamps in databases
380  */
381 function blog_get_month_time($y, $m, $d, $firstday=true) {
383     if ( !empty($y) && !empty($m) && !empty($d)) {
384         $time = mktime(0, 0, 0, $m, $d, $y);
385     } else if ( !empty($y) && !empty($m) ) {
386         $day = blog_mk_getLastDayofMonth($m, $y);
387         if ($firstday) {
388             $day = 1;
389         }
390         $time = mktime(0, 0, 0, $m, $day, $y);
391     } else {
392         $time = '';
393     }
394     return $time;
397 /**
398  * attempting to create a method useful for a popup form on the index
399  * page that will allow a user to filter entries based upon date
400  *
401  * This function will return a list, in order, formatted as "MM-YYYY" for each year and month
402  * in which this blog has entries.
403  * @param BlogFilter $blogFilter - a BlogFilter object with the current filter settings for this page
404  */
405 function blog_get_year_month_of_viewable_entries(&$blogFilter) {
406     global $_SERVER;
407     
408     $entries = $blogFilter->get_filtered_entries();
409     $datearray = array();
410     $datearray['m=&amp;y='] = 'All Dates';
411     
412     if ( !empty($entries) ) {
413         foreach ($entries as $entry) {
414             if ( $entry->user_can_view() ) {
415 //                print_object($entry); //debug
416                 //user is allowed to see this entry, so return its year/month information
417                 $date = $entry->entryLastModified;
418                 $truncDate = date("F Y", $date); // this will return January 2004 for the date.
419                 $curmonth = date("m", $date); // this will return January 2004 for the date.
420                 $curyear = date("Y", $date); // this will return January 2004 for the date.
421                 $index = 'm='. $curmonth .'&amp;y='. $curyear;
422                 $datearray[$index] = $truncDate;
423             }
424         }
425     }
426 //    print_object($datearray); //debug
427         
428     if (is_numeric($blogFilter->startmonth) && is_numeric($blogFilter->startyear)) {
429         $selected = 'm='. $blogFilter->startmonth .'&amp;y='. $blogFilter->startyear;
430     } else {
431         $selected = '';
432     }
433     $unused = array('startmonth', 'startyear');
434     $getvars = $blogFilter->get_getvars($unused);
435     //attach a random number to the popup function's form name
436     //becuase there may be multiple instances of this form on each page
437     $self = basename($_SERVER['PHP_SELF']); 
438     $form = popup_form($self . $getvars .'&amp;', $datearray, 'blog_date_selection'. mt_rand(), $selected, '', '', '', true);
439     return str_replace('<form', '<form style="display: inline;"', $form);
442 /**
443  * pretty close to a direct copy of calendar/view.php calendar_course_filter_selector function
444  */
445 function blog_course_filter_selector(&$blogFilter) {
446     global $USER, $_SERVER;
447     
448     $getvars = $blogFilter->get_getvars('courseid');
450     if ( !isset($USER) || !isset($USER->id) ) {
451         return;
452     }
454     if (isguest($USER->id)) {
455         return '';
456     }
457     
458     if (isadmin($USER->id)) {
459         $courses = get_courses('all', 'c.shortname');
460         
461     } else {
462         $courses = get_my_courses($USER->id, 'shortname');
463     }
464     
465     unset($courses[1]);
466     
467     $courseoptions[1] = get_string('fulllistofcourses');
468     foreach ($courses as $course) {
469         // Verify that there are actually blog entries for this course before showing it as a selection.
470         if ($entries = count_records('post', 'courseid', $course->id)) {
471             $courseoptions[$course->id] = $course->shortname;
472         }
473     }
475     //if there were no courses added then simply return
476     if (count($courseoptions) == 1) {
477         return;
478     }
479     
480     if (is_numeric($blogFilter->courseid)) {
481         $selected = $blogFilter->courseid;
482     } else {
483         $selected = '';
484     }
485     //attach a random number to the popup function's form name
486     //because there may be multiple instances of this form on each page
487     $self = basename($_SERVER['PHP_SELF']); 
488     $form = popup_form($self . $getvars .'&amp;courseid=',
489                        $courseoptions, 'blog_course_selection'. mt_rand(), $selected, '', '', '', true);
490     
491     return str_replace('<form', '<form style="display: inline;"', $form);
494 /**
495  * build and return list of all member blogs
496  *
497  * @param stdObject $memberrecords An object of record entries as output from the get_member_list() function in BlogFilter (->id, ->title are the required variables).
498  * @param int $format - 0, 1 or 2; 0 = hyperlinked list of members, 1 = select element, 2 = select element wrapped in entire form
499  * @param bool $return  indicates whether the function should return the text 
500  *   as a string or echo it directly to the page being rendered
501  * @param BlogFilter $blogFilter - a BlogFilter object with the details of the members listed in $memberrecords.
502  * @param string $hyperlink This is the target link to be used - there is a sensible default for each format.
503  */
504 function blog_member_list(&$blogFilter, &$memberrecords, $format=1, $return=true, $hyperlink='') {
505     global $CFG, $USER;
506     
507 //echo "userid = $blogFilter->userid"; //debug
508 //print_object($memberrecords); //debug
509     $returnstring = '';
510     if (!empty($memberrecords)) {
511         switch($format) {
512             case '0':
513                 foreach($memberrecords as $record) {
514                     if (empty($hyperlink)) {
515                         $CFG->wwwroot .'/blog/index.php?userid='. $record->id;  
516                     }
517                     $returnstring .= '<a href="'. $hyperlink . $record->id .'">'. stripslashes_safe($record->title) .'</a><br />';      
518                 }
519                 break;
520             case '2':
521                 $selected = '';
522                 $options = array('' => 'All Member Blogs');
523                 $formlink = $hyperlink; //TESTING
524                 if (empty($hyperlink)) {
525                     $getvars = $blogFilter->get_getvars('userid');
526                     $self = basename($_SERVER['PHP_SELF']); 
527                     $formlink = $self . $getvars .'&amp;userid=';
528                 }                    
529                 foreach($memberrecords as $record) {
530                     $id = $record->id;
531                     if (blog_isLoggedIn() && $id == $USER->id ) {
532                         $optiontitle = 'My Blog';
533                     } else {
534                         $optiontitle = stripslashes_safe($record->title);
535                     }
536                     $options[$id] = $optiontitle; //TESTING
537                     if ( ($blogFilter->userid == $record->id) && ($blogFilter->userid != 0) ) {
538                         $selected = $id;
539                     }
540                 }
541                 
542                 //attach a random number to the popup function's form name
543                 //becuase there may be multiple instances of this form on each page
544                 $returnstring = popup_form($formlink,
545                        $options, 'blog_member_list'. mt_rand(), $selected, '', '', '', true);
546                 $returnstring = str_replace('<form', '<form style="display: inline;"', $returnstring);
547                 break;
548             
549             case '1':
550             default:
551                 $returnstring = '<select name="userid">';
552                 foreach($memberrecords as $record) {            
553                     $returnstring .= '<option value="'. $record->id .'"';
554                     if ( ($record->id == $blogFilter->userid) && ($blogFilter->userid != 0) ) {
555                         $returnstring .= ' selected';
556                     }
557                     $returnstring .= '>'. stripslashes_safe($record->title) .'</option>';
558                 }
559                 $returnstring .= '</select>';
560                 break;
561         }
562     
563     }
564     if ($return) {
565         return $returnstring;
566     }
567     print $returnstring;
568     return;
571 /**
572  * @param int courseid the selected course in popup
573  */
574 function blog_get_course_selection_popup($courseid='') {
575     global $USER;
576     if ( !isset($USER) || !isset($USER->id) ) {
577         return;
578     }
579     if ( isadmin() ) {
580         $courses = get_courses(); //show admin users all courses
581     } else {
582         $courses = get_my_courses($USER->id) ; //get_my_courses is in datalib.php
583     }
584     //print_object($courses); //debug
585     $courseoptions = array();
586     foreach ($courses as $course) {
587         $courseoptions[$course->id] = $course->shortname;
588     }
589     return choose_from_menu($courseoptions, 'course_selection', $courseid, '', '', '0', true);
592 /**
593  *  This function is in lib and not in BlogInfo because entries being searched
594  *   might be found in any number of blogs rather than just one.
595  *
596  *   $@param BlogFilter blogFilter - a BlogFilter object containing the settings for finding appropriate entries for display
597  */
598 function blog_print_html_formatted_entries(&$blogFilter, $filtertype, $filterselect) {
599     global $CFG, $USER;
600     $blogpage = optional_param('blogpage', 0, PARAM_INT);
601     $bloglimit = get_user_preferences('blogpagesize',8); // expose as user pref when MyMoodle comes around
603     // First let's see if the batchpublish form has submitted data
604     $post = data_submitted();
605     if (!empty($post->batchpublish)) { //make sure we're processing the edit form here
606 //        print_object($post); //debug
607         foreach ($post as $key => $publishto) {
608             if ($key != 'batchpublish') {
609                 $useridandentryid = explode('-', $key);
610                 $userid = $useridandentryid[0];
611                 $entryid = $useridandentryid[1];
612                 $bloginfo = new BlogInfo($userid);
613                 $blogentry = $bloginfo->get_blog_entry_by_id($entryid);
614                 if ($blogentry->entryPublishState != $publishto) {
615                     if (!$blogentry->set_publishstate($publishto)) {
616                         echo 'Entry "'. $blogentry->entryTitle .'" could not be published.';
617                     } else {
618                         if ($error = $blogentry->save()) {
619                             echo 'New publish setting for entry "'. $blogentry->entryTitle .'" could not be saved. ERROR:'. $error.':<br />';
620                         }
621                     }
622                 }
623             }
624         }
625     }
628     $morelink = '<br />&nbsp;&nbsp;';
629     // show personal or general heading block as applicable
630     echo '<div class="headingblock header blog">';
631     //show blog title - blog tagline
632     print "<br />";    //don't print title. blog_get_title_text();
634     if ($blogpage != 0) {
635         // modify the blog filter to fetch the entries we care about right now
636         $oldstart = $blogFilter->fetchstart;
637         $blogFilter->fetchstart = $blogpage * $bloglimit;
638         unset($blogFilter->filtered_entries);
639     }
640     $blogEntries = $blogFilter->get_filtered_entries();
641     // show page next/previous links if applicable
642     print_paging_bar($blogFilter->get_viewable_entry_count(), $blogpage, $bloglimit, $blogFilter->baseurl, 'blogpage');
643     print '</div>';
644     if (isset($blogEntries) ) {
646         if (blog_isLoggedIn() && blog_isediting() ) {
647             print '<form name="batchpublishform" method="post" action="'. $blogFilter->baseurl .'" id="batchpublishform" enctype="multipart/form-data">';
648         }
650         $count = 0;
651         foreach ($blogEntries as $blogEntry) {
652             blog_print_entry($blogEntry, 'list', $filtertype, $filterselect); //print this entry.
653             $count++;
654         }
655         if (!$count) {
656             print '<br /><center>'. get_string('noentriesyet', 'blog') .'</center><br />';
658             if (blog_isLoggedIn()) {
659                 $morelink = '<br />&nbsp;&nbsp;';
660                 $morelink .= $blogFilter->get_complete_link('<a href="'. $CFG->wwwroot .'/blog/edit.php', get_string('addnewentry', 'blog'))."\n";
661                 
662             }
663         }
664 /*
665         if (blog_isLoggedIn() && blog_isediting() ) {
666             //Daryl Hawes note: localize this submit button!
667             print '<div align="center"><input type="submit" value="Save these publish settings" id="batchpublish" name="batchpublish" /></div>'."\n";
668             print '</form>'."\n";
669         }
670 */
671         //yu: testing code
672         if (blog_isLoggedIn()) {
673         //the user's blog is enabled and they are viewing their own blog
674             $morelink .= $blogFilter->get_complete_link($CFG->wwwroot .'/blog/edit.php', get_string('addnewentry', 'blog'));
675         }
677         print $morelink.'<br />'."\n";
679         if ($blogpage != 0) {
680             //put the blogFilter back the way we found it
681             $blogFilter->fetchstart = $oldstart;
682             unset($blogFilter->filtered_entries);
683             $blogFilter->fetch_entries();
684         }
686         return;
687     }
689     $output = '<br /><center>'. get_string('noentriesyet', 'blog') .'</center><br />';
690     $userbloginfo = blog_user_bloginfo();
691     
692     if (blog_isLoggedIn()) {
693         //the user's blog is enabled and they are viewing their own blog
694         $output .= $blogFilter->get_complete_link($CFG->wwwroot .'/blog/edit.php', get_string('addnewentry', 'blog'));
695     }
696     print $output;
697     unset($blogFilter->filtered_entries);
700 /**
701  * What text should be displayed claiming ownership to the current blog entries?
702  * @uses $PAGE
703  * @return string
704  */
705 function blog_get_title_text() {
706     global $PAGE; //hackish
708     if (isset($PAGE) && isset($PAGE->bloginfo)) {
709         $blogInfo = &$PAGE->bloginfo;
710         $title = $blogInfo->get_blog_title();
711         if($title != '') {
712             $displaytitle = $title;
713             $tagline = $blogInfo->get_blog_tagline();
714             if ($tagline != '') {
715                 $displaytitle .= ' - '. $tagline;
716             }
717         }
718     }
719     if (isset($displaytitle)) {
720         return $displaytitle;
721     } else {
722         // Daryl Hawes - better wording would be good here, localize this line once the wording is selected.
723         return 'Combined Blog '. get_string('entries', 'blog') .'<br />';
724     }
727 /**
728  * blog_get_moodle_pix_path
729  *
730  * Returns the directory path to the current theme's pix folder.
731  * @return string
732  */
733 function blog_get_moodle_pix_path(){
734     global $CFG, $THEME;
735     if (empty($THEME->custompix)) {
736         return $CFG->wwwroot.'/pix';
737     } else {
738         return $CFG->themedir.current_theme().'/pix';
739     }
742 /**
743  *  This function is in lib and not in BlogInfo because entries being searched
744  *   might be found in any number of blogs rather than just one.
745  *
746  * This function builds an array which can be used by the included
747  * template file, making predefined and nicely formatted variables available
748  * to the template. Template creators will not need to become intimate
749  * with the internal objects and vars of moodle blog nor will they need to worry
750  * about properly formatting their data
751  *
752  *   @param BlogEntry blogEntry - a hopefully fully populated BlogEntry object
753  *   @param string viewtype Default is 'full'. If 'full' then display this blog entry
754  *     in its complete form (eg. archive page). If anything other than 'full'
755  *     display the entry in its abbreviated format (eg. index page)
756  */
757 function blog_print_entry(&$blogEntry, $viewtype='full', $filtertype, $filterselect) {
758     global $CFG, $THEME, $USER;
759     static $bloginfoarray;
761     if (isset($bloginfoarray) && $bloginfocache[$blogEntry->entryuserid]) {
762         $bloginfo = $bloginfocache[$blogEntry->entryuserid];
763     } else {
764         $bloginfocache[$blogEntry->entryuserid] = new BlogInfo($blogEntry->entryuserid);
765         $bloginfo = $bloginfocache[$blogEntry->entryuserid];
766     }
768     $template['blogtitle'] = $bloginfo->blogtitle;
769     $template['blogtagline'] = $bloginfo->blogtagline;
770     $template['blogurl'] = $bloginfo->get_blogurl();
771     
772     $template['body'] = $blogEntry->get_formatted_entry_body();
773     $template['countofextendedbody'] = 0;
774     
775     if ($template['extendedbody'] = $blogEntry->get_formatted_entry_extended_body()) {
776         $template['extendedbody'] = $blogEntry->get_formatted_entry_extended_body();
777         $template['countofextendedbody'] = count_words($template->extendedbody);
778     } else {
779         $template['extendedbody'] = '';
780     }
781     
782     if ($viewtype=='full' && !empty($template['extendedbody'])) {
783         $template['body'] .= '<hr width="80%" />' . $template['extendedbody'];
784     } else if ( !empty($template->extendedbody) && $template->countofextendedbody != 0) {
785         $template['body'] .= '<br />&nbsp;&nbsp;&nbsp;<a href="'. $blogEntry->get_entryurl() .'">'. get_string('moreelipses', 'blog') .' ('. $template['countofextendedbody'] .' words)</a>';
786     }
788     $template['title'] = '<a name="'. $blogEntry->entryId .'"></a>';
789     //enclose the title in nolink tags so that moodle formatting doesn't autolink the text
790     $template['title'] .= '<span class="nolink">'. stripslashes_safe($blogEntry->entryTitle);
791     $template['title'] .= '</span>';
793     // add editing controls if allowed
794     $template['editbuttons'] = $blogEntry->get_formatted_edit_URL(true);
795     $template['editbuttons'] .= $blogEntry->get_formatted_delete_URL(true);
796     $template['courseid'] = $blogEntry->entryCourseId;
797     $template['userid'] = $blogEntry->entryuserid;
798     $template['authorviewurl'] = $CFG->wwwroot .'/user/view.php?course=1&amp;id='. $template['userid'];
799     $template['moodlepix'] = blog_get_moodle_pix_path();
800     $template['author'] = $blogEntry->entryAuthorName;
801     $template['lastmod'] = $blogEntry->formattedEntryLastModified;
802     $template['created'] = $blogEntry->formattedEntryCreated;
803     $template['publishtomenu'] = $blogEntry->get_publish_to_menu(true, true);
804     $template['groupid'] = $blogEntry->entryGroupId;
805     //forum style printing of blogs
806     blog_print_entry_content ($template, $blogEntry->entryId, $filtertype, $filterselect);
810 //forum style printing of blogs
811 function blog_print_entry_content ($template, $entryid, $filtertype='', $filterselect='') {
812     global $USER, $CFG, $course, $ME;
814     $stredit = get_string('edit');
815     $strdelete = get_string('delete');
817     $user = get_record('user','id',$template['userid']);
819     echo '<div align="center"><table cellspacing="0" class="forumpost" width="100%">';
821     echo '<tr class="header"><td class="picture left">';
822     print_user_picture($template['userid'], $template['courseid'], $user->picture);
823     echo '</td>';
825     echo '<td class="topic starter"><div class="subject">'.$template['title'].'</div><div class="author">';
826     $fullname = fullname($user, isteacher($template['userid']));
827     $by->name =  '<a href="'.$CFG->wwwroot.'/user/view.php?id='.
828                 $user->id.'&amp;course='.$course->id.'">'.$fullname.'</a>';
829     $by->date = $template['lastmod'];
830     print_string('bynameondate', 'forum', $by);
831     echo '</div></td></tr>';
833     echo '<tr><td class="left side">';
834     if ($group = get_record('groups','id',$template['groupid'])) {
835         print_group_picture($group, $course->id, false, false, true);
836     } else {
837         echo '&nbsp;';
838     }
840 /// Actual content
842     echo '</td><td class="content">'."\n";
844     // Print whole message
845     echo format_text($template['body']);
847 /// Links to tags
849     if ($blogtags = get_records_sql('SELECT t.* FROM '.$CFG->prefix.'tags t, '.$CFG->prefix.'blog_tag_instance ti
850                                  WHERE t.id = ti.tagid
851                                  AND ti.entryid = '.$entryid)) {
852         echo '<p />';
853         print_string('tags');
854         echo ': ';
855         foreach ($blogtags as $blogtag) {
856             echo '<a href="index.php?courseid='.$course->id.'&amp;filtertype='.$filtertype.'&amp;filterselect='.$filterselect.'&amp;tagid='.$blogtag->id.'">'.$blogtag->text.'</a>, ';
857         }
858     }
859     
860 /// Commands
862     echo '<div class="commands">';
864     if (isset($USER->id)) {
865         if (($template['userid'] == $USER->id) or isteacher($course->id)) {
866                 echo '<a href="'.$CFG->wwwroot.'/blog/edit.php?editid='.$entryid.'">'.$stredit.'</a>';
867         }
869         if (($template['userid'] == $USER->id) or isteacher($course->id)) {
870             echo '| <a href="'.$CFG->wwwroot.'/blog/edit.php?act=del&amp;postid='.$entryid.'">'.$strdelete.'</a>';
871         }
872     }
874     echo '</div>';
876     echo '</td></tr></table></div>'."\n\n";
879 /**
880  * Use this function to retrieve a list of publish states available for 
881  * the currently logged in user.
882  *
883  * @return array This function returns an array ideal for sending to moodles'
884  *                choose_from_menu function.
885  */
886 function blog_applicable_publish_states($courseid='') {
887     global $CFG;
888     
889     // everyone gets draft access
890     $options = array ( 'draft' => get_string('publishtonoone', 'blog') );
891     if (is_numeric($courseid) && $courseid != SITEID && $course = get_record('course', 'id', $courseid, '', '', '', '', 'shortname') ) {
892         require_login($courseid);
893         // if we're viewing a course allow publishing to course teachers
894         $options['teacher'] = get_string('publishtoteachers', 'blog', $course->shortname);
895         if (!$CFG->blog_enable_moderation || isadmin() || isteacher($courseid) ) {
896             // only admins and teachers can publish to course members when moderation is enabled
897             $options['course'] = get_string('publishtocourse', 'blog', $course->shortname);
898         }
899     }
900     /*
901      //groups not supported quite yet - pseudocode:
902      if (isset($post->groupid) && $post->groupid != '') {
903          $options['group'] = 'Fellow group members and teachers can view';
904      }*/
905     if (!$CFG->blog_enable_moderation || isadmin() || (is_numeric($courseid) && isteacher($courseid)) ) {
906         // only admins and teachers can see site and public options when moderation is enabled
907         $options['site'] = get_string('publishtosite', 'blog');
908         $options['public'] = get_string('publishtoworld', 'blog');
909     }
910     return $options;
913 /**
914  * blog_get_entries_by_category - not in blogInfo because entries being searched 
915  *   can be found in any number of blogs rather than just one.
916  * catids can be an array of category ids or a single category id
917  * defined as either
918  * $catids = array(1, 2, 3, 4, 5);
919  * or
920  * $catids = 2;
921  *
922  * Used by rss.php
923  */
924 function blog_get_entries_by_category($catids, $courseid=0, $limit=8, $start=0) {
925     $catsearch = ' e.id=c.entryid AND '; //only gets categories whose postid matches entries retrieved
926     if (blog_array_count($catids) > 0) {
927         $count = 0;
928         foreach ($catids as $catid) {
929             $catsearch .= 'c.categoryid='. $catid .' ';
930             $count += 1;
931             if (count($catids) != $count) {
932                 $catsearch .= 'OR ';
933             }
934         } 
935     } else {
936         $catsearch .= 'c.categoryid='. $catids;
937     }
938     $wherecourse = '';
939     if (is_numeric($courseid) && $courseid != 0 && $courseid != 1) {
940         $wherecourse = ' AND e.courseid='. $courseid;
941     }
942     $where = $catsearch.$wherecourse;
943 //    echo 'Debug: where clause for blog_get_entries_by_category: '. $where; //debug
944     return blog_get_recent_entries_byrange($limit, $start, $where, '', true);
947 /**
948  * builds calendar with links to filter entries by date
949  * modified by Daryl Hawes to build links even when no userid is specified
950  * and to return the html as a string if desired
951  */
952 function blog_draw_calendar(&$blogFilter, $return=false)
954     global $CFG;
955 //    print_object($blogFilter);
957     if (!empty($blogFilter->startmonth)) {
958         $m = $blogFilter->startmonth;
959     } else {
960         $m = date('n', mktime());
961         $blogFilter->startmonth = $m;
962     }
963     if (!empty($blogFilter->startyear)) {
964         $y = $blogFilter->startyear;
965     } else {
966         $y = date('Y', mktime());
967         $blogFilter->startyear = $y;
968     }
969     $userid = $blogFilter->userid;
970     
971     //create a string to represent a URL argument with userid info. If no userid then string is empty.
972     $useridString = '&amp;userid='. $userid;
973     if ($userid == 0 || $userid == '') {
974         $useridString = '';
975     }
977    // calculate the weekday the first of the month is on
978    $tmpd = getdate(mktime(0, 0, 0, $m, 1, $y));
979    $monthname = $tmpd['month'];
980    $firstwday= $tmpd['wday'];
981    $today = date('Ymd', mktime());
983    $lastday = blog_mk_getLastDayofMonth($m, $y);
985    //determine next and previous month
986    if (($m - 1) < 1) { $pm = 12; } else { $pm = $m - 1; }
987    if (($m + 1) > 12) { $nm = 1; } else { $nm = $m + 1; }
989    if (strlen($pm) == 1) { $pm = '0'. $pm; };
990    if (strlen($nm) == 1) { $nm = '0'. $nm; };
992    $returnstring = "\n".'<table class="generaltable"><tr>'."\n";
993    $returnstring .= '<td style="text-align: left; width: 12%;">'."\n";
995    $currentyear = $y;
996    $currentmonth = $m;
998    if (($m - 1) < 1) {
999        $blogFilter->startyear = $y - 1;
1000    } else {
1001        $blogFilter->startyear = $y;
1002    }
1004    $blogFilter->startmonth = $pm;
1005    $self = basename($_SERVER['PHP_SELF']); 
1006    $returnstring .= $blogFilter->get_complete_link( $self, '&lt;&lt;' , array('startday'))."\n";
1008    $blogFilter->startyear = $currentyear;
1009    $blogFilter->startmonth = $currentmonth;
1011    $returnstring .= '</td><td style="text-align: center;">'."\n";
1012 //   $returnstring .= $blogFilter->get_complete_link($CFG->wwwroot .'/blog/archive.php', $monthname .' '. $y, array('startday'));
1013    $returnstring .= $blogFilter->get_complete_link($self, $monthname .' '. $y, array('startday'));
1015    if (($m + 1) > 12) {
1016        $blogFilter->startyear = $blogFilter->startyear + 1;
1017    } else {
1018         $blogFilter->startyear = $y;
1019    }
1021    $blogFilter->startmonth = $nm;
1022    $returnstring .= '</td><td style="text-align: right; width: 12%;">'."\n";
1023    $returnstring .= $blogFilter->get_complete_link( $self, '&gt;&gt;', array('startday'))."\n";
1024    $returnstring .= '</td></tr>'."\n";
1026    $blogFilter->startyear = $currentyear;
1027    $blogFilter->startmonth = $currentmonth;
1029    $returnstring .= '<tr><td colspan="3">'."\n";
1030    $returnstring .= '<table class="calendarmini"><thead>'."\n";
1031    $returnstring .= '<tr><td width="19" align="center" class="calday">'. get_string('calsun', 'blog') .'</td>'."\n";
1032    $returnstring .= '<td width="19" align="center" class="calday">'. get_string('calmon', 'blog') .'</td>'."\n";
1033    $returnstring .= '<td width="19" align="center" class="calday">'. get_string('caltue', 'blog') .'</td>'."\n";
1034    $returnstring .= '<td width="19" align="center" class="calday">'. get_string('calwed', 'blog') .'</td>'."\n";
1035     $returnstring .= '<td width="19" align="center" class="calday">'. get_string('calthu', 'blog') .'</td>'."\n";
1036     $returnstring .= '<td width="19" align="center" class="calday">'. get_string('calfri', 'blog') .'</td>'."\n";
1037     $returnstring .= '<td width="19" align="center" class="calday">'. get_string('calsat', 'blog') .'</td></tr></thead><tbody>'."\n";
1039     $d = 1;
1040     $wday = $firstwday;
1041     $firstweek = true;
1043     // loop through all the days of the month
1044     while ( $d <= $lastday)
1045     {
1046         // set up blank days for first week
1047         if ($firstweek) {
1048         $returnstring .= '<tr>'."\n";
1049         for ($i=1; $i <= $firstwday; $i++) {
1050             $returnstring .= '<td>&nbsp;</td>'."\n";
1051         }
1052         $firstweek = false;
1053         }
1055        // Sunday start week with <tr>
1056        if ($wday==0) {
1057            $returnstring .= '<tr>'."\n";
1058         }
1060        $mo = $m;
1061        if ($mo < 10) {
1062            if (!preg_match("/0\d/", $mo)) {
1063                 $mo = '0'. $mo;
1064            }
1065        }
1067         // Look for blog entries for this day
1068        $tstart = blog_get_month_time($y, $m, $d, true);
1069        $tend = blog_get_month_time($y, $m, $d + 1, false);
1070        $where = " lastmodified >= $tstart AND lastmodified <= $tend ";
1072         if ($userid != 0 && $userid != '') {
1073             $where .= ' AND author = '. $userid .' ';
1074         }
1076       $count = count_records_select('post', $where);
1078 //echo 'Where clause: '. $where .' | count:'. $count. '<br />'."\n"; //debug
1079         $da = $d;
1080         if($da < 10) {
1081             if(!preg_match("/0\d/", $da)) {
1082                 $da = "0". $da;
1083             }
1084         }        
1085       // check for event
1086       $showdate = $y . $mo . $da;
1088       $returnstring .= '<td align=center';
1089       if ($showdate == $today) {
1090            $returnstring .= ' class="cal_today"';
1091       }
1092       if ($wday == 6 || $wday == 0) { 
1093           $returnstring .= ' class="cal_weekend"';
1094       }
1095       $returnstring .= '>'."\n";
1097       // if entries are found, output link to that day's entries
1098       if ($count > 0) {
1099           $blogFilter->startday = $d;
1100           $returnstring .= $blogFilter->get_complete_link($CFG->wwwroot .'/blog/index.php', $d);
1101       } else {
1102            $returnstring .= $d."\n";
1103       }
1104       $returnstring .= '</td>'."\n";
1106       // Saturday end week with </tr>
1107       if ($wday == 6) { 
1108           $returnstring .= '</tr>'."\n"; 
1109       }
1110  
1111       $wday++;
1112       $wday = $wday % 7;
1113       $d++;
1114     }
1116     if ($wday != 0) {
1117         for($i = $wday; $i < 7; $i++) {
1118             $returnstring .= '<td>&nbsp;</td>'."\n";
1119         }
1120         $returnstring .= '</tr>'."\n";
1121     }
1122     
1123     $returnstring .= '</table>'."\n";
1125     $returnstring .= '</td></tr></tbody></table>'."\n";
1127     if ($return) {
1128         return $returnstring;
1129     }
1130     print $returnstring;
1131 // end blog_draw_calendar function
1134 /**
1135  * get the last day of the month
1136  */
1137 function blog_mk_getLastDayofMonth($mon, $year)
1139     for ($tday=28; $tday <= 31; $tday++)
1140     {
1141         $tdate = getdate(mktime(0, 0, 0, $mon, $tday, $year));
1142         if ($tdate['mon'] != $mon)
1143             { break; }
1145     }
1146     $tday--;
1148     return $tday;
1151 /**
1152  * blog_safeHTML
1153  *   Clean up user input (currently unused, moodle's format_text() is preferable)
1154  */
1155 function blog_safeHTML($html, $tags = 'b|br|i|u|ul|ol|li|p|a|blockquote|em|strong') {
1156 // removes all tags that are considered unsafe
1157 // Adapted from a function posted in the comments about the strip_tags()
1158 // function on the php.net web site.
1159 //
1160 // This function is not perfect! It can be bypassed!
1161 // Remove any nulls from the input
1162     $html = preg_replace('/\0/', '', $html);
1163  
1164     // convert the ampersands to null characters (to save for later)
1165     $html = preg_replace('/&/', '\0', $html);
1166   
1167     // convert the sharp brackets to their html code and escape special characters such as "
1168     $html=htmlspecialchars($html);
1169    
1170     // restore the tags that are considered safe
1171     if ($tags) {
1172         // Fix start tags
1173         $html = preg_replace("/&lt;(($tags).*?)&gt;/i", '<$1>', $html);
1174         // Fix end tags
1175         $html = preg_replace("/&lt;\/($tags)&gt;/i", '</$1>', $html);
1176         // Fix quotes
1177         $html = preg_replace("/&quot;/", '"', $html);
1178         $html = addslashes($html);
1179         // Don't allow, e.g. <a href="javascript:evil_code">
1180         $html = preg_replace("/<($tags)([^>]*)>/ie", "'<$1' . stripslashes_safe(str_replace('javascript', 'hackerscript', '$2')) .'>'", $html);
1181         // Don't allow, e.g. <img src="foo.gif" onmouseover="evil_javascript">
1182         $html = preg_replace("/<($tags)([^>]*)>/ie", "'<$1' . stripslashes_safe(str_replace(' on', ' off', '$2')) .'>'", $html);
1183         $html = stripslashes_safe($html);
1184                                                                             
1185     }
1186                                                                                                      
1187     // restore the ampersands
1188     $html = preg_replace('/\0/', '&', $html);
1189           
1190     return($html);
1191 } // safeHTML
1193 // I don't like how the PHP count() function returns 1 if
1194 // you pass it a scalar. So this is my custom function that
1195 // will return 0 if the argument isn't an array.
1196 function blog_array_count($arr) {
1197     if (!is_array($arr)) {
1198         return 0;
1199     }
1200     
1201     return count($arr);
1204 /**
1205 * check_dir_exists
1206  *   Function to check if a directory exists
1207  *    and, optionally, create it
1208  *    copied from moodle/backup/lib.php
1209  */
1210 if (! function_exists('check_dir_exists')) {
1211     function check_dir_exists($dir, $create=false) {
1212         
1213         global $CFG; 
1214         
1215         $status = true;
1216         if (!is_dir($dir)) {
1217             if (!$create) {
1218                 $status = false;
1219             } else {
1220                 umask(0000);
1221                 $status = mkdir ($dir, $CFG->directorypermissions);
1222             }
1223         }
1224         return $status;
1225     }
1228 /////////////// Time and Date display functions ///////////////
1230 /*
1231  * Returns the current time as a readable date string
1232  * using moodle's chosen full date display format from admin configuration.
1233  */
1234 function blog_now() {
1235     $strftimedaydatetime = get_string('strftimedaydatetime');
1236     $date = userdate(time(), $strftimedaydatetime);
1237     return $date;
1240 /**
1241 * UNIX timestamp to a readable format.
1242  * using moodle's chosen date format from admin configuration.
1243  */
1244 function blog_format_date($datetime) {
1245     $strftimedate = get_string('strftimedate');
1246     $date = userdate($datetime, $strftimedate);
1247     return $date;
1250 /**
1251 * converts unix timestamp to just a date
1252  * using moodle's chosen short date format from admin configuration.
1253  */
1254 function blog_short_date($datetime) {
1255     $strftimedateshort = get_string('strftimedateshort');
1256     $date = userdate($datetime, $strftimedateshort);
1257     return $date;     
1260 /**
1261 * converts unix timestamp to just a date
1262  * using moodle's chosen time format from admin configuration.
1263  */
1264 function blog_short_time($datetime) {
1265     $strftimetime = get_string('strftimetime');
1266     $time = userdate($datetime, $strftimedateshort);
1267     return $time;
1270 /////////////// Trackback functions ///////////////
1272 // Note: trackback specification
1273 // http://www.movabletype.org/docs/mttrackback.html
1276 /**
1277  * generate rdf for trackback autodiscovery
1278  */
1279 function blog_get_trackback_rdf_string($blogEntry) {
1280     
1281     global $CFG;
1282     $userid = $blogEntry->entryuserid;
1283     $entryid = $blogEntry->entryId;
1284     $blogInfo = new BlogInfo($userid);
1285     
1286 //    echo 'in blog_get_trackback_rdf_string blogEntry:<br />'."\n"; //debug
1287 //    print_object($blogEntry); //debug
1288     
1289     $rdf = "\n".'<!-- //RDF for trackback autodiscovery
1290 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
1291          xmlns:dc="http://purl.org/dc/elements/1.1/"
1292          xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
1293 <rdf:Description
1294     rdf:about="'. htmlentities($CFG->wwwroot .'/blog/archive.php?userid='. $userid .'&amp;postid='. $entryid) .'"
1295     dc:identifier="'. htmlentities($CFG->wwwroot .'/blog/archive.php?userid='. $userid .'&amp;postid='. $entryid) .'"
1296     dc:title="'. $blogInfo->blogtitle .'" 
1297     trackback:ping="';
1298     if ($CFG->slasharguments) {
1299                 $rdf .= $CFG->wwwroot .'/blog/tb.php/'. $entryid;
1300     } else {
1301         $rdf .= $CFG->wwwroot .'/blog/tb.php?file=/'. $entryid;
1302     }
1303     $rdf .='" />
1304 </rdf:RDF>
1305 -->'."\n";
1306     unset($blogInfo); //clean up after ourselves
1307     return $rdf;    
1311 /**
1312  * Send a trackback to another server
1313  */
1314 function blog_send_tb_ping($tb_arr) {
1315     // import the http class
1316     include_once('class.HttpClient.php');
1318 //      print "debug: in blog_send_tb_ping tb_arr = <br />"; //debug
1319 //      print_object($tb_arr); //debug
1321     // Make sure the excerpt is short enough
1322     $body = strip_tags($tb_arr['excerpt']);
1323     $tb_arr['excerpt'] = substr($body, 0, 255) ."...";
1325     // extract url
1326 //    $tb_url = $tb_arr['url'];
1327     // extract url -- Daryl Hawes note: isn't this supposed to be tb_url we're extracting here?
1328     $tb_url = $tb_arr['tb_url'];
1330 //      print "debug: tb_url:<br />"; //debug
1331 //      print_object($tb_url); //debug
1332     
1333     // Did we get a trackback url?
1334     if (!$tb_url) {
1335         // Couldn't find a Trackback url. Give up.
1336         return;
1337     }
1339     // remove it from the array
1340     unset($tb_arr['tb_url']);
1342     // parse the TB url to get the host and path
1343     $urlobj = parse_url($tb_url);
1345 //      print "debug: urlobj:<br />";
1346 //      print_object($urlobj);
1348     // Create the http client object
1349     $http_client = new HttpClient($urlobj['host']);
1351     $postPath = $urlobj['path'];
1352     if ( isset($urlobj['query']) ) {
1353         $postPath = $postPath.'?'.$urlobj['query'];
1354     }
1356     // Post the data
1357     $status = $http_client->post($postPath, $tb_arr);   
1359     if ($status == true) {
1360         $rsp = $http_client->getContent();
1361     } else {
1362         $rsp = get_string('error').': '.$http_client->getError();
1363     }
1364     return $rsp;
1367 /**
1368  * Return a list of trackbacks for a particular id
1369  */
1370 function blog_list_trackbacks($postid) {
1371     global $db, $CFG;
1373     //Daryl Hawes note: convert this sql statement to a moodle function call
1374     $sql = 'SELECT * FROM '. $CFG->prefix .'blog_trackback WHERE entryid = '. $postid;
1375     $res = $db->Execute($sql);
1377     //iterate results
1378     $list = array();
1379     while( !$res->EOF && isset($res->fields) ) {
1380         $list[] = $res->fields;
1381         $res->MoveNext();
1382     }
1384     return $list;
1387 /**
1388  * Return a raw count of how many trackbacks an entry has.
1389  */
1390 function blog_tb_count($id) {
1391     $list = list_trackbacks($id);
1393     return array_count($list);
1396 /**
1397  * Display HTML formatted list of trackbacks for the supplied entryid
1398  * called from tb.php if mode == list, also called by archive.php
1399  * @param int id the entry in question by id
1400  */
1401 function blog_print_trackbacks_for_id($id) {
1402     global $CFG;
1403     $list = blog_list_trackbacks($id);
1404     if (! blog_array_count($list)) {
1405         // There are not trackbacks for this entry
1406         // To avoid page clutter return without printing anything
1407         return;
1408     }
1409     if ($CFG->slasharguments) {
1410                 $tburl = $CFG->wwwroot .'/blog/tb.php/'. $id;
1411     } else {
1412         $tburl = $CFG->wwwroot .'/blog/tb.php?file=/'. $id;
1413     }
1414     
1415     print '<div class="trackbacks">'."\n";
1416     print '<h4>'. get_string('trackbacks', 'blog') .'</h4>';
1417     // print '<p>'. get_string('tburlis', 'blog') .':'."\n";
1418     //print '<!--<a href="'. $tburl .'">-->'."\n";
1419     //print $tburl;
1420     //print '<!--</a>-->'."\n</p>";
1421     print '<ul>';
1422 /*
1423     if (!blog_array_count($list)) {
1424         // No trackbacks
1425         ?>
1426         <li><?php print_string('notrackbacks', 'blog'); ?>.</li>
1427         <?php
1428     } else {
1429 */
1430         while (list($row, $data) = each($list)) {
1431             $post_title = stripslashes_safe($data['title']);
1432             $excerpt = stripslashes_safe($data['excerpt']);
1433             $url = stripslashes_safe($data['url']);
1434             $blogname = stripslashes_safe($data['blogname']);
1435             $added = blog_format_date($data['lastmodified']);
1437             if ($blogname) {
1438                 $blogname = ' '. get_string('tbfrom', 'blog') .' '. $blogname;
1439             }
1441             ?><li>
1442             <a href="<?php echo $url; ?>"><?php echo $post_title; ?></a>
1443             <cite><?php echo $blogname; ?> <?php echo $added; ?></cite>
1444             <blockquote cite="<?php echo $url; ?>" title="<?php print_string('tbquotedfrom', 'blog'); ?>
1445 <?php echo $blogname; ?>">
1446             <?php echo $excerpt; ?>
1447             </blockquote>
1448             </li>
1449             <?php
1450         }
1451 //    }
1452     print '</ul></div>'."\n";
1456 /**
1457  * Display RSSized list
1458  *daryl hawes note: what the heck does this do? What is the $list var?
1459  * it's called from tb.php if mode == rss
1460  */
1461 function blog_tb_rss($id) {
1462     $list = blog_list_trackbacks($id);
1465 /**
1466  * Fetch urls in entry and attempt to auto-discover a TB link
1467  */
1468 function blog_tb_autodiscover($text) {
1469     global $CFG;
1470     require_once($CFG->libdir .'/rsslib.php'); //for rss_unhtmlentities()
1471     include_once('class.HttpClient.php');
1473     preg_match_all("/(((http(s?):\/\/)|(www\.))([\-\_\w\.\/\#\?\+\&\=\%\;]+))/i", $text, $matches);
1475     $tb_urls = array();
1477 //      echo "Debug: blog_tb_autodiscover - matches:<br />"; //debug
1478 //    print_object($matches[0]); //debug
1480     foreach($matches[0] as $url) {
1481         $contents = HttpClient::quickGet($url);
1483 //              echo "Debug: contents from quick get: $contents<br />"; //debug
1485         if (preg_match_all("/(<rdf:RDF.*?<\/rdf:RDF>)/si", $contents, $m)) {
1486             foreach($m[0] as $rdf) {
1487                 preg_match("/dc:identifier=\"([^\"]+)\"/", $rdf, $m2);
1488                 if (rss_unhtmlentities($m2[1]) == $url) {
1489                     if (preg_match("/trackback:ping=\"([^\"]+)\"/", $rdf, $m3)) {
1490                         if (!in_array($m3[1], $tb_urls)) {
1491                             array_push($tb_urls, $m3[1]);
1492                         }
1493                     }
1494                 }
1495             }
1496         }
1497     }
1498     return $tb_urls;
1501 function blog_tblink($id, $date, &$blogEntry) {
1502     $tblist = blog_list_trackbacks($id);
1503     $count = blog_array_count($tblist);
1504     $post_link = $blogEntry->get_simple_entry_link();
1505     $msg = '<a href="'. $post_link .'">'. get_string('trackbacks', 'blog') .'('. $count .')</a>';
1506     return $msg;
1511 /////////////////////// CATEGORY MANAGEMENT ////////////////////////////////////
1515   
1516 /**
1517  *called by blog_category_list
1518  * @return string  html links for each category
1519  */
1520 function blog_get_html_display_for_categories(&$blogFilter, $shownumentries, &$records, $showseparators, $title, $section) {
1521     global $CFG, $editing;
1522     $returnstring ='';
1523     if ($showseparators) {
1524         //first show a separator if requested
1525         $returnstring .= $title .'<br />'."\n";
1526     }
1527     $editallowed = false;
1529     if ($editing) {
1530         $isteacher = false;
1531         if (isset($blogFilter->courseid)) {
1532             $isteacher = isteacher($blogFilter->courseid);
1533         }
1534         if ( isadmin() ) {
1535             // admin is allowed to edit any categories on the site
1536             $editallowed = true;
1537         } else if ( ($section == 'course' || $section == 'group') && $isteacher ) {
1538             // teacher of course can modify course categories and group categories
1539             $editallowed = true;
1540         } else if ($section == 'personal' && blog_is_blog_admin($blogFilter->userid) ) {
1541             // user can modify their own blog categories
1542             $editallowed = true;
1543         }
1544     }
1546     if (!isset($records) ) {
1547         return;
1548     }
1549     
1550     foreach($records as $record) {
1551         $catcount = '';
1552         $categoryid = $record->id;
1553         $categoryname = $record->catname;
1554         if ($shownumentries) {
1555             $tempfilter =& new BlogFilter('', $categoryid);
1556             $catcount = ' (';
1557             $catcount .= $tempfilter->get_filtered_entry_count();
1558             $catcount .= ')';
1559         }
1560         $blogFilter->categoryid = $categoryid;
1561         $returnstring .= $blogFilter->get_complete_link($CFG->wwwroot .'/blog/index.php', stripslashes_safe($categoryname) . $catcount);
1562         if ($editallowed) {
1563             // note that only the 'act' and 'categoryid' vars are needed here because the me() function includes the 
1564             // existing query string
1565             $returnstring .= '&nbsp;<a href="'. me() .'&amp;act=editcategory&amp;categoryid='. $categoryid .'">';
1566             $returnstring .= '<img src="'. $CFG->pixpath .'/t/edit.gif" alt="'. get_string('edit');
1567             $returnstring .= '" title="'. get_string('edit') .'" align="absmiddle" height="16" width="16" border="0" /></a>'."\n";
1568             if ($categoryid != 1) { //do not remove "General" sitewide category
1569                 $returnstring .= '&nbsp;<a href="'. $CFG->wwwroot .'/blog/admin.php?act=delcategory&amp;categoryid='. $categoryid;
1570                 $returnstring .= '&amp;userid='. $blogFilter->userid .'&amp;courseid='. $blogFilter->courseid .'&amp;groupid='. $blogFilter->groupid .'" onClick="return confirm(\''. get_string('confirmcategorydelete', 'blog') .'\');">';
1571                 $returnstring .= '<img src="'. $CFG->pixpath .'/t/delete.gif" ALT="'. get_string('delete');
1572 $returnstring .= '" title="'. get_string('delete') .'" align="absmiddle" border="0" /></a>'."\n";
1573             }
1574         }
1575         $returnstring .= '<br />'."\n";
1576     }
1577     return $returnstring;
1580 /**
1581  *
1582  */
1583 function blog_get_popup_display_for_categories(&$blogFilter, $format, $shownumentries, &$records) {
1584     global $CFG;
1586     if (!isset($records) ) {
1587         return;
1588     }
1589     $returnstring = '';
1590     
1591     foreach ($records as $record) {
1592         if ($format == 2) {
1593             $value = $CFG->wwwroot .'/blog/index.php?categoryid='. $record->id;
1594             $value .= '&amp;userid='. $blogFilter->userid .'&amp;courseid='. $blogFilter->courseid .'&amp;groupid='. $blogFilter->groupid;
1595         } else {
1596             $value = $record->id;
1597         }
1598         
1599         $returnstring .= '<option value="'. $value .'"';
1600         if ($record->id == $blogFilter->categoryid) {
1601             $returnstring .= ' selected';
1602         }
1603         $catcount = '';
1604         $categoryid = $record->id;
1605         $categoryname = $record->catname;
1606         if ($shownumentries) {
1607             $tempfilter =& new BlogFilter('', $categoryid);
1608             $tempfilter->userid = $blogFilter->userid;
1609             $catcount = ' (';
1610             //if we had an array of blogentry objects we could avoid a database call
1611             //and instead simply ask the blogentry objects to tell us which apply
1612             $catcount .= $tempfilter->get_filtered_entry_count();
1613             $catcount .= ')';
1614         }
1615         $returnstring .= '>' ."\n". stripslashes_safe($categoryname) . $catcount ."\n";
1616         $returnstring .= '</option>';
1617     }
1618     return $returnstring;
1620 ?>