1<?php 2/** 3 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 4 * @author Michael Klier <chi@chimeric.de> 5 */ 6// must be run within Dokuwiki 7if(!defined('DOKU_INC')) die(); 8 9/** 10 * Class helper_plugin_blogtng_comments 11 */ 12class helper_plugin_blogtng_comments extends DokuWiki_Plugin { 13 14 /** 15 * @var helper_plugin_blogtng_sqlite 16 */ 17 private $sqlitehelper = null; 18 19 private $pid; 20 21 /** 22 * Constructor, loads the sqlite helper plugin 23 */ 24 public function __construct() { 25 $this->sqlitehelper = plugin_load('helper', 'blogtng_sqlite'); 26 } 27 28 /** 29 * Set pid 30 * 31 * @param $pid 32 */ 33 public function setPid($pid) { 34 $this->pid = trim($pid); 35 } 36 37 /** 38 * Select comment by cid and return it as a blogtng_comment. The 39 * function returns false if the database query fails. It returns 40 * null if the query result is empty. 41 * 42 * @param $cid The cid 43 * @return blogtng_comment|bool|null 44 */ 45 public function comment_by_cid($cid) { 46 47 $query = 'SELECT cid, pid, source, name, mail, web, avatar, created, text, status FROM comments WHERE cid = ?'; 48 $resid = $this->sqlitehelper->getDB()->query($query, $cid); 49 if ($resid === false) { 50 return false; 51 } 52 if ($this->sqlitehelper->getDB()->res2count($resid) == 0) { 53 return null; 54 } 55 $result = $this->sqlitehelper->getDB()->res2arr($resid); 56 57 $comment = new blogtng_comment(); 58 $comment->init($result[0]); 59 return $comment; 60 } 61 62 /** 63 * Get comment count 64 * 65 * @param null $types 66 * @param bool $includehidden 67 * @return int 68 */ 69 public function get_count($types=null, $includehidden=false) { 70 if (!$this->sqlitehelper->ready()) return 0; 71 72 $sql = 'SELECT COUNT(pid) as val 73 FROM comments 74 WHERE pid = ?'; 75 if ($includehidden === false){ 76 $sql .= ' AND status = \'visible\''; 77 } 78 $args = array(); 79 $args[] = $this->pid; 80 if(is_array($types)){ 81 $qs = array(); 82 foreach($types as $type){ 83 $args[] = $type; 84 $qs[] = '?'; 85 } 86 $sql .= ' AND type IN ('.join(',',$qs).')'; 87 } 88 $res = $this->sqlitehelper->getDB()->query($sql,$args); 89 $res = $this->sqlitehelper->getDB()->res2row($res,0); 90 return (int) $res['val']; 91 } 92 93 /** 94 * Save comment 95 * 96 * @param $comment 97 */ 98 public function save($comment) { 99 if (!$this->sqlitehelper->ready()) { 100 msg('BlogTNG: no sqlite helper plugin available', -1); 101 return; 102 } 103 104 if (isset($comment['cid'])) { 105 // Doing an update 106 $query = 'UPDATE comments SET pid=?, source=?, name=?, mail=?, ' . 107 'web=?, avatar=?, created=?, text=?, status=? WHERE cid=?'; 108 $this->sqlitehelper->getDB()->query($query, 109 $comment['pid'], 110 $comment['source'], 111 $comment['name'], 112 $comment['mail'], 113 $comment['web'], 114 $comment['avatar'], 115 $comment['created'], 116 $comment['text'], 117 $comment['status'], 118 $comment['cid'] 119 ); 120 return; 121 } 122 123 // Doing an insert 124 /** @var helper_plugin_blogtng_entry $entry */ 125 $entry = plugin_load('helper', 'blogtng_entry'); 126 $entry->load_by_pid($comment['pid']); 127 if ($entry->entry['commentstatus'] !== 'enabled') { 128 return; 129 } 130 131 $query = 132 'INSERT OR IGNORE INTO comments ( 133 pid, source, name, mail, web, avatar, created, text, status, ip 134 ) VALUES ( 135 ?, ?, ?, ?, ?, ?, ?, ?, ?, ? 136 )'; 137 $comment['status'] = ($this->getconf('moderate_comments')) ? 'hidden' : 'visible'; 138 139 if(!isset($comment['created'])) $comment['created'] = time(); 140 141 $comment['avatar'] = ''; // FIXME create avatar using a helper function 142 143 $this->sqlitehelper->getDB()->query($query, 144 $comment['pid'], 145 $comment['source'], 146 $comment['name'], 147 $comment['mail'], 148 $comment['web'], 149 $comment['avatar'], 150 $comment['created'], 151 $comment['text'], 152 $comment['status'], 153 $comment['ip'] 154 ); 155 156 //retrieve cid of this comment 157 $sql = "SELECT cid 158 FROM comments 159 WHERE pid = ? 160 AND created = ? 161 AND mail =? 162 LIMIT 1"; 163 $res = $this->sqlitehelper->getDB()->query($sql, 164 $comment['pid'], 165 $comment['created'], 166 $comment['mail']); 167 $cid = $this->sqlitehelper->getDB()->res2single($res); 168 $comment['cid'] = $cid === false ? 0 : $cid; 169 170 171 // handle subscriptions 172 if($this->getConf('comments_subscription')) { 173 if($comment['subscribe']) { 174 $this->subscribe($comment['pid'],$comment['mail']); 175 } 176 // send subscriber and notify mails 177 $this->send_subscriber_mails($comment); 178 } 179 } 180 181 /** 182 * Delete comment 183 * 184 * @param $cid 185 * @return bool 186 */ 187 public function delete($cid) { 188 if (!$this->sqlitehelper->ready()) return false; 189 $query = 'DELETE FROM comments WHERE cid = ?'; 190 return (bool) $this->sqlitehelper->getDB()->query($query, $cid); 191 } 192 193 /** 194 * Delete all comments for an entry 195 * 196 * @param $pid 197 * @return bool 198 */ 199 public function delete_all($pid) { 200 if (!$this->sqlitehelper->ready()) return false; 201 $sql = "DELETE FROM comments WHERE pid = ?"; 202 return (bool) $this->sqlitehelper->getDB()->query($sql,$pid); 203 } 204 205 /** 206 * Moderate comment 207 * 208 * @param $cid 209 * @param $status 210 * @return bool 211 */ 212 public function moderate($cid, $status) { 213 if (!$this->sqlitehelper->ready()) return false; 214 $query = 'UPDATE comments SET status = ? WHERE cid = ?'; 215 return (bool) $this->sqlitehelper->getDB()->query($query, $status, $cid); 216 } 217 218 /** 219 * Send a mail about the new comment 220 * 221 * Mails are sent to the author of the post and 222 * all subscribers that opted-in 223 * 224 * @param $comment 225 */ 226 public function send_subscriber_mails($comment){ 227 global $conf; 228 229 if (!$this->sqlitehelper->ready()) return; 230 231 // get general article info 232 $sql = "SELECT title, page, mail 233 FROM entries 234 WHERE pid = ?"; 235 $res = $this->sqlitehelper->getDB()->query($sql,$comment['pid']); 236 $entry = $this->sqlitehelper->getDB()->res2row($res,0); 237 238 // prepare mail bodies 239 $atext = io_readFile($this->localFN('notifymail')); 240 $stext = io_readFile($this->localFN('subscribermail')); 241 $title = sprintf($this->getLang('subscr_subject'),$entry['title']); 242 243 $repl = array( 244 '@TITLE@' => $entry['title'], 245 '@NAME@' => $comment['name'], 246 '@COMMENT@' => $comment['text'], 247 '@USER@' => $comment['name'], 248 '@MAIL@' => $comment['mail'], 249 '@DATE@' => dformat(time()), 250 '@BROWSER@' => $_SERVER['HTTP_USER_AGENT'], 251 '@IPADDRESS@' => clientIP(), 252 '@HOSTNAME@' => gethostsbyaddrs(clientIP()), 253 '@URL@' => wl($entry['page'],'',true).($comment['cid'] ? '#comment_'.$comment['cid'] : ''), 254 '@DOKUWIKIURL@' => DOKU_URL, 255 ); 256 257 $atext = str_replace(array_keys($repl),array_values($repl),$atext); 258 $stext = str_replace(array_keys($repl),array_values($repl),$stext); 259 260 // notify author 261 $mails = array_map('trim', explode(',', $conf['notify'])); 262 $mails[] = $entry['mail']; 263 $mails = array_unique(array_filter($mails)); 264 if (count($mails) > 0) { 265 mail_send('', $title, $atext, $conf['mailfrom'], '', implode(',', $mails)); 266 } 267 268 // finish here when subscriptions disabled 269 if(!$this->getConf('comments_subscription')) return; 270 271 // get subscribers 272 $sql = "SELECT A.mail as mail, B.key as key 273 FROM subscriptions A, optin B 274 WHERE A.mail = B.mail 275 AND B.optin = 1 276 AND A.pid = ?"; 277 $res = $this->sqlitehelper->getDB()->query($sql,$comment['pid']); 278 $rows = $this->sqlitehelper->getDB()->res2arr($res); 279 foreach($rows as $row){ 280 // ignore commenter herself: 281 if($row['mail'] == $comment['mail']) continue; 282 // ignore email addresses already notified: 283 if(in_array($row['mail'], $mails)) continue; 284 mail_send($row['mail'], $title, str_replace('@UNSUBSCRIBE@', wl($entry['page'],array('btngu'=>$row['key']),true), $stext), $conf['mailfrom']); 285 } 286 } 287 288 /** 289 * Send a mail to commenter and let her login 290 * 291 * @param $mail 292 * @param $key 293 */ 294 public function send_optin_mail($mail,$key){ 295 global $conf; 296 297 $text = io_readFile($this->localFN('optinmail')); 298 $title = sprintf($this->getLang('optin_subject')); 299 300 $repl = array( 301 '@TITLE@' => $conf['title'], 302 '@URL@' => wl('',array('btngo'=>$key),true), 303 '@DOKUWIKIURL@' => DOKU_URL, 304 ); 305 $text = str_replace(array_keys($repl),array_values($repl),$text); 306 307 mail_send($mail, $title, $text, $conf['mailfrom']); 308 } 309 310 /** 311 * Subscribe entry 312 * 313 * @param string $pid - entry to subscribe 314 * @param string $mail - email of subscriber 315 * @param int $optin - set to 1 for immediate optin 316 */ 317 public function subscribe($pid, $mail, $optin = -3) { 318 if (!$this->sqlitehelper->ready()) { 319 msg('BlogTNG: subscribe fails. (sqlite helper plugin not available)',-1); 320 return; 321 } 322 323 // add to subscription list 324 $sql = "INSERT OR IGNORE INTO subscriptions 325 (pid, mail) VALUES (?,?)"; 326 $this->sqlitehelper->getDB()->query($sql,$pid,strtolower($mail)); 327 328 // add to optin list 329 if($optin == 1){ 330 $sql = "INSERT OR REPLACE INTO optin 331 (mail,optin,key) VALUES (?,?,?)"; 332 $this->sqlitehelper->getDB()->query($sql,strtolower($mail),$optin,md5(time())); 333 }else{ 334 $sql = "INSERT OR IGNORE INTO optin 335 (mail,optin,key) VALUES (?,?,?)"; 336 $this->sqlitehelper->getDB()->query($sql,strtolower($mail),$optin,md5(time())); 337 338 // see if we need to send a optin mail 339 $sql = "SELECT optin, key FROM optin WHERE mail = ?"; 340 $res = $this->sqlitehelper->getDB()->query($sql,strtolower($mail)); 341 $row = $this->sqlitehelper->getDB()->res2row($res,0); 342 if($row['optin'] < 0){ 343 $this->send_optin_mail($mail,$row['key']); 344 $sql = "UPDATE optin SET optin = optin+1 WHERE mail = ?"; 345 $this->sqlitehelper->getDB()->query($sql,strtolower($mail)); 346 } 347 } 348 349 350 } 351 352 /** 353 * Unsubscribe by key 354 * 355 * @param $pid 356 * @param $key 357 */ 358 public function unsubscribe_by_key($pid, $key) { 359 if (!$this->sqlitehelper->ready()) { 360 msg('BlogTNG: unsubscribe by key fails. (sqlite helper plugin not available)',-1); 361 return; 362 } 363 $sql = 'SELECT mail FROM optin WHERE key = ?'; 364 $res = $this->sqlitehelper->getDB()->query($sql, $key); 365 $row = $this->sqlitehelper->getDB()->res2row($res); 366 if (!$row) { 367 msg($this->getLang('unsubscribe_err_key'), -1); 368 return; 369 } 370 371 $this->unsubscribe($pid, $row['mail']); 372 } 373 374 /** 375 * Unsubscribe entry 376 * 377 * @param $pid 378 * @param $mail 379 */ 380 public function unsubscribe($pid, $mail) { 381 if (!$this->sqlitehelper->ready()) { 382 msg($this->getlang('unsubscribe_err_other') . ' (sqlite helper plugin not available)', -1); 383 return; 384 } 385 $sql = 'DELETE FROM subscriptions WHERE pid = ? AND mail = ?'; 386 $res = $this->sqlitehelper->getDB()->query($sql, $pid, $mail); 387 $upd = $this->sqlitehelper->getDB()->countChanges($res); 388 389 if ($upd) { 390 msg($this->getLang('unsubscribe_ok'), 1); 391 } else { 392 msg($this->getlang('unsubscribe_err_other'), -1); 393 } 394 } 395 396 /** 397 * Opt in 398 * 399 * @param $key 400 */ 401 public function optin($key) { 402 if (!$this->sqlitehelper->ready()) { 403 msg($this->getlang('optin_err') . ' (sqlite helper plugin not available)', -1); 404 return; 405 } 406 407 $sql = 'UPDATE optin SET optin = 1 WHERE key = ?'; 408 $res = $this->sqlitehelper->getDB()->query($sql,$key); 409 $upd = $this->sqlitehelper->getDB()->countChanges($res); 410 411 if($upd){ 412 msg($this->getLang('optin_ok'),1); 413 }else{ 414 msg($this->getLang('optin_err'),-1); 415 } 416 } 417 418 /** 419 * Enable discussion 420 * 421 * @param $pid 422 */ 423 public function enable($pid) { 424 } 425 426 /** 427 * Disable discussion 428 * 429 * @param $pid 430 */ 431 public function disable($pid) { 432 } 433 434 /** 435 * Close discussion 436 * 437 * @param $pid 438 */ 439 public function close($pid) { 440 } 441 442 /** 443 * Prints the comment form 444 * 445 * FIXME 446 * allow comments only for registered users 447 * add toolbar 448 * 449 * @param $page 450 * @param $pid 451 * @param $tplname 452 */ 453 public function tpl_form($page, $pid, $tplname) { 454 global $BLOGTNG; 455 456 $form = new Doku_Form(array('id'=>'blogtng__comment_form','action'=>wl($page).'#blogtng__comment_form','data-tplname'=>$tplname)); 457 $form->addHidden('pid', $pid); 458 $form->addHidden('id', $page); 459 $form->addHidden('btng[comment][source]', 'comment'); 460 461 foreach(array('name', 'mail', 'web') as $field) { 462 $attr = ($BLOGTNG['comment_submit_errors'][$field]) ? array('class' => 'edit error') : array(); 463 464 if($field == 'web' && !$this->getConf('comments_allow_web')) { 465 continue; 466 } else { 467 $form->addElement( 468 form_makeTextField( 469 'btng[comment][' . $field . ']', 470 $BLOGTNG['comment'][$field], 471 $this->getLang('comment_'.$field), 472 'blogtng__comment_' . $field, 473 'edit block', 474 $attr) 475 ); 476 } 477 } 478 479 $form->addElement(form_makeOpenTag('div', array('class' => 'blogtng__toolbar'))); 480 $form->addElement(form_makeCloseTag('div')); 481 482 if($BLOGTNG['comment_submit_errors']['text']) { 483 $form->addElement(form_makeWikiText($BLOGTNG['comment']['text'], array('class' => 'edit error'))); 484 } else { 485 $form->addElement(form_makeWikiText($BLOGTNG['comment']['text'])); 486 } 487 488 //add captcha if available 489 /** @var helper_plugin_captcha $helper */ 490 $helper = null; 491 if(@is_dir(DOKU_PLUGIN.'captcha')) $helper = plugin_load('helper','captcha'); 492 if(!is_null($helper) && $helper->isEnabled()){ 493 $form->addElement($helper->getHTML()); 494 } 495 496 $form->addElement(form_makeButton('submit', 'comment_preview', $this->getLang('comment_preview'), array('class' => 'button', 'id' => 'blogtng__preview_submit'))); 497 $form->addElement(form_makeButton('submit', 'comment_submit', $this->getLang('comment_submit'), array('class' => 'button', 'id' => 'blogtng__comment_submit'))); 498 499 if($this->getConf('comments_subscription')){ 500 $form->addElement(form_makeCheckboxField('blogtng[subscribe]', 1, $this->getLang('comment_subscribe'))); 501 } 502 503 print '<div id="blogtng__comment_form_wrap">'.DOKU_LF; 504 $form->printForm(); 505 if(isset($BLOGTNG['comment_action']) && ($BLOGTNG['comment_action'] == 'preview') && empty($BLOGTNG['comment_submit_errors'])) { 506 print '<div id="blogtng__comment_preview">' . DOKU_LF; 507 $comment = new blogtng_comment(); 508 $comment->data = $BLOGTNG['comment']; 509 $comment->data['cid'] = 'preview'; 510 $comment->output($tplname); 511 print '</div>' . DOKU_LF; 512 } 513 print '</div>'.DOKU_LF; 514 } 515 516 /** 517 * Print the number of comments 518 * 519 * @param string $fmt_zero_comments - text for no comment 520 * @param string $fmt_one_comments - text for 1 comment 521 * @param string $fmt_comments - text for 1+ comment 522 * @param array $types - a list of wanted comment sources (empty for all) 523 * @return bool 524 */ 525 public function tpl_count($fmt_zero_comments='', $fmt_one_comments='', $fmt_comments='', $types=null) { 526 if(!$this->pid) return; 527 528 if(!$fmt_zero_comments) 529 $fmt_zero_comments = $this->getLang('0comments'); 530 if(!$fmt_one_comments) 531 $fmt_one_comments = $this->getLang('1comments'); 532 if(!$fmt_comments) 533 $fmt_comments = $this->getLang('Xcomments'); 534 535 $count = $this->get_count($types); 536 537 switch($count) { 538 case 0: 539 printf($fmt_zero_comments, $count); 540 break; 541 case 1: 542 printf($fmt_one_comments, $count); 543 break; 544 default: 545 printf($fmt_comments, $count); 546 break; 547 } 548 } 549 550 /** 551 * Print the comments 552 */ 553 public function tpl_comments($name,$types=null) { 554 $pid = $this->pid; 555 if(!$pid) return; 556 557 if (!$this->sqlitehelper->ready()) return; 558 559 $sql = 'SELECT * 560 FROM comments 561 WHERE pid = ?'; 562 $args = array(); 563 $args[] = $pid; 564 if(is_array($types)){ 565 $qs = array(); 566 foreach($types as $type){ 567 $args[] = $type; 568 $qs[] = '?'; 569 } 570 $sql .= ' AND type IN ('.join(',',$qs).')'; 571 } 572 $sql .= ' ORDER BY created ASC'; 573 $res = $this->sqlitehelper->getDB()->query($sql,$args); 574 $res = $this->sqlitehelper->getDB()->res2arr($res); 575 576 $comment = new blogtng_comment(); 577 foreach($res as $row){ 578 $comment->init($row); 579 $comment->output($name); 580 } 581 } 582 583 /** 584 * Displays a list of recent comments 585 * 586 * @param $conf 587 * @return string 588 */ 589 public function xhtml_recentcomments($conf){ 590 ob_start(); 591 if($conf['listwrap']) echo '<ul class="blogtng_recentcomments">'; 592 $this->tpl_recentcomments($conf['tpl'],$conf['limit'],$conf['blog'],$conf['type']); 593 if($conf['listwrap']) echo '</ul>'; 594 $output = ob_get_contents(); 595 ob_end_clean(); 596 return $output; 597 } 598 599 /** 600 * Display a list of recent comments 601 */ 602 public function tpl_recentcomments($tpl='default',$num=5,$blogs=array('default'),$types=array()){ 603 // check template 604 $tpl = helper_plugin_blogtng_tools::getTplFile($tpl, 'recentcomments'); 605 if($tpl === false){ 606 return false; 607 } 608 609 if(!$this->sqlitehelper->ready()) return false; 610 611 // prepare and execute query 612 if(count($types)){ 613 $types = $this->sqlitehelper->getDB()->quote_and_join($types,','); 614 $tquery = " AND B.source IN ($types) "; 615 }else{ 616 $tquery = ""; 617 } 618 $blog_query = '(A.blog = '. 619 $this->sqlitehelper->getDB()->quote_and_join($blogs, 620 ' OR A.blog = ').')'; 621 $query = "SELECT A.pid as pid, page, title, cid 622 FROM entries A, comments B 623 WHERE $blog_query 624 AND A.pid = B.pid 625 $tquery 626 AND B.status = 'visible' 627 AND GETACCESSLEVEL(A.page) >= ".AUTH_READ." 628 ORDER BY B.created DESC 629 LIMIT ".(int) $num; 630 631 $res = $this->sqlitehelper->getDB()->query($query); 632 633 if(!$this->sqlitehelper->getDB()->res2count($res)) return false; // no results found 634 $res = $this->sqlitehelper->getDB()->res2arr($res); 635 636 // print all hits using the template 637 foreach($res as $row){ 638 /** @var helper_plugin_blogtng_entry $entry */ 639 $entry = plugin_load('helper', 'blogtng_entry'); 640 $entry->load_by_pid($row['pid']); 641 $comment = $this->comment_by_cid($row['cid']); 642 include($tpl); 643 } 644 return true; 645 } 646 647} 648 649/** 650 * Simple wrapper class for a single comment object 651 */ 652class blogtng_comment{ 653 var $data; 654 var $num; 655 656 /** 657 * Resets the internal data with a given row 658 */ 659 public function blogtng_comment(){ 660 $this->tools = new helper_plugin_blogtng_tools(); 661 } 662 663 /** 664 * @param $row array row of table 'commments' 665 */ 666 public function init($row){ 667 $this->data = $row; 668 } 669 670 /** 671 * Render a comment using the templates comments file. 672 * 673 * @param string $name of template 674 * @return bool 675 */ 676 public function output($name){ 677 global $INFO; 678 $name = preg_replace('/[^a-zA-Z_\-]+/','',$name); 679 $tpl = $this->tools->getTplFile($name,'comments'); 680 if($tpl === false){ 681 return false; 682 } 683 684 $comment = $this; 685 if($comment->data['status'] == 'visible' || ($comment->data['status'] == 'hidden' && $INFO['isadmin'])) { 686 $comment->num++; 687 include($tpl); 688 } 689 return true; 690 } 691 692 /** 693 * Get translated string for @$name 694 * 695 * @param string $name id of the string to be retrieved 696 * @return string string in appropriate language or english if not available 697 */ 698 public function getLang($name){ 699 return $this->tools->getLang($name); 700 } 701 702 /** 703 * Render the text/content of a single comment 704 * 705 * @param string $name id of the string to be retrieved 706 * @return string string in appropriate language or english if not available 707 */ 708 public function tpl_comment(){ 709 //FIXME add caching 710 711 $inst = p_get_instructions($this->data['text']); 712 echo p_render('blogtng_comment',$inst,$info); 713 } 714 715 /** 716 * Render the cid of a single comment 717 */ 718 public function tpl_cid(){ 719 echo $this->data['cid']; 720 } 721 722 /** 723 * Render the number of a comment. 724 * 725 * @param bool $link whether wrapped with link element 726 * @param string $fmt format of number 727 * @param string $title null or alternative title 728 */ 729 public function tpl_number($link = true, $fmt = '%d', $title = null) { 730 if($title === null) $title = sprintf($fmt, $this->num); 731 732 if($link) echo '<a href="#comment_' . $this->data['cid'] . '" class="blogtng_num">'; 733 echo $title; 734 if($link) echo '</a>'; 735 } 736 737 /** 738 * Render the hcard/userdata of a single comment 739 */ 740 public function tpl_hcard(){ 741 echo '<div class="vcard">'; 742 if($this->data['web']){ 743 echo '<a href="'.hsc($this->data['web']).'" class="fn nickname">'; 744 echo hsc($this->data['name']); 745 echo '</a>'; 746 }else{ 747 echo '<span class="fn nickname">'; 748 echo hsc($this->data['name']); 749 echo '</span>'; 750 } 751 echo '</div>'; 752 } 753 754 /** 755 * Render the name of a single comment 756 */ 757 public function tpl_name(){ 758 echo hsc($this->data['name']); 759 } 760 761 /** 762 * Render the type of a single comment 763 */ 764 public function tpl_type(){ 765 echo hsc($this->data['type']); 766 } 767 768 /** 769 * Render the mail of a single comment 770 */ 771 public function tpl_mail(){ 772 echo hsc($this->data['mail']); 773 } 774 775 /** 776 * Render the web address of a single comment 777 */ 778 public function tpl_web(){ 779 echo hsc($this->data['web']); 780 } 781 782 /** 783 * Render the creation date of a single comment 784 * 785 * @param string $fmt date format, empty string default to $conf['dformat'] 786 */ 787 public function tpl_created($fmt=''){ 788 echo hsc(dformat($this->data['created'],$fmt)); 789 } 790 791 /** 792 * Render the status of a single comment 793 */ 794 public function tpl_status() { 795 echo $this->data['status']; 796 } 797 798 /** 799 * Render the avatar of a single comment 800 * 801 * @param int $w avatar width 802 * @param int $h avatar height 803 * @param bool $return whether the url is returned or printed 804 * @return void|string url of avatar 805 */ 806 public function tpl_avatar($w=0,$h=0,$return=false){ 807 global $conf; 808 $img = ''; 809 if($this->data['avatar']) { 810 $img = $this->data['avatar']; 811 //FIXME add hook for additional methods 812 } elseif ($this->data['mail']) { 813 $dfl = $conf['plugin']['blogtng']['comments_gravatar_default']; 814 if(!isset($dfl) || $dfl == 'blank') $dfl = DOKU_URL . 'lib/images/blank.gif'; 815 816 $img = 'http://gravatar.com/avatar.php' 817 . '?gravatar_id=' . md5($this->data['mail']) 818 . '&size=' . $w 819 . '&rating=' . $conf['plugin']['blogtng']['comments_gravatar_rating'] 820 . '&default='.rawurlencode($dfl) 821 . '&.png'; 822 } elseif ($this->data['web']){ 823 $img = 'http://getfavicon.appspot.com/'.rawurlencode($this->data['web']).'?.png'; 824 } 825 826 827 //use fetch for caching and resizing 828 if($img){ 829 $img = ml($img,array('w'=>$w,'h'=>$h,'cache'=>'recache')); 830 } 831 if($return) { 832 return $img; 833 } else { 834 print $img; 835 } 836 } 837} 838// vim:ts=4:sw=4:et: 839