• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List

system/classes/comment.php

00001 <?php
00007 namespace Habari;
00008 
00035 class Comment extends QueryRecord implements IsContent
00036 {
00037   private $post_object = null;
00038 
00039   private $inforecords = null;
00040 
00041   // static variables to hold comment status and comment type values
00042   static $comment_status_list = array();
00043   static $comment_type_list = array();
00044   static $comment_status_actions = array();
00045 
00050   public static function default_fields()
00051   {
00052     return array(
00053       'id' => 0,
00054       'post_id' => 0,
00055       'name' => '',
00056       'email' => '',
00057       'url' => '',
00058       'ip' => 0,
00059       'content' => '',
00060       'status' => self::status('unapproved'),
00061       'date' => DateTime::create(),
00062       'type' => self::type('comment')
00063     );
00064   }
00065 
00070   public function __construct( $paramarray = array() )
00071   {
00072     // Defaults
00073     $this->fields = array_merge( self::default_fields(), $this->fields );
00074     parent::__construct( $paramarray );
00075     $this->exclude_fields( 'id' );
00076   }
00077 
00082   public static function __static()
00083   {
00084     Pluggable::load_hooks(__CLASS__);
00085   }
00086 
00098   static function get( $id = 0 )
00099   {
00100     if ( ! $id ) {
00101       return false;
00102     }
00103     return DB::get_row( 'SELECT * FROM {comments} WHERE id = ?', array( $id ), 'Comment' );
00104   }
00105 
00112   static function create( $paramarray )
00113   {
00114     $comment = new Comment( $paramarray );
00115     $comment->insert();
00116     return $comment;
00117   }
00118 
00123   public function insert()
00124   {
00125     $allow = true;
00126     $allow = Plugins::filter( 'comment_insert_allow', $allow, $this );
00127     if ( ! $allow ) {
00128       return false;
00129     }
00130     Plugins::act( 'comment_insert_before', $this );
00131     // Invoke plugins for all fields, since they're all "changed" when inserted
00132     foreach ( $this->fields as $fieldname => $value ) {
00133       Plugins::act( 'comment_update_' . $fieldname, $this, $this->$fieldname, $value );
00134     }
00135     $result = parent::insertRecord( DB::table( 'comments' ) );
00136     $this->newfields['id'] = DB::last_insert_id(); // Make sure the id is set in the comment object to match the row id
00137     $this->fields = array_merge( $this->fields, $this->newfields );
00138     $this->newfields = array();
00139     $this->info->commit( $this->fields['id'] );
00140     Plugins::act( 'comment_insert_after', $this );
00141     return $result;
00142   }
00143 
00149   public static function add_type($type)
00150   {
00151     DB::insert(
00152       DB::table('commenttype'),
00153       array(
00154         'name' => $type,
00155         'active' => 1,
00156       )
00157     );
00158     return DB::last_insert_id();
00159   }
00160 
00167   public static function add_status($status, $internal = false)
00168   {
00169     DB::insert(
00170       DB::table('commentstatus'),
00171       array(
00172         'name' => $status,
00173         'internal' => $internal ? 1 : 0,
00174       )
00175     );
00176     return DB::last_insert_id();
00177   }
00178 
00184   public static function remove_type($type, $delete = false)
00185   {
00186     if($delete) {
00187       // Delete comments of this type, delete type
00188       $type_id = Comment::type($type);
00189       DB::delete(
00190         DB::table('comments'),
00191         array('type' => $type_id)
00192       );
00193       DB::exec('DELETE FROM {commentinfo} WHERE comment_id IN (SELECT {commentinfo}.comment_id FROM {commentinfo} LEFT JOIN {comments} ON {commentinfo}.comment_id = {comments}.id WHERE {comments}.id IS NULL)');
00194       DB::delete(
00195         DB::table('commenttype'),
00196         array('name' => Comment::type_name($type))
00197       );
00198     }
00199     else {
00200       DB::update(
00201         DB::table('commenttype'),
00202         array(
00203           'name' => Comment::type_name($type),
00204           'active' => 0,
00205         ),
00206         array('name')
00207       );
00208     }
00209   }
00210 
00216   public static function remove_status($status, $newstatus = null)
00217   {
00218     // Delete comments of this status, delete status
00219     $status_id = Comment::status($status);
00220     if(is_null($newstatus)) {
00221       DB::delete(
00222         DB::table('comments'),
00223         array('status' => $status_id)
00224       );
00225       DB::exec('DELETE FROM {commentinfo} WHERE comment_id IN (SELECT {commentinfo}.comment_id FROM {commentinfo} LEFT JOIN {comments} ON {commentinfo}.comment_id = {comments}.id WHERE {comments}.id IS NULL)');
00226     }
00227     else {
00228       DB::update(
00229         DB::table('comments'),
00230         array('status' => Comment::status($newstatus)),
00231         array('status' => $status_id)
00232       );
00233     }
00234     DB::delete(
00235       DB::table('commentstatus'),
00236       array('name' => Comment::status_name($status))
00237     );
00238   }
00239 
00244   public function update()
00245   {
00246     $allow = true;
00247     $allow = Plugins::filter( 'comment_update_allow', $allow, $this );
00248     if ( ! $allow ) {
00249       return false;
00250     }
00251     Plugins::act( 'comment_update_before', $this );
00252     // invoke plugins for all fields which have been updated
00253     foreach ( $this->newfields as $fieldname => $value ) {
00254       Plugins::act( 'comment_update_' . $fieldname, $this, $this->fields[$fieldname], $value );
00255     }
00256     $result = parent::updateRecord( DB::table( 'comments' ), array( 'id'=>$this->id ) );
00257     $this->fields = array_merge( $this->fields, $this->newfields );
00258     $this->newfields = array();
00259     $this->info->commit();
00260     Plugins::act( 'comment_update_after', $this );
00261     return $result;
00262   }
00263 
00268   public function delete()
00269   {
00270     $allow = true;
00271     $allow = Plugins::filter( 'comment_delete_allow', $allow, $this );
00272     if ( ! $allow ) {
00273       return false;
00274     }
00275     Plugins::act( 'comment_delete_before', $this );
00276 
00277     // Delete all info records associated with this comment
00278     $this->info->delete_all();
00279 
00280     $result = parent::deleteRecord( DB::table( 'comments' ), array( 'id'=>$this->id ) );
00281     Plugins::act( 'comment_delete_after', $this );
00282     return $result;
00283   }
00284 
00290   public function __get( $name )
00291   {
00292     $fieldnames = array_merge( array_keys( $this->fields ), array('post', 'info', 'editlink' ) );
00293     $filter = false;
00294     if ( !in_array( $name, $fieldnames ) && strpos( $name, '_' ) !== false ) {
00295       $field_matches = implode('|', $fieldnames);
00296       if(preg_match( '/^(' . $field_matches . ')_(.+)$/', $name, $matches )) {
00297         list( $unused, $name, $filter ) = $matches;
00298       }
00299     }
00300 
00301     switch ( $name ) {
00302       case 'name':
00303         if ( parent::__get( $name ) == '' ) {
00304           $out = _t( 'Anonymous' );
00305         }
00306         else {
00307           $out = parent::__get( $name );
00308         }
00309         break;
00310       case 'post':
00311         $out = $this->get_post();
00312         break;
00313       case 'info':
00314         $out = $this->get_info();
00315         break;
00316       case 'statusname':
00317         $out = self::status_name( $this->status );
00318         break;
00319       case 'typename':
00320         $out = self::type_name( $this->type );
00321         break;
00322       case 'editlink':
00323         $out = $this->get_editlink();
00324         break;
00325       default:
00326         if(preg_match('#^is_(.+)$#i', $name, $matches)) {
00327           $ts_field = $matches[1];
00328           if($index = array_search($ts_field, Comment::list_comment_statuses())) {
00329             $out = $this->status == $index;
00330           }
00331           if($index = array_search($ts_field, Comment::list_comment_types())) {
00332             $out = $this->type == $index;
00333           }
00334           // Dumb check for plurals
00335           $pluralize = function($s) {
00336             return $s . 's';
00337           };
00338           if($index = array_search($ts_field, array_map($pluralize, Comment::list_comment_statuses()))) {
00339             $out = $this->status == $index;
00340           }
00341           if($index = array_search($ts_field, array_map($pluralize, Comment::list_comment_types()))) {
00342             $out = $this->type == $index;
00343           }
00344         }
00345         else {
00346           $out = parent::__get( $name );
00347         }
00348         break;
00349     }
00350     //$out = parent::__get( $name );
00351     $out = Plugins::filter( "comment_{$name}", $out, $this );
00352     if ( $filter ) {
00353       $out = Plugins::filter( "comment_{$name}_{$filter}", $out, $this );
00354     }
00355     return $out;
00356   }
00357 
00364   public function __set( $name, $value )
00365   {
00366     switch ( $name ) {
00367       case 'status':
00368         $value = self::status($value);
00369         break;
00370       case 'date':
00371         if ( !( $value instanceOf DateTime ) ) {
00372           $value = DateTime::create( $value );
00373         }
00374         break;
00375       case 'post':
00376         if ( is_int( $value ) ) {
00377           // a post ID was passed
00378           $p = Post::get( array( 'id'=>$value ) );
00379           $this->post_id = $p->id;
00380           $this->post_object = $p;
00381         }
00382         elseif ( is_string( $value ) ) {
00383           // a post Slug was passed
00384           $p = Post::get( array( 'slug'=>$value ) );
00385           $this->post_id = $p->id;
00386           $this->post_object = $p;
00387         }
00388         elseif ( is_object( $value ) ) {
00389           // a Post object was passed, so just use it directly
00390           $this->post_id = $value->id;
00391           $this->post_object = $value;
00392         }
00393         return $value;
00394     }
00395     return parent::__set( $name, $value );
00396   }
00397 
00403   private function get_post( $use_cache = true )
00404   {
00405     if ( ! isset( $this->post_object ) || ( ! $use_cache)  ) {
00406       $this->post_object = Posts::get( array('id' => $this->post_id, 'fetch_fn' => 'get_row') );
00407     }
00408     return $this->post_object;
00409   }
00410 
00416   private function get_info()
00417   {
00418     if ( ! $this->inforecords ) {
00419       if ( 0 == $this->id ) {
00420         $this->inforecords = new CommentInfo();
00421       }
00422       else {
00423         $this->inforecords = new CommentInfo( $this->id );
00424       }
00425     }
00426     return $this->inforecords;
00427   }
00428 
00434   public static function list_comment_types( $refresh = false )
00435   {
00436     if ( $refresh || empty( self::$comment_type_list ) ) {
00437       self::$comment_type_list = DB::get_keyvalue('SELECT id, name FROM {commenttype} WHERE active = 1;');
00438     }
00439     self::$comment_type_list = Plugins::filter( 'list_comment_types', self::$comment_type_list );
00440     return self::$comment_type_list;
00441   }
00442 
00448   public static function list_comment_statuses( $refresh = false )
00449   {
00450     if ( $refresh || empty( self::$comment_status_list ) ) {
00451       self::$comment_status_list = DB::get_keyvalue('SELECT id, name FROM {commentstatus};');
00452     }
00453     self::$comment_status_list = Plugins::filter( 'list_comment_statuses', self::$comment_status_list );
00454     return self::$comment_status_list;
00455   }
00456 
00462   public static function status_action( $status )
00463   {
00464     if ( empty( self::$comment_status_actions ) ) {
00465       self::$comment_status_actions = array(
00466         'unapproved' => _t( 'Unapprove' ),
00467         'approved' => _t( 'Approve' ),
00468         'spam' => _t( 'Spam' ),
00469       );
00470       self::$comment_status_actions = Plugins::filter( 'list_comment_actions', self::$comment_status_actions );
00471     }
00472     if ( isset( self::$comment_status_actions[$status] ) ) {
00473       return self::$comment_status_actions[$status];
00474     }
00475     if ( isset(self::$comment_status_actions[Comment::status_name($status)]) ) {
00476       return self::$comment_status_actions[Comment::status_name($status)];
00477     }
00478 
00479     return '';
00480   }
00481 
00482 
00488   public static function status( $name )
00489   {
00490     $statuses = Comment::list_comment_statuses();
00491     if ( is_numeric( $name ) && ( isset( $statuses[$name] ) ) ) {
00492       return $name;
00493     }
00494     $statuses = array_flip( $statuses );
00495     if ( isset( $statuses[$name] ) ) {
00496       return $statuses[$name];
00497     }
00498     return false;
00499   }
00500 
00506   public static function status_name( $status )
00507   {
00508     $statuses = Comment::list_comment_statuses();
00509     if ( is_numeric( $status ) && isset( $statuses[$status] ) ) {
00510       return $statuses[$status];
00511     }
00512     $statuses = array_flip( $statuses );
00513     if ( isset( $statuses[$status] ) ) {
00514       return $status;
00515     }
00516     return '';
00517   }
00518 
00524   public static function type( $name )
00525   {
00526     $types = Comment::list_comment_types();
00527     if ( is_numeric( $name ) && ( isset( $types[$name] ) ) ) {
00528       return $name;
00529     }
00530     $types = array_flip( $types );
00531     if ( isset( $types[$name] ) ) {
00532       return $types[$name];
00533     }
00534     return false;
00535   }
00536 
00542   public static function type_name( $type )
00543   {
00544     $types = Comment::list_comment_types();
00545     if ( is_numeric( $type ) && isset( $types[$type] ) ) {
00546       return $types[$type];
00547     }
00548     $types = array_flip( $types );
00549     if ( isset( $types[$type] ) ) {
00550       return $type;
00551     }
00552     return '';
00553   }
00554 
00561   public function content_type()
00562   {
00563     return Comment::type_name( $this->type );
00564   }
00565 
00572   public function get_access( $user = null )
00573   {
00574     if ( ! $user instanceof User ) {
00575       $user = User::identify();
00576     }
00577 
00578     // these tokens automatically grant full access to the comment
00579     if ( $user->can( 'super_user' ) || $user->can( 'manage_all_comments' ) ||
00580       ( $user->id == $this->post->user_id && $user->can( 'manage_own_post_comments' ) ) ) {
00581       return ACL::get_bitmask( 'full' );
00582     }
00583 
00584     /* If we got this far, we can't update or delete a comment. We still need to check if we have
00585      * read access to it. Collect a list of applicable tokens
00586      */
00587     $tokens = array(
00588       'post_any',
00589       'post_' . Post::type_name( $this->post->content_type ),
00590     );
00591 
00592     if ( $user->id == $this->post->user_id ) {
00593       $tokens[] = 'own_posts';
00594     }
00595 
00596     $tokens = array_merge( $tokens, $this->post->get_tokens() );
00597 
00598     $token_accesses = array();
00599 
00600     // grab the access masks on these tokens
00601     foreach ( $tokens as $token ) {
00602       $access = ACL::get_user_token_access( $user, $token );
00603       if ( $access instanceof Bitmask ) {
00604         $token_accesses[] = ACL::get_user_token_access( $user, $token )->value;
00605       }
00606     }
00607 
00608     // now that we have all the accesses, loop through them to build the access to the particular post
00609     if ( in_array( 0, $token_accesses ) ) {
00610       return ACL::get_bitmask( 0 );
00611     }
00612 
00613     if ( ACL::get_bitmask( Utils::array_or( $token_accesses ) )->read ) {
00614       return ACL::get_bitmask( 'read' );
00615     }
00616 
00617     // if we haven't returned by this point, we can neither manage the comment nor read it
00618     return ACL::get_bitmask( 0 );
00619   }
00620 
00625   private function get_editlink()
00626   {
00627     return URL::get( 'edit_comment', $this, false );
00628   }
00629 
00636   public function css_class ( $append = array() ) {
00637 
00638     $classes = $append;
00639 
00640     $classes[] = 'comment';
00641     $classes[] = 'comment-' . $this->id;
00642     $classes[] = 'type-' . $this->typename;
00643     $classes[] = 'status-' . $this->statusname;
00644 
00645     $classes[] = 'comment-post-' . $this->post->id;
00646 
00647     return implode( ' ', $classes );
00648 
00649   }
00650 
00659   public static function filter_comment_type_display_4( $type, $foruse )
00660   {
00661     $names = array(
00662       'comment' => array(
00663         'singular' => _t( 'comment' ),
00664         'plural' => _t( 'comments' ),
00665       ),
00666       'pingback' => array(
00667         'singular' => _t( 'pingback' ),
00668         'plural' => _t( 'pingbacks' ),
00669       ),
00670       'trackback' => array(
00671         'singular' => _t( 'trackback' ),
00672         'plural' => _t( 'trackbacks' ),
00673       ),
00674     );
00675     return isset( $names[$type][$foruse] ) ? $names[$type][$foruse] : $type;
00676   }
00677 
00685   public static function filter_comment_status_display_4( $status )
00686   {
00687     $names = array(
00688       'unapproved' => _t( 'unapproved' ),
00689       'approved' => _t( 'approved' ),
00690       'spam' => _t( 'spam' ),
00691     );
00692     return isset( $names[$status] ) ? $names[$status] : $status;
00693   }
00694 }
00695 
00696 ?>

Generated on Sun Aug 4 2013 12:51:42 for Habari by  doxygen 1.7.1