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