b2evolution

Multilingual multiuser multiblog engine

b2evolution Technical Documentation (Version 2.4) [ class tree: evocore ] [ index: evocore ] [ all elements ]

Source for file _comment.class.php

Documentation is available at _comment.class.php

  1. <?php
  2. /**
  3.  * This file implements the Comment class.
  4.  *
  5.  * This file is part of the b2evolution/evocms project - {@link http://b2evolution.net/}.
  6.  * See also {@link http://sourceforge.net/projects/evocms/}.
  7.  *
  8.  * @copyright (c)2003-2008 by Francois PLANQUE - {@link http://fplanque.net/}.
  9.  *  Parts of this file are copyright (c)2004-2005 by Daniel HAHLER - {@link http://thequod.de/contact}.
  10.  *
  11.  * @license http://b2evolution.net/about/license.html GNU General Public License (GPL)
  12.  *
  13.  *  {@internal Open Source relicensing agreement:
  14.  *  Daniel HAHLER grants Francois PLANQUE the right to license
  15.  *  Daniel HAHLER's contributions to this file and the b2evolution project
  16.  *  under any OSI approved OSS license (http://www.opensource.org/licenses/).
  17.  *  }}}
  18.  *
  19.  * @package evocore
  20.  *
  21.  *  {@internal Below is a list of authors who have contributed to design/coding of this file: }}
  22.  * @author blueyed: Daniel HAHLER.
  23.  * @author fplanque: Francois PLANQUE
  24.  *
  25.  * @version $Id: _comment.class.php,v 1.14.2.1 2009/01/27 00:45:54 blueyed Exp $
  26.  */
  27. if!defined('EVO_MAIN_INIT') ) die'Please, do not access this page directly.' );
  28.  
  29. load_class('_core/model/dataobjects/_dataobject.class.php');
  30.  
  31. /**
  32.  * Comment Class
  33.  *
  34.  * @package evocore
  35.  */
  36. class Comment extends DataObject
  37. {
  38.     /**
  39.      * The item (parent) of this Comment (lazy-filled).
  40.      * @see Comment::get_Item()
  41.      * @see Comment::set_Item()
  42.      * @access protected
  43.      * @var Item 
  44.      */
  45.     var $Item;
  46.     /**
  47.      * The ID of the comment's Item.
  48.      * @var integer 
  49.      */
  50.     var $item_ID;
  51.     /**
  52.      * The comment's user, this is NULL for (anonymous) visitors (lazy-filled).
  53.      * @see Comment::get_author_User()
  54.      * @see Comment::set_author_User()
  55.      * @access protected
  56.      * @var User 
  57.      */
  58.     var $author_User;
  59.     /**
  60.      * The ID of the author's user. NULL for anonymous visitors.
  61.      * @var integer 
  62.      */
  63.     var $author_ID;
  64.     /**
  65.      * Comment type: 'comment', 'linkback', 'trackback' or 'pingback'
  66.      * @var string 
  67.      */
  68.     var $type;
  69.     /**
  70.      * Comment visibility status: 'published', 'deprecated', 'redirected', 'protected', 'private' or 'draft'
  71.      * @var string 
  72.      */
  73.     var $status;
  74.     /**
  75.      * Name of the (anonymous) visitor (if any).
  76.      * @var string 
  77.      */
  78.     var $author;
  79.     /**
  80.      * Email address of the (anonymous) visitor (if any).
  81.      * @var string 
  82.      */
  83.     var $author_email;
  84.     /**
  85.      * URL/Homepage of the (anonymous) visitor (if any).
  86.      * @var string 
  87.      */
  88.     var $author_url;
  89.     /**
  90.      * IP address of the comment's author (while posting).
  91.      * @var string 
  92.      */
  93.     var $author_IP;
  94.     /**
  95.      * Date of the comment (MySQL DATETIME - use e.g. {@link mysql2timestamp()}); local time ({@link $localtimenow})
  96.      * @var string 
  97.      */
  98.     var $date;
  99.     /**
  100.      * @var string 
  101.      */
  102.     var $content;
  103.     /**
  104.      * Spam karma of the comment (0-100), 0 being "probably no spam at all"
  105.      * @var integer 
  106.      */
  107.     var $spam_karma;
  108.     /**
  109.      * Does an anonymous commentator allow to send messages through a message form?
  110.      * @var boolean 
  111.      */
  112.     var $allow_msgform;
  113.  
  114.     var $nofollow;
  115.  
  116.     /**
  117.      * Constructor
  118.      */
  119.     function Comment$db_row NULL )
  120.     {
  121.         // Call parent constructor:
  122.         parent::DataObject'T_comments''comment_''comment_ID' );
  123.  
  124.         if$db_row == NULL )
  125.         {
  126.             // echo 'null comment';
  127.             $this->rating NULL;
  128.             $this->featured 0;
  129.             $this->nofollow = 1;
  130.         }
  131.         else
  132.         {
  133.             $this->ID = $db_row['comment_ID'];
  134.             $this->item_ID = $db_row['comment_post_ID'];
  135.             ifempty($db_row['comment_author_ID']) )
  136.             {
  137.                 $this->author_user_ID $db_row['comment_author_ID'];
  138.             }
  139.             $this->type = $db_row['comment_type'];
  140.             $this->status = $db_row['comment_status'];
  141.             $this->author = $db_row['comment_author'];
  142.             $this->author_email = $db_row['comment_author_email'];
  143.             $url trim$db_row['comment_author_url');
  144.             ifempty($url&& preg_match'~^\w+://~'$url ) )
  145.             // URL given and does not start with a protocol:
  146.                 $url 'http://'.$url;
  147.             }
  148.             $this->author_url = $url;
  149.             $this->author_IP = $db_row['comment_author_IP'];
  150.             $this->date = $db_row['comment_date'];
  151.             $this->content = $db_row['comment_content'];
  152.             $this->rating $db_row['comment_rating'];
  153.             $this->featured $db_row['comment_featured'];
  154.             $this->nofollow = $db_row['comment_nofollow'];
  155.             $this->spam_karma = $db_row['comment_spam_karma'];
  156.             $this->allow_msgform = $db_row['comment_allow_msgform'];
  157.         }
  158.     }
  159.  
  160.  
  161.     /**
  162.      * Get the author User of the comment. This is NULL for anonymous visitors.
  163.      *
  164.      * @return User 
  165.      */
  166.     function get_author_User()
  167.     {
  168.         ifisset($this->author_user_ID&& isset($this->author_User) )
  169.         {
  170.             $UserCache get_Cache'UserCache' );
  171.             $this->author_User = $UserCache->get_by_ID$this->author_user_ID );
  172.         }
  173.  
  174.         return $this->author_User;
  175.     }
  176.  
  177.  
  178.     /**
  179.      * Get the Item this comment relates to
  180.      *
  181.      * @return Item 
  182.      */
  183.     function get_Item()
  184.     {
  185.         ifisset($this->Item) )
  186.         {
  187.             $ItemCache get_Cache'ItemCache' );
  188.             $this->Item = $ItemCache->get_by_ID$this->item_ID );
  189.         }
  190.  
  191.         return $this->Item;
  192.     }
  193.  
  194.  
  195.     /**
  196.      * Get a member param by its name
  197.      *
  198.      * @param mixed Name of parameter
  199.      * @return mixed Value of parameter
  200.      */
  201.     function get$parname )
  202.     {
  203.         global $post_statuses;
  204.  
  205.         switch$parname )
  206.         {
  207.             case 't_status':
  208.                 // Text status:
  209.                 return T_$post_statuses[$this->status);
  210.         }
  211.  
  212.         return parent::get$parname );
  213.     }
  214.  
  215.  
  216.     /**
  217.      * Set param value
  218.      *
  219.      * @param string parameter name
  220.      * @param mixed parameter value
  221.      * @return boolean true, if a value has been set; false if it has not changed
  222.      */
  223.     function set$parname$parvalue )
  224.     {
  225.         switch$parname )
  226.         {
  227.             case 'rating':
  228.                 return parent::set_param$parname'string'$parvaluetrue );
  229.  
  230.             default:
  231.                 return parent::set_param$parname'string'$parvalue );
  232.         }
  233.     }
  234.  
  235.  
  236.     /**
  237.      * Set Item this comment relates to
  238.      * @param Item 
  239.      */
  240.     function set_Item$Item )
  241.     {
  242.         $this->Item = $Item;
  243.         $this->item_ID = $Item->ID;
  244.         parent::set_param'post_ID''number'$Item->ID );
  245.     }
  246.  
  247.  
  248.     /**
  249.      * Set author User of this comment
  250.      */
  251.     function set_author_User$author_User )
  252.     {
  253.         $this->author_User = $author_User;
  254.         parent::set_param'author_ID''number'$author_User->ID );
  255.     }
  256.  
  257.  
  258.     /**
  259.      * Set the spam karma, as a number.
  260.      * @param integer Spam karma (-100 - 100)
  261.      * @access protected
  262.      */
  263.     function set_spam_karma$spam_karma )
  264.     {
  265.         return parent::set_param'spam_karma''number'$spam_karma );
  266.     }
  267.  
  268.  
  269.     /**
  270.      * Get the anchor-ID of the comment
  271.      *
  272.      * @return string 
  273.      */
  274.     function get_anchor()
  275.     {
  276.         return 'c'.$this->ID;
  277.     }
  278.  
  279.  
  280.     /**
  281.      * Template function: display anchor for permalinks to refer to
  282.      */
  283.     function anchor()
  284.     {
  285.         echo '<a id="'.$this->get_anchor().'"></a>';
  286.     }
  287.  
  288.  
  289.     /**
  290.      * Get the comment author's name.
  291.      *
  292.      * @return string 
  293.      */
  294.     function get_author_name()
  295.     {
  296.         if$this->get_author_User() )
  297.         {
  298.             return $this->author_User->get_preferred_name();
  299.         }
  300.         else
  301.         {
  302.             return $this->author;
  303.         }
  304.     }
  305.  
  306.  
  307.     /**
  308.      * Get the EMail of the comment's author.
  309.      *
  310.      * @return string 
  311.      */
  312.     function get_author_email()
  313.     {
  314.         if$this->get_author_User() )
  315.         // Author is a user
  316.             return $this->author_User->get('email');
  317.         }
  318.         else
  319.         {
  320.             return $this->author_email;
  321.         }
  322.     }
  323.  
  324.  
  325.     /**
  326.      * Get the URL of the comment's author.
  327.      *
  328.      * @return string 
  329.      */
  330.     function get_author_url()
  331.     {
  332.         if$this->get_author_User() )
  333.         // Author is a user
  334.             return $this->author_User->get('url');
  335.         }
  336.         else
  337.         {
  338.             return $this->author_url;
  339.         }
  340.     }
  341.  
  342.  
  343.     /**
  344.      * Template function: display author of comment
  345.      *
  346.      * @param string String to display before author name if not a user
  347.      * @param string String to display after author name if not a user
  348.      * @param string String to display before author name if he's a user
  349.      * @param string String to display after author name if he's a user
  350.      * @param string Output format, see {@link format_to_output()}
  351.      * @param boolean true for link, false if you want NO html link
  352.      */
  353.     function author$before ''$after '#'$before_user ''$after_user '#',
  354.                                         $format 'htmlbody'$makelink false )
  355.     {
  356.         global $Plugins;
  357.  
  358.         if$this->get_author_User() )
  359.         // Author is a user
  360.             ifstrlen$this->author_User->url <= 10 )
  361.             {
  362.                 $makelink false;
  363.             }
  364.             if$after_user == '#' $after_user ' ['.T_('Member').']';
  365.  
  366.             $author_name format_to_output$this->author_User->get_preferred_name()$format );
  367.  
  368.             $before $before_user;
  369.             $after $after_user;
  370.  
  371.         }
  372.         else
  373.         // Display info recorded at edit time:
  374.             ifstrlen$this->author_url <= 10 )
  375.             {
  376.                 $makelink false;
  377.             }
  378.             if$after == '#' $after ' ['.T_('Visitor').']';
  379.  
  380.             $author_name $this->dget'author'$format );
  381.  
  382.         }
  383.  
  384.         if$makelink )
  385.         {    // Make a link:
  386.             $r $this->get_author_url_link$author_name$before$aftertrue );
  387.         }
  388.         else
  389.         {    // Display the name: (NOTE: get_author_url_link( with nolink option ) would NOT handle this correctly when url is empty
  390.             $r $before.$author_name.$after;
  391.         }
  392.  
  393.         $Plugins->trigger_event'FilterCommentAuthor'array'data' => $r'makelink' => $makelink'Comment' => $this ) );
  394.  
  395.         echo $r;
  396.     }
  397.  
  398.  
  399.     /**
  400.      * Template function: display comment's author's IP
  401.      *
  402.      * @param string String to display before IP, if IP exists
  403.      * @param string String to display after IP, if IP exists
  404.      */
  405.     function author_ip$before=''$after='' )
  406.     {
  407.         if!empty$this->author_IP ) )
  408.         {
  409.             global $Plugins;
  410.  
  411.             echo $before;
  412.             // Filter the IP by plugins for display, allowing e.g. the DNSBL plugin to add a link that displays info about the IP:
  413.             echo $Plugins->get_trigger_event'FilterIpAddress'array(
  414.                     'format'=>'htmlbody',
  415.                     'data' => $this->author_IP ),
  416.                 'data' );
  417.             echo $after;
  418.         }
  419.     }
  420.  
  421.  
  422.     /**
  423.      * Template function: display link to comment author's provided email
  424.      *
  425.      * @param string String to display for link: leave empty to display email
  426.      * @param string String to display before email, if email exists
  427.      * @param string String to display after email, if email exists
  428.      * @param boolean false if you want NO html link
  429.      */
  430.     function author_email$linktext=''$before=''$after=''$makelink true )
  431.     {
  432.         $email $this->get_author_email();
  433.  
  434.         ifstrlen$email )
  435.         // If email exists:
  436.             echo $before;
  437.             if$makelink echo '<a href="mailto:'.$email.'">';
  438.             echo ($linktext != ''$linktext $email;
  439.             if$makelink echo '</a>';
  440.             echo $after;
  441.         }
  442.     }
  443.  
  444.  
  445.     /**
  446.      * Get link to comment author's provided URL
  447.      *
  448.      * @param string String to display for link: leave empty to display URL
  449.      * @param string String to display before link, if link exists
  450.      * @param string String to display after link, if link exists
  451.      * @param boolean false if you want NO html link
  452.      * @return boolean true if URL has been displayed
  453.      */
  454.     function get_author_url_link$linktext=''$before=''$after=''$makelink true )
  455.     {
  456.         global $Plugins;
  457.  
  458.         $url $this->get_author_url();
  459.  
  460.         ifstrlen$url 10 )
  461.         {
  462.             return false;
  463.         }
  464.  
  465.         // If URL exists:
  466.         $r $before;
  467.         if$makelink )
  468.         {
  469.             $r .= '<a ';
  470.             if$this->nofollow )
  471.             {
  472.                 $r .= 'rel="nofollow" ';
  473.             }
  474.             $r .= 'href="'.$url.'">';
  475.         }
  476.         $r .= empty($linktext$url $linktext );
  477.         if$makelink $r .= '</a>';
  478.         $r .= $after;
  479.  
  480.         $Plugins->trigger_event'FilterCommentAuthorUrl'array'data' => $r'makelink' => $makelink'Comment' => $this ) );
  481.  
  482.         return $r;
  483.     }
  484.  
  485.  
  486.   /**
  487.      * Template function: display link to comment author's provided URL
  488.      *
  489.      * @param string String to display for link: leave empty to display URL
  490.      * @param string String to display before link, if link exists
  491.      * @param string String to display after link, if link exists
  492.      * @param boolean false if you want NO html link
  493.      * @return boolean true if URL has been displayed
  494.      */
  495.     function author_url$linktext=''$before=''$after=''$makelink true )
  496.     {
  497.         $r $this->get_author_url_link$linktext$before$after$makelink );
  498.         if!empty$r ) )
  499.         {
  500.             echo $r;
  501.             return true;
  502.         }
  503.         return false;
  504.     }
  505.  
  506.  
  507.     /**
  508.      * Template function: display spam karma of the comment (in percent)
  509.      *
  510.      * "%s" gets replaced by the karma value
  511.      *
  512.      * @param string Template string to display, if we have a karma value
  513.      * @param string Template string to display, if we have no karma value (pre-Phoenix)
  514.      */
  515.     function spam_karma$template '%s%'$template_unknown NULL )
  516.     {
  517.         ifisset($this->spam_karma) )
  518.         {
  519.             echo str_replace'%s'$this->spam_karma$template );
  520.         }
  521.         else
  522.         {
  523.             ifisset($template_unknown) )
  524.             {
  525.                 echo /* TRANS: "not available" */ T_('N/A');
  526.             }
  527.             else
  528.             {
  529.                 echo $template_unknown;
  530.             }
  531.         }
  532.     }
  533.  
  534.  
  535.     /**
  536.      * Provide link to edit a comment if user has edit rights
  537.      *
  538.      * @param string to display before link
  539.      * @param string to display after link
  540.      * @param string link text
  541.      * @param string link title
  542.      * @param string class name
  543.      * @return boolean 
  544.      */
  545.     function edit_link$before ' '$after ' '$text '#'$title '#'$class ''$glue '&amp;'$save_context true )
  546.     {
  547.         global $current_User$admin_url;
  548.  
  549.         ifis_logged_in() ) return false;
  550.  
  551.         ifempty($this->ID) )
  552.         {    // Happens in Preview
  553.             return false;
  554.         }
  555.  
  556.         $this->get_Item();
  557.  
  558.         if$current_User->check_perm'blog_comments'''false$this->Item->get'blog_ID' ) ) )
  559.         // If User has no permission to edit comments:
  560.             return false;
  561.         }
  562.  
  563.         if$text == '#' $text get_icon'edit' ).' '.T_('Edit...');
  564.         if$title == '#' $title T_('Edit this comment');
  565.  
  566.         echo $before;
  567.         echo '<a href="'.$admin_url.'?ctrl=comments&amp;action=edit&amp;comment_ID='.$this->ID;
  568.        if$save_context )
  569.         {
  570.             echo $glue.'redirect_to='.rawurlencoderegenerate_url'''''''&' ) );
  571.         }
  572.         echo '" title="'.$title.'"';
  573.         if!empty$class ) ) echo ' class="'.$class.'"';
  574.         echo '>'.$text.'</a>';
  575.         echo $after;
  576.  
  577.         return true;
  578.     }
  579.  
  580.  
  581.     /**
  582.      * Displays button for deleeing the Comment if user has proper rights
  583.      *
  584.      * @param string to display before link
  585.      * @param string to display after link
  586.      * @param string link text
  587.      * @param string link title
  588.      * @param string class name
  589.      * @param boolean true to make this a button instead of a link
  590.      */
  591.     function delete_link$before ' '$after ' '$text '#'$title '#'$class ''$button false$glue '&amp;'$save_context true )
  592.     {
  593.         global $current_User$admin_url;
  594.  
  595.         ifis_logged_in() ) return false;
  596.  
  597.         ifempty($this->ID) )
  598.         {    // Happens in Preview
  599.             return false;
  600.         }
  601.  
  602.         $this->get_Item();
  603.  
  604.         if$current_User->check_perm'blog_comments'''false$this->Item->get'blog_ID' ) ) )
  605.         // If User has permission to edit comments:
  606.             return false;
  607.         }
  608.  
  609.         if$text == '#' )
  610.         // Use icon+text as default, if not displayed as button (otherwise just the text)
  611.             if$button )
  612.             {
  613.                 $text get_icon'delete''imgtag' ).' '.T_('Delete!');
  614.             }
  615.             else
  616.             {
  617.                 $text T_('Delete!');
  618.             }
  619.         }
  620.         if$title == '#' $title T_('Delete this comment');
  621.  
  622.         $url $admin_url.'?ctrl=comments&amp;action=delete&amp;comment_ID='.$this->ID;
  623.        if$save_context )
  624.         {
  625.             $url .= $glue.'redirect_to='.rawurlencoderegenerate_url'''''''&' ) );
  626.         }
  627.  
  628.         echo $before;
  629.         if$button )
  630.         // Display as button
  631.             echo '<input type="button"';
  632.             echo ' value="'.$text.'" title="'.$title.'" onclick="if ( confirm(\'';
  633.             echo TS_('You are about to delete this comment!\\nThis cannot be undone!');
  634.             echo '\') ) { document.location.href=\''.$url.'\' }"';
  635.             if!empty$class ) ) echo ' class="'.$class.'"';
  636.             echo '/>';
  637.         }
  638.         else
  639.         // Display as link
  640.             echo '<a href="'.$url.'" title="'.$title.'" onclick="return confirm(\'';
  641.             echo TS_('You are about to delete this comment!\\nThis cannot be undone!');
  642.             echo '\')"';
  643.             if!empty$class ) ) echo ' class="'.$class.'"';
  644.             echo '>'.$text.'</a>';
  645.         }
  646.         echo $after;
  647.  
  648.         return true;
  649.     }
  650.  
  651.  
  652.     /**
  653.      * Provide link to deprecate a comment if user has edit rights
  654.      *
  655.      * @param string to display before link
  656.      * @param string to display after link
  657.      * @param string link text
  658.      * @param string link title
  659.      * @param string class name
  660.      * @param string glue between url params
  661.      * @param boolean save context?
  662.      */
  663.     function get_deprecate_link$before ' '$after ' '$text '#'$title '#'$class ''$glue '&amp;'$save_context true )
  664.     {
  665.         global $current_User$admin_url;
  666.  
  667.         ifis_logged_in() ) return false;
  668.  
  669.         $this->get_Item();
  670.  
  671.         if( ($this->status == 'deprecated'// Already deprecateded!
  672.             || $current_User->check_perm'blog_comments'''false$this->Item->get'blog_ID' ) ) )
  673.         // If User has permission to edit comments:
  674.             return false;
  675.         }
  676.  
  677.         if$text == '#' $text get_icon'deprecate''imgtag' ).' '.T_('Deprecate!');
  678.         if$title == '#' $title T_('Deprecate this comment!');
  679.  
  680.         $r $before;
  681.         $r .= '<a href="';
  682.         $r .= $admin_url.'?ctrl=comments'.$glue.'action=deprecate'.$glue.'comment_ID='.$this->ID;
  683.        if$save_context )
  684.         {
  685.             $r .= $glue.'redirect_to='.rawurlencoderegenerate_url'''''''&' ) );
  686.         }
  687.         $r .= '" title="'.$title.'"';
  688.         if!empty$class ) ) $r .= ' class="'.$class.'"';
  689.         $r .= '>'.$text.'</a>';
  690.         $r .= $after;
  691.  
  692.         return $r;
  693.     }
  694.  
  695.  
  696.     /**
  697.      * Display link to deprecate a comment if user has edit rights
  698.      *
  699.      * @param string to display before link
  700.      * @param string to display after link
  701.      * @param string link text
  702.      * @param string link title
  703.      * @param string class name
  704.      * @param string glue between url params
  705.      * @param boolean save context?
  706.      */
  707.     function deprecate_link$before ' '$after ' '$text '#'$title '#'$class ''$glue '&amp;'$save_context true )
  708.     {
  709.         echo $this->get_deprecate_link$before$after$text$title$class$glue$save_context );
  710.     }
  711.  
  712.  
  713.     /**
  714.      * Provide link to publish a comment if user has edit rights
  715.      *
  716.      * @param string to display before link
  717.      * @param string to display after link
  718.      * @param string link text
  719.      * @param string link title
  720.      * @param string class name
  721.      * @param string glue between url params
  722.      * @param boolean save context?
  723.      */
  724.     function get_publish_link$before ' '$after ' '$text '#'$title '#'$class ''$glue '&amp;'$save_context true )
  725.     {
  726.         global $current_User$admin_url;
  727.  
  728.         ifis_logged_in() ) return false;
  729.  
  730.         $this->get_Item();
  731.  
  732.         if( ($this->status == 'published'// Already published!
  733.             || $current_User->check_perm'blog_comments'''false$this->Item->get'blog_ID' ) ) )
  734.         // If User has permission to edit comments:
  735.             return false;
  736.         }
  737.  
  738.         if$text == '#' $text get_icon'publish''imgtag' ).' '.T_('Publish!');
  739.         if$title == '#' $title T_('Publish this comment!');
  740.  
  741.         $r $before;
  742.         $r .= '<a href="';
  743.         $r .= $admin_url.'?ctrl=comments'.$glue.'action=publish'.$glue.'comment_ID='.$this->ID;
  744.        if$save_context )
  745.         {
  746.             $r .= $glue.'redirect_to='.rawurlencoderegenerate_url'''''''&' ) );
  747.         }
  748.         $r .= '" title="'.$title.'"';
  749.         if!empty$class ) ) $r .= ' class="'.$class.'"';
  750.         $r .= '>'.$text.'</a>';
  751.         $r .= $after;
  752.  
  753.         return $r;
  754.     }
  755.  
  756.  
  757.     /**
  758.      * Display link to publish a comment if user has edit rights
  759.      *
  760.      * @param string to display before link
  761.      * @param string to display after link
  762.      * @param string link text
  763.      * @param string link title
  764.      * @param string class name
  765.      * @param string glue between url params
  766.      * @param boolean save context?
  767.      */
  768.     function publish_link$before ' '$after ' '$text '#'$title '#'$class ''$glue '&amp;'$save_context true )
  769.     {
  770.         echo $this->get_publish_link$before$after$text$title$class$glue$save_context );
  771.     }
  772.  
  773.  
  774.     /**
  775.      * Provide link to message form for this comment's author
  776.      *
  777.      * @param string url of the message form
  778.      * @param string to display before link
  779.      * @param string to display after link
  780.      * @param string link text
  781.      * @param string link title
  782.      * @param string class name
  783.      */
  784.     function msgform_link$form_url$before ' '$after ' '$text '#'$title '#'$class '' )
  785.     {
  786.         if$this->get_author_User() )
  787.         // This comment is from a registered user:
  788.             ifempty($this->author_User->email) )
  789.             // We have no email for this Author :(
  790.                 return false;
  791.             }
  792.             elseifempty($this->author_User->allow_msgform) )
  793.             // User does not allow message form
  794.                 return false;
  795.             }
  796.             $form_url url_add_param$form_url'recipient_id='.$this->author_User->ID );
  797.         }
  798.         else
  799.         // This comment is from a visitor:
  800.             ifempty($this->author_email) )
  801.             // We have no email for this comment :(
  802.                 return false;
  803.             }
  804.             elseifempty($this->allow_msgform) )
  805.             // Anonymous commentator does not allow message form (for this comment)
  806.                 return false;
  807.             }
  808.         }
  809.  
  810.         $form_url url_add_param$form_url'comment_id='.$this->ID.'&amp;post_id='.$this->item_ID
  811.                 .'&amp;redirect_to='.rawurlencode(url_rel_to_same_host(regenerate_url('','','','&')$form_url)) );
  812.  
  813.         if$title == '#' $title T_('Send email to comment author');
  814.         if$text == '#' $text get_icon'email''imgtag'array'class' => 'middle''title' => $title ) );
  815.  
  816.         echo $before;
  817.         echo '<a href="'.$form_url.'" title="'.$title.'"';
  818.         if!empty$class ) ) echo ' class="'.$class.'"';
  819.         echo '>'.$text.'</a>';
  820.         echo $after;
  821.  
  822.         return true;
  823.     }
  824.  
  825.  
  826.     /**
  827.      * Generate permalink to this comment.
  828.      *
  829.      * Note: This actually only returns the URL, to get a real link, use Comment::get_permanent_link()
  830.      */
  831.     function get_permanent_url()
  832.     {
  833.         $this->get_Item();
  834.  
  835.         $post_permalink $this->Item->get_single_url'auto' );
  836.  
  837.         return $post_permalink.'#'.$this->get_anchor();
  838.     }
  839.  
  840.  
  841.     /**
  842.      * Template function: display permalink to this comment
  843.      *
  844.      * Note: This actually only returns the URL, to get a real link, use Comment::permanent_link()
  845.      *
  846.      * @param string 'urltitle', 'pid', 'archive#id' or 'archive#title'
  847.      * @param string url to use
  848.      */
  849.     function permanent_url$mode ''$blogurl='' )
  850.     {
  851.         echo $this->get_permanent_url$mode$blogurl );
  852.     }
  853.  
  854.  
  855.     /**
  856.      * Returns a permalink link to the Comment
  857.      *
  858.      * Note: If you only want the permalink URL, use Comment::get_permanent_url()
  859.      *
  860.      * @param string link text or special value: '#', '#icon#', '#text#'
  861.      * @param string link title
  862.      * @param string class name
  863.      */
  864.     function get_permanent_link$text '#'$title '#'$class ''$nofollow false )
  865.     {
  866.         global $current_User$baseurl;
  867.  
  868.         switch$text )
  869.         {
  870.             case '#':
  871.                 $text get_icon'permalink' ).T_('Permalink');
  872.                 break;
  873.  
  874.             case '#icon#':
  875.                 $text get_icon'permalink' );
  876.                 break;
  877.  
  878.             case '#text#':
  879.                 $text T_('Permalink');
  880.                 break;
  881.         }
  882.  
  883.         if$title == '#' $title T_('Permanent link to this comment');
  884.  
  885.         $url $this->get_permanent_url();
  886.  
  887.         // Display as link
  888.         $r '<a href="'.$url.'" title="'.$title.'"';
  889.         if!empty$class ) ) $r .= ' class="'.$class.'"';
  890.         if!empty$nofollow ) ) $r .= ' rel="nofollow"';
  891.         $r .= '>'.$text.'</a>';
  892.  
  893.         return $r;
  894.     }
  895.  
  896.  
  897.     /**
  898.      * Displays a permalink link to the Comment
  899.      *
  900.      * Note: If you only want the permalink URL, use Comment::permanent_url()
  901.      */
  902.     function permanent_link$params array() )
  903.     {
  904.         // Make sure we are not missing any param:
  905.         $params array_mergearray(
  906.                 'before'      => ' ',
  907.                 'after'       => ' ',
  908.                 'text'        => '#',
  909.                 'title'       => '#',
  910.                 'class'       => '',
  911.                 'nofollow'    => false,
  912.             )$params );
  913.  
  914.         echo $params['before'];
  915.         echo $this->get_permanent_link$params['text']$params['title']$params['class']$params['nofollow');
  916.         echo $params['after'];
  917.     }
  918.  
  919.  
  920.     /**
  921.      * Template function: get content of comment
  922.      *
  923.      * @param string Output format, see {@link format_to_output()}
  924.      * @return string 
  925.      */
  926.     function get_content$format 'htmlbody' )
  927.     {
  928.         global $Plugins;
  929.  
  930.         $comment $this->content;
  931.         // fp> obsolete: $comment = str_replace('<trackback />', '', $comment);
  932.         $Plugins->trigger_event'FilterCommentContent'array'data' => $comment'Comment' => $this ) );
  933.         $comment format_to_output$comment$format );
  934.  
  935.         return $comment;
  936.     }
  937.  
  938.  
  939.     /**
  940.      * Template function: display content of comment
  941.      *
  942.      * @param string Output format, see {@link format_to_output()}
  943.      */
  944.     function content$format 'htmlbody' )
  945.     {
  946.         echo $this->get_content$format );
  947.     }
  948.  
  949.  
  950.     /**
  951.      * Template function: display date (datetime) of comment
  952.      *
  953.      * @param string date/time format: leave empty to use locale default date format
  954.      * @param boolean true if you want GMT
  955.      */
  956.     function date$format=''$useGM false )
  957.     {
  958.         ifempty($format) )
  959.             echo mysql2datelocale_datefmt()$this->date$useGM);
  960.         else
  961.             echo mysql2date$format$this->date$useGM);
  962.     }
  963.  
  964.  
  965.     /**
  966.      * Template function: display time (datetime) of comment
  967.      *
  968.      * @param string date/time format: leave empty to use locale default time format
  969.      * @param boolean true if you want GMT
  970.      */
  971.     function time$format=''$useGM false )
  972.     {
  973.         ifempty($format) )
  974.             echo mysql2datelocale_timefmt()$this->date$useGM );
  975.         else
  976.             echo mysql2date$format$this->date$useGM );
  977.     }
  978.  
  979.  
  980.     /**
  981.      * Template tag:  display rating
  982.      */
  983.     function rating$params array() )
  984.     {
  985.         ifempty$this->rating ) )
  986.         {
  987.             return false;
  988.         }
  989.  
  990.         // Make sure we are not missing any param:
  991.         $params array_mergearray(
  992.                 'before'      => '<div class="comment_rating">',
  993.                 'after'       => '</div>',
  994.             )$params );
  995.  
  996.         echo $params['before'];
  997.  
  998.         for$i=1$i<=5$i++ )
  999.         {
  1000.             if$i <= $this->rating )
  1001.             {
  1002.                 echo get_icon'star_on''imgtag'array'class'=>'middle' ) );
  1003.             }
  1004.             else
  1005.             {
  1006.                 echo get_icon'star_off''imgtag'array'class'=>'middle' ) );
  1007.             }
  1008.         }
  1009.  
  1010.         echo $params['after'];
  1011.     }
  1012.  
  1013.   /**
  1014.      * Rating input
  1015.      */
  1016.     function rating_input$params array() )
  1017.     {
  1018.         $params array_mergearray(
  1019.                                     'before'    => '',
  1020.                                     'after'     => '',
  1021.                                     'label_low'  => T_('Poor'),
  1022.                                     'label_high' => T_('Excellent'),
  1023.                                 )$params );
  1024.  
  1025.         echo $params['before'];
  1026.  
  1027.         echo $params['label_low'];
  1028.  
  1029.         for$i=1$i<=5$i++ )
  1030.         {
  1031.             echo '<input type="radio" class="radio" name="comment_rating" value="'.$i.'"';
  1032.             if$this->rating == $i )
  1033.             {
  1034.                 echo ' checked="checked"';
  1035.             }
  1036.             echo ' />';
  1037.         }
  1038.  
  1039.         echo $params['label_high'];
  1040.  
  1041.         echo $params['after'];
  1042.     }
  1043.  
  1044.  
  1045.   /**
  1046.      * Rating reset input
  1047.      */
  1048.     function rating_none_input$params array() )
  1049.     {
  1050.         $params array_mergearray(
  1051.                                     'before'    => '',
  1052.                                     'after'     => '',
  1053.                                     'label'     => T_('No rating'),
  1054.                                 )$params );
  1055.  
  1056.         echo $params['before'];
  1057.  
  1058.         echo '<label><input type="radio" class="radio" name="comment_rating" value="0"';
  1059.         ifempty($this->rating) )
  1060.         {
  1061.             echo ' checked="checked"';
  1062.         }
  1063.         echo ' />';
  1064.  
  1065.         echo $params['label'].'</label>';
  1066.  
  1067.         echo $params['after'];
  1068.     }
  1069.  
  1070.  
  1071.     /**
  1072.      * Template function: display status of comment
  1073.      *
  1074.      * Statuses:
  1075.      * - published
  1076.      * - deprecated
  1077.      * - protected
  1078.      * - private
  1079.      * - draft
  1080.      *
  1081.      * @param string Output format, see {@link format_to_output()}
  1082.      */
  1083.     function status$format 'htmlbody' )
  1084.     {
  1085.         global $post_statuses;
  1086.  
  1087.         if$format == 'raw' )
  1088.         {
  1089.             $this->disp'status''raw' );
  1090.         }
  1091.         else
  1092.         {
  1093.             echo format_to_output$this->get('t_status')$format );
  1094.         }
  1095.     }
  1096.  
  1097.  
  1098.     /**
  1099.      * Send email notifications to subscribed users:
  1100.      *
  1101.      * @todo fp> SEPARATE MODERATION notifications from SUBSCRIPTION notifications
  1102.      * @todo shall we notify suscribers of blog were this is in extra-cat?
  1103.      * @todo cache message by locale like {@link Item::send_email_notifications()}
  1104.      * @todo dh> Indicator in url to see where the user came from (&from=subnote ["subscription notification"]) - Problem: too long urls.
  1105.      * @todo dh> "Beautify" like {@link Item::send_email_notifications()} ? fp > sure
  1106.      * @todo Should include "visibility status" in the mail to the Item's Author
  1107.      */
  1108.     function send_email_notifications()
  1109.     {
  1110.         global $DB$admin_url$debug$Debuglog;
  1111.  
  1112.         $edited_Item $this->get_Item();
  1113.         $edited_Blog $edited_Item->get_Blog();
  1114.  
  1115.         $notify_array array();
  1116.  
  1117.         if$edited_Blog->get_setting'allow_subscriptions' ) )
  1118.         {    // Get list of users who want to be notfied:
  1119.             // TODO: also use extra cats/blogs??
  1120.             // So far you get notifications for everything. We'll need a setting to decide if you want to received unmoderated (aka unpublished) comments or not.
  1121.             // Note: users receive comments on their own posts. This is done on purpose. Otherwise they think it's broken when they test the app.
  1122.             $sql 'SELECT DISTINCT user_email, user_locale
  1123.                                 FROM T_subscriptions INNER JOIN T_users ON sub_user_ID = user_ID
  1124.                              WHERE sub_coll_ID = '.$this->Item->blog_ID.'
  1125.                                AND sub_comments <> 0
  1126.                                AND LENGTH(TRIM(user_email)) > 0';
  1127.             $notify_list $DB->get_results$sql );
  1128.  
  1129.             // Preprocess list:
  1130.             foreach$notify_list as $notification )
  1131.             {
  1132.                 $notify_array[$notification->user_email$notification->user_locale;
  1133.             }
  1134.         }
  1135.  
  1136.         // Check if we need to include the author:
  1137.         $item_author_User $edited_Item->get_creator_User();
  1138.         if$item_author_User->notify
  1139.                 && empty$item_author_User->email ) ) )
  1140.         // Author wants to be notified...
  1141.             if($this->get_author_User(// comment is from registered user
  1142.                             && $item_author_User->login == $this->author_User->login) ) // comment is from same user as post
  1143.                 {    // Author is not commenting on his own post...
  1144.                     $notify_array[$item_author_User->email$item_author_User->locale;
  1145.                 }
  1146.         }
  1147.  
  1148.         ifcount($notify_array) )
  1149.         // No-one to notify:
  1150.             return false;
  1151.         }
  1152.  
  1153.  
  1154.         /*
  1155.          * We have a list of email addresses to notify:
  1156.          */
  1157.         // TODO: dh> this reveals the comments author's email address to all subscribers!!
  1158.         //           $notify_from should get used by default, unless the user has opted in to be the sender!
  1159.         // fp>If the subscriber has permission to moderate the comments, he SHOULD receive the email address.
  1160.         if$this->get_author_User() )
  1161.         // Comment from a registered user:
  1162.             $mail_from '"'.$this->author_User->get('preferredname').'" <'.$this->author_User->get('email').'>';
  1163.         }
  1164.         elseifempty$this->author_email ) )
  1165.         // non-member, but with email address:
  1166.             $mail_from "\"$this->author\" <$this->author_email>";
  1167.         }
  1168.         else
  1169.         // Fallback (we have no email address):  fp>TODO: or the subscriber is not allowed to view it.
  1170.             global $notify_from;
  1171.             $mail_from $notify_from;
  1172.         }
  1173.  
  1174.         // Send emails:
  1175.         foreach$notify_array as $notify_email => $notify_locale )
  1176.         {
  1177.             locale_temp_switch($notify_locale);
  1178.  
  1179.             switch$this->type )
  1180.             {
  1181.                 case 'trackback':
  1182.                     /* TRANS: Subject of the mail to send on new trackbacks. First %s is the blog's shortname, the second %s is the item's title. */
  1183.                     $subject T_('[%s] New trackback on "%s"');
  1184.                     break;
  1185.  
  1186.                 default:
  1187.                     /* TRANS: Subject of the mail to send on new comments. First %s is the blog's shortname, the second %s is the item's title. */
  1188.                     $subject T_('[%s] New comment on "%s"');
  1189.             }
  1190.  
  1191.             $subject sprintf$subject$edited_Blog->get('shortname')$edited_Item->get('title') );
  1192.  
  1193.             $notify_message T_('Blog').': '.$edited_Blog->get('shortname')."\n"
  1194.                 // Mail bloat: .' ( '.str_replace('&amp;', '&', $edited_Blog->gen_blogurl())." )\n"
  1195.                 .T_('Post').': '.$edited_Item->get('title')."\n";
  1196.                 // Mail bloat: .' ( '.str_replace('&amp;', '&', $edited_Item->get_permanent_url())." )\n";
  1197.                 // TODO: fp> We MAY want to force short URL and avoid it to wrap on a new line in the mail which may prevent people from clicking
  1198.  
  1199.             switch$this->type )
  1200.             {
  1201.                 case 'trackback':
  1202.                     $user_domain gethostbyaddr($this->author_IP);
  1203.                     $notify_message .= T_('Website')."$this->author (IP: $this->author_IP$user_domain)\n";
  1204.                     $notify_message .= T_('Url')."$this->author_url\n";
  1205.                     break;
  1206.  
  1207.                 default:
  1208.                     if$this->get_author_User() )
  1209.                     // Comment from a registered user:
  1210.                         $notify_message .= T_('Author').': '.$this->author_User->get('preferredname').' ('.$this->author_User->get('login').")\n";
  1211.                     }
  1212.                     else
  1213.                     // Comment from visitor:
  1214.                         $user_domain gethostbyaddr($this->author_IP);
  1215.                         $notify_message .= T_('Author')."$this->author (IP: $this->author_IP$user_domain)\n";
  1216.                         $notify_message .= T_('Email')."$this->author_email\n";
  1217.                         $notify_message .= T_('Url')."$this->author_url\n";
  1218.                     }
  1219.             }
  1220.  
  1221.             $notify_message .=
  1222.                 T_('Comment').': '.str_replace('&amp;''&'$this->get_permanent_url())."\n"
  1223.                 // TODO: fp> We MAY want to force a short URL and avoid it to wrap on a new line in the mail which may prevent people from clicking
  1224.                 .$this->get('content')."\n\n"
  1225.                 .T_('Edit/Delete').': '.$admin_url.'?ctrl=items&blog='.$edited_Blog->ID.'&p='.$edited_Item->ID.'&c=1#c'.$this->ID."\n\n"
  1226.                 .T_('Edit your subscriptions/notifications').': '.str_replace('&amp;''&'url_add_param$edited_Blog->gen_blogurl()'disp=subs' ) )."\n";
  1227.  
  1228.             if$debug )
  1229.             {
  1230.                 $mail_dump "Sending notification to $notify_email:<pre>Subject: $subject\n$notify_message</pre>";
  1231.  
  1232.                 if$debug >= )
  1233.                 // output mail content - NOTE: this will kill sending of headers.
  1234.                     echo "<p>$mail_dump</p>";
  1235.                 }
  1236.  
  1237.                 $Debuglog->add$mail_dump'notification' );
  1238.             }
  1239.  
  1240.             send_mail$notify_email$subject$notify_message$mail_from );
  1241.  
  1242.             locale_restore_previous();
  1243.         }
  1244.     }
  1245.  
  1246.  
  1247.     /**
  1248.      * Trigger event AfterCommentUpdate after calling parent method.
  1249.      *
  1250.      * @return boolean true on success
  1251.      */
  1252.     function dbupdate()
  1253.     {
  1254.         global $Plugins;
  1255.  
  1256.         $dbchanges $this->dbchanges;
  1257.  
  1258.         if$r parent::dbupdate() )
  1259.         {
  1260.             $Plugins->trigger_event'AfterCommentUpdate'$params array'Comment' => $this'dbchanges' => $dbchanges ) );
  1261.         }
  1262.  
  1263.         return $r;
  1264.     }
  1265.  
  1266.  
  1267.     /**
  1268.      * Get karma and set it before adding the Comment to DB.
  1269.      *
  1270.      * @return boolean true on success, false if it did not get inserted
  1271.      */
  1272.     function dbinsert()
  1273.     {
  1274.         /**
  1275.          * @var Plugins
  1276.          */
  1277.         global $Plugins;
  1278.         global $Settings;
  1279.  
  1280.         // Get karma percentage (interval -100 - 100)
  1281.         $spam_karma $Plugins->trigger_karma_collect'GetSpamKarmaForComment'array'Comment' => $this ) );
  1282.  
  1283.         $this->set_spam_karma$spam_karma );
  1284.  
  1285.         // Change status accordingly:
  1286.         ifis_null($spam_karma) )
  1287.         {
  1288.             if$spam_karma $Settings->get('antispam_threshold_publish') )
  1289.             // Publish:
  1290.                 $this->set'status''published' );
  1291.             }
  1292.             elseif$spam_karma $Settings->get('antispam_threshold_delete') )
  1293.             // Delete/No insert:
  1294.                 return false;
  1295.             }
  1296.         }
  1297.  
  1298.         $dbchanges $this->dbchanges;
  1299.  
  1300.         if$r parent::dbinsert() )
  1301.         {
  1302.             $Plugins->trigger_event'AfterCommentInsert'$params array'Comment' => $this'dbchanges' => $dbchanges ) );
  1303.         }
  1304.  
  1305.         return $r;
  1306.     }
  1307.  
  1308.  
  1309.     /**
  1310.      * Trigger event AfterCommentDelete after calling parent method.
  1311.      *
  1312.      * @return boolean true on success
  1313.      */
  1314.     function dbdelete()
  1315.     {
  1316.         global $Plugins;
  1317.  
  1318.         // remember ID, because parent method resets it to 0
  1319.         $old_ID $this->ID;
  1320.  
  1321.         if$r parent::dbdelete() )
  1322.         {
  1323.             // re-set the ID for the Plugin event
  1324.             $this->ID = $old_ID;
  1325.  
  1326.             $Plugins->trigger_event'AfterCommentDelete'$params array'Comment' => $this ) );
  1327.  
  1328.             $this->ID = 0;
  1329.         }
  1330.  
  1331.         return $r;
  1332.     }
  1333.  
  1334. }
  1335.  
  1336.  
  1337. /*
  1338.  * $Log: _comment.class.php,v $
  1339.  * Revision 1.14.2.1  2009/01/27 00:45:54  blueyed
  1340.  *  - MFH: Fix for Comment::get_author_name, which echos and returns
  1341.  *    for registered users. Thanks Walter.
  1342.  *  - Version 2.4.7-dev
  1343.  *
  1344.  * Revision 1.14  2008/01/21 09:35:27  fplanque
  1345.  * (c) 2008
  1346.  *
  1347.  * Revision 1.13  2008/01/11 19:18:29  fplanque
  1348.  * bugfixes
  1349.  *
  1350.  * Revision 1.12  2008/01/10 19:59:51  fplanque
  1351.  * reduced comment PITA
  1352.  *
  1353.  * Revision 1.11  2008/01/08 20:15:21  personman2
  1354.  * Post author no longer gets emails when he comments on his own post
  1355.  *
  1356.  * Revision 1.10  2007/12/28 13:45:33  fplanque
  1357.  * bugfix again
  1358.  *
  1359.  * Revision 1.9  2007/12/28 13:24:29  fplanque
  1360.  * bugfix
  1361.  *
  1362.  * Revision 1.8  2007/12/26 20:04:26  fplanque
  1363.  * fixed missing nofollow handling
  1364.  *
  1365.  * Revision 1.7  2007/12/23 20:10:49  fplanque
  1366.  * removed suspects
  1367.  *
  1368.  * Revision 1.6  2007/12/22 17:24:35  fplanque
  1369.  * cleanup
  1370.  *
  1371.  * Revision 1.5  2007/12/18 23:51:32  fplanque
  1372.  * nofollow handling in comment urls
  1373.  *
  1374.  * Revision 1.4  2007/11/03 04:56:03  fplanque
  1375.  * permalink / title links cleanup
  1376.  *
  1377.  * Revision 1.3  2007/11/02 01:50:54  fplanque
  1378.  * comment ratings
  1379.  *
  1380.  * Revision 1.2  2007/09/04 19:51:26  fplanque
  1381.  * in-context comment editing
  1382.  *
  1383.  * Revision 1.1  2007/06/25 10:59:40  fplanque
  1384.  * MODULES (refactored MVC)
  1385.  *
  1386.  * Revision 1.65  2007/05/28 15:18:30  fplanque
  1387.  * cleanup
  1388.  *
  1389.  * Revision 1.64  2007/05/20 20:54:49  fplanque
  1390.  * better comment moderation links
  1391.  *
  1392.  * Revision 1.63  2007/04/26 00:11:08  fplanque
  1393.  * (c) 2007
  1394.  *
  1395.  * Revision 1.62  2007/03/24 20:41:16  fplanque
  1396.  * Refactored a lot of the link junk.
  1397.  * Made options blog specific.
  1398.  * Some junk still needs to be cleaned out. Will do asap.
  1399.  *
  1400.  * Revision 1.61  2007/03/22 00:03:40  blueyed
  1401.  * Escape author_url and author_User->url in author_url() template function
  1402.  *
  1403.  * Revision 1.60  2007/03/11 23:57:06  fplanque
  1404.  * item editing: allow setting to 'redirected' status
  1405.  *
  1406.  * Revision 1.59  2007/02/28 23:37:52  blueyed
  1407.  * doc
  1408.  *
  1409.  * Revision 1.58  2007/02/25 01:34:19  fplanque
  1410.  * doc
  1411.  *
  1412.  * Revision 1.57  2007/02/21 23:59:00  blueyed
  1413.  * Trigger FilterIpAddress event in author_ip()
  1414.  *
  1415.  * Revision 1.56  2006/12/26 00:08:29  fplanque
  1416.  * wording
  1417.  *
  1418.  * Revision 1.55  2006/12/16 01:30:46  fplanque
  1419.  * Setting to allow/disable email subscriptions on a per blog basis
  1420.  *
  1421.  * Revision 1.54  2006/12/12 02:53:56  fplanque
  1422.  * Activated new item/comments controllers + new editing navigation
  1423.  * Some things are unfinished yet. Other things may need more testing.
  1424.  *
  1425.  * Revision 1.53  2006/12/07 23:13:10  fplanque
  1426.  * @var needs to have only one argument: the variable type
  1427.  * Otherwise, I can't code!
  1428.  *
  1429.  * Revision 1.52  2006/12/03 18:10:22  fplanque
  1430.  * Not releasable. Discussion by email.
  1431.  *
  1432.  * Revision 1.51  2006/11/26 02:30:39  fplanque
  1433.  * doc / todo
  1434.  *
  1435.  * Revision 1.50  2006/11/17 18:36:23  blueyed
  1436.  * dbchanges param for AfterItemUpdate, AfterItemInsert, AfterCommentUpdate and AfterCommentInsert
  1437.  *
  1438.  * Revision 1.49  2006/11/16 22:41:59  blueyed
  1439.  * Fixed email from address in notifications, but also added TODO
  1440.  *
  1441.  * Revision 1.48  2006/11/16 19:23:12  fplanque
  1442.  * minor
  1443.  *
  1444.  * Revision 1.47  2006/11/14 21:02:57  blueyed
  1445.  * TODO
  1446.  *
  1447.  * Revision 1.46  2006/11/06 00:05:36  blueyed
  1448.  * Encoding of "&" in Comment::author_url makes no sense, should get done on output.
  1449.  *
  1450.  * Revision 1.45  2006/11/05 22:12:35  blueyed
  1451.  * Fix
  1452.  *
  1453.  * Revision 1.44  2006/10/23 22:19:02  blueyed
  1454.  * Fixed/unified encoding of redirect_to param. Use just rawurlencode() and no funky &amp; replacements
  1455.  *
  1456.  * Revision 1.43  2006/10/18 00:03:50  blueyed
  1457.  * Some forgotten url_rel_to_same_host() additions
  1458.  */
  1459. ?>

Documentation generated on Sat, 06 Mar 2010 03:30:26 +0100 by phpDocumentor 1.4.2. This site is hosted and maintained by Daniel HAHLER (Contact).