Campustream 1.0
A social network MQP for WPI
application/models/newsevent.php
Go to the documentation of this file.
00001 <?
00002 
00006 class Newsevent_Model extends ActiveRecord {
00007         public $table_name = 'newsevents';
00008         public $columns = array('id', 'type', 'category_id', 'newsevent', 'title', 'post', 'posted_by', 'time_posted', 'votes', 'num_comments');
00009         public $cache_keys = array( 'newsevent/#' => 'id', 'newsevents/type:#' => 'type', 'newsevents/category:#' => 'category', 'newsevents/user:#' => 'posted_by' );
00010         public $has_many = array('comments');
00011         public $has_one = array('category', 'user', 'eventmeta');
00012         public $public_columns = array( 'id', 'short_id', 'type', 'category_id', 'newsevent', 'title', 'post', 'posted_by', 'time_posted', 'votes', 'num_comments', 'comments', 'user', 'eventmeta' );
00013         
00017         public function load_category() {
00018                 if (!$this->category) {
00019                         $category = new Newseventcategory_Model();
00020                         $category->load($this->category_id);
00021                         
00022                         $this->add_relationship('category', $category);
00023                 }
00024         }
00025         
00029         public function load_user() {
00030                 if (!$this->user) {
00031                         $user = ActiveCache::find('User_Model', $this->posted_by, 43200)->sql(
00032                                 "SELECT * FROM users WHERE id = {$this->posted_by} LIMIT 1"
00033                         );
00034                         
00035                         if ($user->is_loaded()) {
00036                                 $this->add_relationship('user', $user);
00037                         }
00038                 }
00039         }
00040         
00044         public function load_comments() {
00045                 if (!$this->comments && $this->num_comments > 0) {
00046                         $comments = Newscomment_Model::load_comment_tree($this->id);
00047                         $this->add_relationship('comments', $comments);
00048                 }
00049         }
00050         
00054         public function load_eventmeta() {
00055                 $this->load_category();
00056                 
00057                 if (!$this->eventmeta && $this->category->type == 'event') {
00058                         $eventmeta = ActiveCache::find('Eventmeta_Model', "event:{$this->id}", 43200)->sql(
00059                                 "SELECT * FROM eventmeta WHERE event_id = {$this->id} LIMIT 1"
00060                         );
00061                         
00062                         if ($eventmeta->is_loaded()) {
00063                                 $this->add_relationship('eventmeta', $eventmeta);
00064                         }
00065                 }
00066         }
00067         
00072         public static function load_popular($opts = false) {
00073                 $category = (isset($opts['cat_id']) ? $opts['cat_id'] : -1);
00074                 $type = (isset($opts['type']) ? $opts['type'] : 'all');
00075                 $page = (isset($opts['page']) ? $opts['page'] : 1);
00076 
00077                 $key = "news/popular:$category/type:$type/page:$page";
00078                 $query = "
00079                   SELECT
00080                         id,
00081                         (log(greatest(abs(votes), 1)) +
00082                         (
00083                                 SIGN(votes)
00084                                 * (UNIX_TIMESTAMP(time_posted) - 1134028003)
00085                         ) / 45000.0) as rating
00086                   FROM newsevents";
00087                   
00088                   if ($category != -1 || $type != 'all') {
00089                         $where = array();
00090                         if ($category != -1) {
00091                                 $where[] = "category_id = $category";
00092                         }
00093                         if ($type != 'all') {
00094                                 $where[] = "newsevent = '$type'";
00095                         }
00096                         
00097                         $query .= " WHERE " . implode(" AND ", $where);
00098                   }
00099                   
00100                 $query .= "
00101                         ORDER BY rating DESC
00102                   LIMIT 0, 20
00103                 ";
00104                 
00105                 $m = MemcacheManager::connection();
00106                 $ids = $m->get($key);
00107                 if ($m->getResultCode() == Memcached::RES_NOTFOUND) {
00108                         $ids = array();
00109                         
00110                         $result = DatabaseManager::readConnection()->query($query);
00111                         if ($result) {
00112                                 while ($data = $result->fetch_assoc()) {
00113                                         $ids[] = $data['id'];
00114                                 }
00115                                 
00116                                 $m->set($key, $ids, 300);
00117                         }
00118                 }
00119                 
00120                 $posts = array();
00121                 foreach ($ids as $id) {
00122                         $news = ActiveCache::find('Newsevent_Model', $id, 43200)->sql(
00123                                 "SELECT * FROM newsevents WHERE id = $id LIMIT 1"
00124                         );
00125                         
00126                         if ($news->is_loaded()) {
00127                                 $posts[] = $news;
00128                         }
00129                 }
00130                 
00131                 return $posts;
00132         }
00133         
00137         public function save($voteup=false) {
00138                 parent::save();
00139                 
00140                 if (!$voteup) {
00141                         return;
00142                 }
00143                 
00144                 $this->vote('up');
00145                 
00146                 // then create the status message for it
00147                 $status = new Status_Model();
00148                 $status->user_id = $this->posted_by;
00149                 $status->source = 'site';
00150                 $status->message = $this->title;
00151                 $status->post_date = ActiveRecord::NOW();
00152                 $status->type = 'newsevent';
00153                 $status->content_id = $this->id;
00154                 $status->is_public = 1;
00155                 $status->save();
00156         }
00157         
00161         public function vote($dir) {
00162                 // First we need to check to make sure this user hasn't voted on this response before
00163                 $r = RedisManager::connection();
00164                 $userID = sess::getUserID();
00165                 $dir = strtolower($dir);
00166                 $has_voted = $this->has_voted();
00167                                 
00168                 if ($has_voted === 'up') {
00169                         $this->votes--;
00170                         $r->srem("news:{$this->id}:voting:up", $userID);
00171                 } elseif ($has_voted === 'down') {
00172                         $this->votes++;
00173                         $r->srem("news:{$this->id}:voting:down", $userID);
00174                 }
00175                 
00176                 $this->load_user();
00177                 
00178                 if ($has_voted === 'up' && $dir === 'up') {
00179                         $this->save(false);
00180                         $this->user->karma--;
00181                         $this->user->save();
00182                         return;
00183                 }
00184                 
00185                 if ($has_voted === 'down' && $dir === 'down') {
00186                         $this->save(false);
00187                         $this->user->karma++;
00188                         $this->user->save();
00189                         return;
00190                 }
00191                 
00192                 // New vote
00193                 if ($dir === 'up') {
00194                         $this->votes++;
00195                         $this->user->karma++;
00196                         $r->sadd("news:{$this->id}:voting:up", $userID);
00197                 } else {
00198                         $this->votes--;
00199                         $this->user->karma--;
00200                         $r->sadd("news:{$this->id}:voting:down", $userID);
00201                 }
00202                 
00203                 $this->user->save();
00204                 $this->save(false);
00205         }
00206         
00211         public function has_voted($user_id=false) {
00212                 if (!$user_id) {
00213                         $user_id = sess::getUserID();
00214                 } elseif ($user_id instanceof User_Model) {
00215                         $user_id = $user_id->id;
00216                 }
00217                 
00218                 $r = RedisManager::connection();
00219                 $up_vote = $r->sismember("news:{$this->id}:voting:up", $user_id);
00220                 if (!$up_vote) {
00221                         $down_vote = $r->sismember("news:{$this->id}:voting:down", $user_id);
00222                         
00223                         if ($down_vote) {
00224                                 return 'down';
00225                         }
00226                 } else {
00227                         return 'up';
00228                 }
00229                 
00230                 return false;
00231         }
00232         
00233         private function get_votes($which) {
00234                 $r = RedisManager::connection();
00235                 $num = $r->scard("news:{$this->id}:voting:$which");
00236                 
00237                 if ($num) {
00238                   return $num;
00239                 } else {
00240                   return 0;
00241                 }
00242         }
00243         
00244         public function __get($key) {
00245                 switch ($key) {
00246                         case 'short_id': return base_convert($this->id, 10, 36);
00247                         case 'upvotes': return $this->get_votes('up');
00248                         case 'downvotes': return $this->get_votes('down');
00249                 }
00250                 
00251                 return parent::__get($key);
00252         }
00253 }