Campustream 1.0
A social network MQP for WPI
application/controllers/collaborate.php
Go to the documentation of this file.
00001 <?
00002 
00006 class Collaborate_Controller extends Controller implements REST {
00007         public $enable_session = true;
00008         public $template = 'template/main';
00009         
00013         public function index() {
00014                 sess::require_login();
00015                 
00016                 $view = new View('collaborate/index');
00017                 $this->template->title = "Collaborate";
00018                 $this->template->active = 'collaborate';
00019                 $this->template->content = $view->render();
00020                 echo $this->template->render();
00021         }
00022         
00026         public function show_section($args) {
00027                 $sections = Question_Model::$categories;
00028                 
00029                 sess::require_login();
00030                 
00031                 $section = $args['section'];
00032                 
00033                 if (!in_array($section, $sections)) {
00034                         return Hub::redirect('/collaborate');
00035                 }
00036                 
00037                 $view = new View('collaborate/section');
00038                 $view->section = ucfirst(strtolower($section));
00039                 $this->template->title = "Collaborate &raquo; {$view->section}";
00040                 $this->template->active = 'collaborate';
00041                 $this->template->content = $view->render();
00042                 echo $this->template->render();
00043         }
00044         
00048         public function show_list($args) {
00049                 $section = (isset($_GET['section']) ? $_GET['section'] : 'academic');
00050                 $sorting = (isset($_GET['sorting']) ? $_GET['sorting'] : 'last_updated');
00051                 $page = (isset($_GET['page']) ? $_GET['page'] : 1);
00052                 
00053                 $r = RedisManager::connection();
00054                 
00055                 $question_ids = array();
00056                 $questions = null;
00057                 
00058                 $start = ($page - 1) * 20;
00059                 
00060                 switch ($sorting) {
00061                         case 'last_updated':
00062                                 $questions = ActiveRecord::find_all('Question_Model', "SELECT * FROM questions WHERE category = '{$section}' AND deleted = 0 ORDER BY last_update DESC LIMIT $start, 20");
00063                                 break;
00064                         case 'popular':
00065                                 break;
00066                         case 'newest':
00067                                 $question_ids = $r->lrange("questions:stream:{$section}:newest", $start, $start + 20);
00068                         case 'search':
00069                                 break;
00070                 }
00071                 
00072                 if (!$questions) {
00073                         $questions = array();
00074                         foreach($question_ids as $qid) {
00075                                 $question = ActiveCache::find('Question_Model', $qid, 43200)->sql(
00076                                         "SELECT * FROM questions WHERE id = $qid"
00077                                 );
00078                                 
00079                                 if (!$question->is_loaded() || $question->deleted > 0) {
00080                                         continue;
00081                                 }
00082                                 
00083                                 $question->load_user();
00084                                 $question->load_tags();
00085                                 $question->user = $question->user->limited_object();
00086                                 $questions[] = $question->limited_object();
00087                         }
00088                 } else {
00089                         foreach ($questions as $i=>$question) {
00090                                 $question->load_user();
00091                                 $question->load_tags();
00092                                 $question->user = $question->user->limited_object();
00093                                 $questions[$i] = $question->limited_object();
00094                         }
00095                 }
00096                 
00097                 View::respond_to(array('json', 'jsonp', 'xml'), function ($format) use($questions) {
00098                         switch ($format) {
00099                                 case 'json': echo json_encode($questions); break;
00100                                 case 'xml': echo xml::encode_array($questions, 'questions', 'question');
00101                         }
00102                 });
00103         }
00104         
00108         public function show($args) {
00109                 $id = null;
00110                 
00111                 if (isset($args['short_id'])) {
00112                         $id = base_convert($args['short_id'], 36, 10);
00113                 } elseif (isset($_GET['short_id'])) {
00114                         $id = base_convert($_GET['short_id'], 36, 10);
00115                 } elseif (isset($_GET['id']) && is_numeric($_GET['id'])) {
00116                         $id = $_GET['id'];
00117                 } else {
00118                         return Hub::http_error(401, "Missing question ID");
00119                 }
00120                 
00121                 $question = ActiveCache::find('Question_Model', $id, 43200)->sql(
00122                         "SELECT * FROM questions WHERE id = $id LIMIT 1"
00123                 );
00124                 
00125                 if (!$question->is_loaded() || $question->deleted) {
00126                         View::respond_to(array('xml', 'json', 'jsonp'), function () {
00127                                 Hub::http_error(404, "Question not found");
00128                         });
00129                         
00130                         // Should show an error page in the future
00131                         View::respond_to('html', function () {
00132                                 Hub::redirect('/collaborate');
00133                         });
00134                         
00135                         return false;
00136                 }
00137                 
00138                 $question->load_user();
00139                 $question->load_responses();
00140                 $question->load_tags();
00141                 
00142                 View::respond_to(array('xml', 'json', 'jsonp'), function ($format) use($question) {
00143                         foreach ($question->responses as $i=>$response) {
00144                                 $response->message = htmlspecialchars_decode($response->message, ENT_QUOTES);
00145                                 $question->responses[$i] = $response;
00146                         }
00147                         
00148                         echo $question->{"to_$format"}();
00149                 });
00150                 
00151                 $template = $this->template;
00152                 View::respond_to('html', function ($format) use($question, $template) {
00153                         $view = new View('collaborate/show');
00154                         $view->question = $question;
00155                         $template->title = "Collaborate &raquo; " . ucfirst($question->category) . " &raquo; " . $question->title;
00156                         $template->active = 'collaborate';
00157                         $template->content = $view->render();
00158                         echo $template->render();
00159                 });
00160         }
00161         
00165         public function create() {
00166                 if (!$this->session->get('authenticated')) {
00167                         return Hub::http_error(403, "Not authorized");
00168                 }
00169                 
00170                 if (!isset($_POST['title']) || !isset($_POST['message']) || !isset($_POST['category'])) {
00171                         return Hub::http_error(401, "Missing required data");
00172                 }
00173                 
00174                 if (!in_array($_POST['category'], Question_Model::$categories)) {
00175                         return Hub::http_error(401, "Invalid category");
00176                 }
00177                 
00178                 $public = 1;
00179                 if (isset($_POST['public'])) {
00180                         $public = ($_POST['public'] == '0' ? 0 : 1);
00181                 }
00182                 
00183                 $title = htmlspecialchars(trim($_POST['title']), ENT_QUOTES, 'UTF-8');
00184                 $message = htmlspecialchars(trim($_POST['message']), ENT_QUOTES, 'UTF-8');
00185                 
00186                 $question = new Question_Model();
00187                 $question->user_id = sess::getUserID();
00188                 $question->category = strtolower($_POST['category']);
00189                 $question->title = $title;
00190                 $question->message = nl2br($message);
00191                 $question->post_date = ActiveRecord::NOW();
00192                 $question->last_update = ActiveRecord::NOW();
00193                 $question->vote_count = 0;
00194                 $question->is_public = $public;
00195                 $question->save();
00196                 
00197                 // and now to save the tags...
00198                 $tags_list = isset($_POST['tags']) ? trim($_POST['tags']) : false;
00199                 if ($tags_list) {
00200                         $tags = explode(',', $tags_list);
00201                 }
00202                 
00203                 foreach($tags as $tag) {
00204                         // convert newlines and tabs to spaces
00205                         $tag = trim(str_replace(array("\t", "\n", "\r"), " ", $tag));
00206                         if (strlen($tag) > 0 && !preg_match('/[^A-Z0-9_-\s]+/i', $tag)) {
00207                                 $_tag = new Questiontag_Model();
00208                                 $_tag->question_id = $question->id;
00209                                 $_tag->tag = $tag;
00210                                 $_tag->save();
00211                         }
00212                 }
00213                 
00214                 View::respond_to(array('json', 'xml'), function ($format) use($question) {
00215                         $question->load_user();
00216                         $question->load_tags();
00217                         echo $question->{"to_$format"}();
00218                 });     
00219         }
00220         
00224         public function respond() {
00225                 if (!$this->session->get('authenticated')) {
00226                         return Hub::http_error(403, "Unauthorized");
00227                 }
00228                 
00229                 if (!isset($_POST['message'])) {
00230                         return Hub::http_error(401, "Missing respond message");
00231                 }
00232                 
00233                 $id = null;
00234                 if (isset($_POST['short_id'])) {
00235                         $id = base_convert($_POST['short_id'], 36, 10);
00236                 } elseif (isset($_POST['id']) && is_numeric($_POST['id'])) {
00237                         $id = $_POST['id'];
00238                 } else {
00239                         return Hub::http_error(401, "Question ID missing or invalid");
00240                 }
00241                 
00242                 $message = htmlspecialchars(trim($_POST['message']), ENT_QUOTES, 'UTF-8');
00243                 
00244                 $public = 1;
00245                 if (isset($_POST['public']) && is_numeric($_POST['public'])) {
00246                         $public = $_POST['public'];
00247                 }
00248                 
00249                 $response = new Response_Model();
00250                 $response->question_id = $id;
00251                 $response->user_id = sess::getUserID();
00252                 $response->message = nl2br($message);
00253                 $response->post_date = ActiveRecord::NOW();
00254                 $response->vote_count = 0;
00255                 $response->is_public = $public;
00256                 $response->save();
00257                 
00258                 // chances are, you probably want to vote your own response up. digg
00259                 // and reddit do it, we can too.
00260                 $response->vote('up');
00261                 
00262                 // Now that we've responded, we need to move this question back to the top
00263                 // of the 'last updated' questions
00264                 $response->load_question();
00265                 $response->question->last_update = ActiveRecord::NOW();
00266                 $response->question->save(false);
00267                 
00268                 View::respond_to(array('json', 'xml'), function ($format) use($response) {
00269                         echo $response->{"to_$format"}();
00270                 });
00271         }
00272         
00276         public function vote() {
00277                 if (!$this->session->get('authenticated')) {
00278                         return Hub::http_error(403, "Unauthorized");
00279                 }
00280                 
00281                 if (!isset($_POST['dir']) || !isset($_POST['id'])) {
00282                         return Hub::http_error(401, "Missing data, invalid request");
00283                 }
00284                 
00285                 if (($_POST['dir'] != 'up' && $_POST['dir'] != 'down') || !is_numeric($_POST['id'])) {
00286                         return Hub::http_error(401, "Invalid data");
00287                 }
00288                 
00289                 $response = ActiveCache::find('Response_Model', $_POST['id'], 43200)->sql(
00290                         "SELECT * FROM responses WHERE id = {$_POST['id']} LIMIT 1"
00291                 );
00292                 
00293                 if (!$response->is_loaded()) {
00294                         return Hub::http_error(404, "Response not found");
00295                 }
00296                 
00297                 $response->vote($_POST['dir']);
00298                 
00299                 View::respond_to(array('json', 'xml'), function ($format) use($response) {
00300                         echo $response->{"to_$format"}();
00301                 });
00302         }
00303         
00307         public function delete() {
00308                 if (!$this->session->get('authenticated')) {
00309                         return Hub::http_error(403, "Not authorized");
00310                 }
00311                 
00312                 $id = $_POST['id'];
00313                 
00314                 if (!$id || !is_numeric($id)) {
00315                         return Hub::http_error(401, "Invalid or missing ID");
00316                 }
00317                 
00318                 $question = ActiveCache::find('Question_Model', $id, 43200)->sql(
00319                         "SELECT * FROM questions WHERE id = $id LIMIT 1"
00320                 );
00321                 
00322                 if (!$question->is_loaded()) {
00323                         return Hub::http_error(404, "Question not found");
00324                 }
00325                 
00326                 if ($question->user_id != sess::getUserID()) {
00327                         return Hub::http_error(403, "Not authorized");
00328                 }
00329                 
00330                 $question->delete();
00331         }
00332 }