'/:(int)thread_id/:thread_name/', 'edit' => '/edit/:thread_id', 'quickedit' => '/quickedit/:thread_id', 'tag' => '/tag/:thread_id', 'history' => '/history/:thread_id/:thread_name', 'diff' => '/diff/:thread_id/:thread_name', 'delete' => '/delete/:what/:thread_id/:rev_id', 'revert' => '/revert/:thread_id/:rev_id', 'revision' => '/revision/:thread_id/:rev_id/:thread_name', 'user' => '/user/:user_id/:user_name', ); } //-------------------------------------------- // Get a thread based on its thread id, then // set some of its permissions to the template // based on the current user. //-------------------------------------------- function _genericThreadStuff(&$reg, &$req, &$resp) { $info = &new InformationDisplay($reg, $req, $resp); $user = &$reg->get('user'); //-------------------------------------------- // Check permissions //-------------------------------------------- if(!$user->canDo('view', 'threads')) { $info->display('permsRequired'); } //-------------------------------------------- // Get the thread. //-------------------------------------------- $finder = &$this->getFinder('threads'); $thread = &$finder->find($req->get('thread_id')); //-------------------------------------------- // Whoops! This thread doesn't exist! //-------------------------------------------- if($thread === NULL) { $info->text("The requested thread does not exist."); } //-------------------------------------------- $thread->setUser($user); $thread->setPermissions($resp); //-------------------------------------------- $resp->assignRef('thread', $thread); } //-------------------------------------------- // This is actually the index action, but since there // are variables in the route it is named differently. // Otherwise, this deals with viewing threads. //-------------------------------------------- function thread(&$reg, &$req, &$resp) { $this->_genericThreadStuff($reg, $req, $resp); //-------------------------------------------- $info = &new InformationDisplay($reg, $req, $resp); $user = &$reg->get('user'); $thread = &$resp->getRef('thread'); //-------------------------------------------- // Whoops! This thread has been soft deleted. // Make sure this person has permission to view // it. //-------------------------------------------- if($thread->get('deleted') == 1) { if((!$user->canDo('delete', 'threads') && $user->getId() != $thread->get('user_id')) || !$user->canDo('moderate', 'threads')) { $info->display('permsRequired'); } } //-------------------------------------------- // Alter the number of people who have viewed this thread. //-------------------------------------------- $session = &$reg->get('session'); $viewings = &$session->get('k4_viewings'); //-------------------------------------------- // If this is the first time the user sees this thread in the // current session, increment the number of views for the thread //-------------------------------------------- if (!isset($viewings['threads'][$thread->getId()])) { //-------------------------------------------- // Update the number of thread views. //-------------------------------------------- $thread->set('views', 1 + $thread->get('views')); $thread->save(); //-------------------------------------------- // If this thread has been tagged by this user, // update the number of times this user has viewed // this thread. //-------------------------------------------- if($user->isMember()) { $thread_tags = &$thread->getMyTags(); if($thread_tags->numRows() > 0) { //-------------------------------------------- // Increment the views. //-------------------------------------------- $finder = &$this->getFinder('bookmarked_threads'); $finder->updateWhere("views=views+1", "thread_id=? AND user_id=?", array($thread->getId(), $user->getId())); } } } //-------------------------------------------- // Save the time the the user last accessed this thread //-------------------------------------------- $viewings['threads'][$thread->getId()] = time(); //-------------------------------------------- // Done. Display the right templates. //-------------------------------------------- $resp->assign('viewing_thread', 1); $this->setPage($thread->get('name')); $resp->assign('content', 'comments.html'); $this->setLayout('forum_base.html'); } //-------------------------------------------- // Generic function to check if a user can create a thread // Through permissions and such. //-------------------------------------------- function _checkCreateThread(&$reg, &$req, &$resp) { $user = &$reg->get('user'); $info = &new InformationDisplay($reg, $req, $resp); if (!$user->canDo('post', 'threads')) { $info->display('permsRequired'); } if ($user->get('karma') < 1) { $info->display('karmaRequired'); } } //-------------------------------------------- // Generic function to check if a user can edit a thread // Through permissions and such. //-------------------------------------------- function _checkEditThread(&$reg, &$req, &$resp, &$thread) { $user = &$reg->get('user'); $info = &new InformationDisplay($reg, $req, $resp); //-------------------------------------------- // Whoop.. bad request varible.. though this is // a bit redundant now that we're passing $thread // to this function.. oh well. //-------------------------------------------- if($req->get('thread_id') == 0) { $info->text("The thread that you are trying to edit doesn't exist!"); } //-------------------------------------------- // This user isn't a moderator. //-------------------------------------------- if(!$user->canDo('moderate', 'threads')) { //-------------------------------------------- // This user doesn't have the general permission // to edit threads. //-------------------------------------------- if (!$user->canDo('edit', 'threads')) { $info->display('permsRequired'); } //-------------------------------------------- // This user is not the original author. //-------------------------------------------- if($user->getId() != $thread->get('user_id')) { //-------------------------------------------- // ... And we're not allowing co-authors. //-------------------------------------------- if(intval($thread->get('allow_coauthors')) != 1) { $info->display('permsRequired'); } } } } //-------------------------------------------- // Add a thread to the database. //-------------------------------------------- function &_saveThread(&$reg, &$req, &$resp, $edit = FALSE, $quick_edit = FALSE) { $user = &$reg->get('user'); $info = &new InformationDisplay($reg, $req, $resp); //-------------------------------------------- // Register some REQUEST filters.. once registered, the // $req->get('varname') will always be changed! //-------------------------------------------- $req->registerFilter('name', new K4TrimFilter()); $req->registerFilter('body', new K4BBParserFilter()); if(!$edit) { //-------------------------------------------- // We're creating this thread. //-------------------------------------------- $this->_checkCreateThread($reg, $req, $resp); //-------------------------------------------- // Add the thread to the database. //-------------------------------------------- $created = time(); $finder = &$this->getFinder('threads'); $thread = &$finder->createRecord(); $thread->set('created', $created); $thread->set('recent_created', $created); $thread->setThreadName($req->get('name')); $thread->setThreadBody($req->get('body')); $thread->set('user_id', $user->getId()); $thread->setTags($req->get('tags')); $thread->setUser($user); $thread->setKarma(); $thread->setUserKarma(); $thread->set('edit_user_id', $user->getId()); $thread->set('edit_time', $created); $thread->set('edit_message', "[Created]"); $thread->set('allow_coauthors', intval($req->get('allow_coauthors')) == 1 ? 1 : 0); } else { if($this->popReferer() == '/') { $info->display('permsRequired'); } //-------------------------------------------- // Get our thread. //-------------------------------------------- $finder = &$this->getFinder('threads'); $thread = &$finder->find($req->get('thread_id')); if($thread === NULL) { $info->text("The thread that you are trying to edit doesn't exist!"); } //-------------------------------------------- // Are we allowed to update it? //-------------------------------------------- $this->_checkEditThread($reg, $req, $resp, $thread); //-------------------------------------------- // Set the user to the thread that's editing it. //-------------------------------------------- $thread->setUser($user); //-------------------------------------------- // Some request variables, if they exist. //-------------------------------------------- $is_mod = $user->canDo('moderate', 'threads'); $is_mod_or_author = $is_mod || $user->getId() == $thread->get('user_id') ? TRUE : FALSE; //-------------------------------------------- // Make sure the the thread record knows what type // of editing it's doing. //-------------------------------------------- if($quick_edit) { $thread->setQuickEdit(); $thread->set('edit_message', ''); } else { //-------------------------------------------- // Build a tags array from current and new tags. //-------------------------------------------- $tags = array(); if($req->get('current_tags')) { $tags = clean_tags($req->get('current_tags')); } $tags = array_merge($tags, explode(",", $req->get('tags'))); $tags = array_unique($tags); //-------------------------------------------- // Set some general info. //-------------------------------------------- $thread->setEdit(); $thread->setTags($tags); if($is_mod_or_author) { $thread->set('allow_coauthors', $req->get('allow_coauthors') && $req->get('allow_coauthors') == '1' ? 1 : 0); } if($is_mod) { //-------------------------------------------- // So, this user is a moderator and wants // to get rid of all of the old revisions. //-------------------------------------------- if($req->get('set_rev_point') && $req->get('set_rev_point') == '1') { $thread->clearRevisions(); } $thread->setThreadName($req->get('name')); } //-------------------------------------------- // If we've left an edit message, let's set it. //-------------------------------------------- $thread->set('edit_message', substr_utf(htmlentities(trim($req->get('edit_message')), ENT_QUOTES, K4_CHARSET), 0, 250)); } $thread->setThreadBody($req->get('body')); //-------------------------------------------- // Some editing stuff. //-------------------------------------------- $thread->set('edit_time', time()); $thread->set('edit_user_id', $user->getId()); //-------------------------------------------- // Regardless if we are deleting all of the revisions, // this must be called. //-------------------------------------------- $thread->createRevision(); } //-------------------------------------------- // Return the thread! //-------------------------------------------- return $thread; } //-------------------------------------------- // Save a thread, either by creating or updating // it. //-------------------------------------------- function _save(&$reg, &$req, &$resp, $edit = FALSE, $quick_edit = FALSE) { $info = &new InformationDisplay($reg, $req, $resp); $thread = &$this->_saveThread($reg, $req, $resp, $edit, $quick_edit); //-------------------------------------------- // Check for the captcha. We do it here so we can // still redirect them back to fix the problem if // necessary. //-------------------------------------------- $valid = TRUE; if(!$edit) { $captcha = &$this->getExtension('captcha'); if(!$captcha->isValid($reg, $req)) { $valid = FALSE; $resp->setError('captcha_input'); } } if ($valid && $thread->save()) { // redirect us $path = '/thread/'. $thread->getId() . '/'. k4_us($thread->get('name')) .'/'; //$info->text('Your thread has been saved.', $path, 3); $this->redirect($path); } else { //-------------------------------------------- // Yahtzee! Some errors occured.. time to go back. //-------------------------------------------- $resp->assign('thread', $req->getArray(FA_REQUEST_POST)); $resp->assign('error_msg', TRUE); // Show the error message foreach ($thread->getInvalid() as $invalid) { $resp->setError($invalid); } $func = $edit ? 'edit' : 'create'; $this->$func($reg, $req, $resp); } } //-------------------------------------------- // Display for to create a thread. //-------------------------------------------- function create(&$reg, &$req, &$resp) { $this->_checkCreateThread($reg, $req, $resp); $captcha = &$this->getExtension('captcha'); $captcha->drawCaptcha($reg, $req, $resp); $resp->assign('content', 'thread_create_form.html'); $this->setPage("Post a Thread"); $this->setLayout("forum_base.html"); } //-------------------------------------------- // Show the form to edit a comment. //-------------------------------------------- function edit(&$reg, &$req, &$resp) { $this->_genericThreadStuff($reg, $req, $resp); //-------------------------------------------- $thread = &$resp->getRef('thread'); $user = &$reg->get('user'); $info = &new InformationDisplay($reg, $req, $resp); //-------------------------------------------- // Standard error checking. //-------------------------------------------- $this->_checkEditThread($reg, $req, $resp, $thread); //-------------------------------------------- // Permissions... //-------------------------------------------- $can_invite_author = 0; $can_remove_author = 0; $can_edit_title = 0; $can_moderate = 0; $can_disable_coauthors = 0; //-------------------------------------------- if($thread->get('user_id') == $user->getId()) { $can_invite_author = 1; $can_remove_author = 1; } if($user->canDo('moderate', 'threads')) { $can_edit_title = 1; $can_moderate = 1; $can_disable_coauthors = 1; } //-------------------------------------------- $resp->assign('can_invite_author', $can_invite_author); $resp->assign('can_remove_author', $can_remove_author); $resp->assign('can_edit_title', $can_edit_title); $resp->assign('can_moderate', $can_moderate); $resp->assign('can_disable_coauthors', $can_disable_coauthors); $resp->assign('show_options_section', ($can_moderate + $can_disable_coauthors > 0) ? 1 : 0); //-------------------------------------------- // Finish off with template stuff. //-------------------------------------------- $resp->assign('content', 'thread_edit_form.html'); $this->setPage("Edit a Thread"); $this->setLayout("forum_base.html"); } //-------------------------------------------- // Show the form to quick edit a comment. //-------------------------------------------- function quickedit(&$reg, &$req, &$resp) { $this->checkXHR(); $user = &$reg->get('user'); //-------------------------------------------- // Get our thread. //-------------------------------------------- $finder = &$this->getFinder('threads'); $thread = &$finder->find($req->get('thread_id')); if($thread === NULL) { $this->informationPage("The thread that you are trying to edit doesn't exist!"); } //-------------------------------------------- // Standard error checking. //-------------------------------------------- $this->_checkEditThread($reg, $req, $resp, $thread); //-------------------------------------------- // Finish off with template stuff. //-------------------------------------------- $resp->assignRef('thread', $thread); $this->setLayout("thread_quickedit_form.html"); } //-------------------------------------------- // Create the thread.. or at least try! //-------------------------------------------- function post(&$reg, &$req, &$resp) { $this->_save($reg, $req, $resp, FALSE, FALSE); } //-------------------------------------------- // Update the thread.. or at least try! //-------------------------------------------- function update(&$reg, &$req, &$resp) { $this->_save($reg, $req, $resp, TRUE, FALSE); } //-------------------------------------------- // Quick update the thread.. or at least try! //-------------------------------------------- function quickupdate(&$reg, &$req, &$resp) { $this->checkXHR(); $thread = &$this->_saveThread($reg, $req, $resp, TRUE, TRUE); $thread->save(); //-------------------------------------------- // We're done, pass the new comment to the template //-------------------------------------------- $finder = &$this->getFinder('threads'); $thread = &$finder->find($thread->getId()); $resp->assign('thread', $thread); $this->setLayout("thread_view_body.html"); } //-------------------------------------------- // Cancel quick editing. //-------------------------------------------- function canceledit(&$reg, &$req, &$resp) { $this->checkXHR(); $finder = &$this->getFinder('threads'); $thread = &$finder->find($req->get('thread_id')); $resp->assign('thread', $thread); $this->setLayout("thread_view_body.html"); } //-------------------------------------------- // Show the form to set personal tags for a thread // or, if the thread_tags request variable is present, // add/update the personal tags for this thread. //-------------------------------------------- function tag(&$reg, &$req, &$resp) { $this->checkLogin($reg, $req, $resp); $this->_genericThreadStuff($reg, $req, $resp); //-------------------------------------------- // Get the stuff. //-------------------------------------------- $thread = &$resp->getRef('thread'); $info = &new InformationDisplay($reg, $req, $resp); $user = &$reg->get('user'); //-------------------------------------------- // If there is the appropriate request variable, // try to add / save the tags. //-------------------------------------------- if($req->get('thread_tags')) { $tags = preg_split('~,~', $req->get('thread_tags'), -1, PREG_SPLIT_NO_EMPTY); if($user->addThreadTags($thread->getId(), $tags)) { $info->text("Successfully tagged the thread!", "/thread/". $thread->getId() ."/", 3); } else { $info->text("An error occured while trying to tag this thread. Please make sure that you have formatted your tags correctly."); } } else { $finder = &$this->getFinder('thread_user_tags'); $tags = &$finder->findAllWhere("tut.thread_id=? AND tut.user_id=?", array($thread->getId(), $user->getId())); if($tags !== NULL) { $tag_string = ""; while($tags->next()) { $tag = &$tags->current(); $tag_string .= $tag->get('tag_name') .", "; } if($tag_string != "") { $resp->assign('thread_user_tags', substr_utf($tag_string, 0, -2)); } } } //-------------------------------------------- // Update the user. //-------------------------------------------- $finder = &$this->getFinder('users'); $finder->updateWhere("num_tagged_threads=num_tagged_threads+1", "user_id=?", array($user->getId())); //-------------------------------------------- // If we've made it to this point, it means that // no tags have been added/saved and that will will // simply display the form to do so. //-------------------------------------------- $resp->assign('content', 'thread_tag_form.html'); $this->setLayout("forum_base.html"); } //-------------------------------------------- // View the revision history of a thread. //-------------------------------------------- function history(&$reg, &$req, &$resp) { $this->_genericThreadStuff($reg, $req, $resp); //-------------------------------------------- // Set everything to the template. //-------------------------------------------- $resp->assign('content', 'thread_history.html'); $this->setLayout("forum_base.html"); $this->setPage("Thread History"); } //-------------------------------------------- // Do a thread diff. //-------------------------------------------- function diff(&$reg, &$req, &$resp) { $this->_genericThreadStuff($reg, $req, $resp); //-------------------------------------------- // Get the stuff. //-------------------------------------------- $thread = &$resp->getRef('thread'); $info = &new InformationDisplay($reg, $req, $resp); $user = &$reg->get('user'); //-------------------------------------------- // Okay, let's sort out what two versions of // this thread we want to compare. Note: version // 0 (zero) represents the thread. //-------------------------------------------- $diff_a_id = intval($req->get('diff_ver_1')); $diff_b_id = intval($req->get('diff_ver_2')); $diff_a = NULL; $diff_b = NULL; //-------------------------------------------- // So, we're trying to compare two of the same // versions.. that's dumb. //-------------------------------------------- if($diff_a_id == $diff_b_id) { $info->text("There's really no point in comparing two identical revisions of this thread, now is there?"); } //-------------------------------------------- // If one of the diff's if the thread, let's // revert the threads body text. //-------------------------------------------- if($diff_a_id == 0 || $diff_b_id == 0) { $filter = &new K4BBRevertFilter(); $thread->set('body', $filter->filter($thread->get('body'))); } //-------------------------------------------- // Get the two different versions. //-------------------------------------------- $finder = &$this->getFinder('thread_revisions'); if($diff_a_id == 0) { $diff_a = &$thread; $diff_b = &$finder->find($diff_b_id); } else if($diff_b_id == 0) { $diff_b = &$thread; $diff_a = &$finder->find($diff_a_id); } else { $diff_a = &$finder->find($diff_a_id); $diff_b = &$finder->find($diff_b_id); } //-------------------------------------------- // Error check them. //-------------------------------------------- if($diff_a === NULL || $diff_b === NULL) { $info->text("It appears that one of the revisions you have selected does not exist."); } //-------------------------------------------- // Format the two texts a bit. //-------------------------------------------- $text_a = preg_replace("~(\r\n|\r|\n)~", "\n", html_entity_decode($diff_a->get('body'), ENT_QUOTES)); $text_b = preg_replace("~(\r\n|\r|\n)~", "\n", html_entity_decode($diff_b->get('body'), ENT_QUOTES)); $text_a = explode("\n", $text_a); $text_b = explode("\n", $text_b); //print_r($text_a); //-------------------------------------------- // Do the diff. //-------------------------------------------- $this->getPearPackage("Text_Diff"); if($diff_a->get('edit_time') > $diff_b->get('edit_time')) { $diff = &new Text_Diff($text_b, $text_a); } else { $diff = &new Text_Diff($text_a, $text_b); } $renderer = &new Text_Diff_Renderer_inline(); $html = str_replace("\n", "
", $renderer->render($diff)); //-------------------------------------------- // Finish off all the template general stuff. //-------------------------------------------- $resp->assignRef('thread_diff_html', $html); $resp->assign('content', 'thread_diff.html'); $this->setLayout("forum_base.html"); $this->setPage("Thread Revision Comparison"); } //-------------------------------------------- // Delete threads, revisions, etc. //-------------------------------------------- function delete(&$reg, &$req, &$resp) { $this->_genericThreadStuff($reg, $req, $resp); //-------------------------------------------- // Get the stuff. //-------------------------------------------- $thread = &$resp->getRef('thread'); $info = &new InformationDisplay($reg, $req, $resp); $user = &$reg->get('user'); //-------------------------------------------- // Figure out what to delete. //-------------------------------------------- if($req->get('what') == 'thread') { //-------------------------------------------- // We're deleting a thread. //-------------------------------------------- if((!$user->canDo('delete', 'threads') && $user->getId() != $thread->get('user_id')) || !$user->canDo('moderate', 'threads')) { $info->display('permsRequired'); } if($thread->get('deleted') == 1) { $thread->hardDelete(); //-------------------------------------------- // We're done. //-------------------------------------------- $info->text("Successfully hard deleted the thread. It is now completely gone.", "/", 3); } else { $thread->softDelete(); //-------------------------------------------- // We're done. //-------------------------------------------- $info->text("Successfully soft deleted the thread. It is not yet gone and can still be retrieved.", "/", 3); } } else if($req->get('what') == 'revision') { //-------------------------------------------- // We're deleting a thread revision. //-------------------------------------------- if(!$user->canDo('delete', 'threads')) { $info->display('permsRequired'); } //-------------------------------------------- // Delete the revision. //-------------------------------------------- $finder = &$this->getFinder('thread_revisions'); $finder->delete($req->get('rev_id')); //-------------------------------------------- // Redirect... //-------------------------------------------- $url = "/thread/history/". $thread->getId() ."/". k4_us($thread->get('name')) ."/"; $info->text("Successfully deleted the thread revision.", $url, 3); } else { $info->text("You must specify what you want to delete."); } } //-------------------------------------------- // Revert a thread to a previous revision. //-------------------------------------------- function revert(&$reg, &$req, &$resp) { $this->_genericThreadStuff($reg, $req, $resp); //-------------------------------------------- // Get the stuff. //-------------------------------------------- $thread = &$resp->getRef('thread'); $info = &new InformationDisplay($reg, $req, $resp); $user = &$reg->get('user'); if(!$user->canDo('edit', 'threads') && $user->getId() != $thread->get('user_id')) { if($thread->get('allow_coauthors') == 0) { $info->display('permsRequired'); } } //-------------------------------------------- // Revert the thread. //-------------------------------------------- $thread->setUser($user); $thread->revertTo($req->get('rev_id')); //-------------------------------------------- // We're done. //-------------------------------------------- $url = "/thread/history/". $thread->getId() ."/". k4_us($thread->get('name')) ."/"; $info->text("Successfully reverted the thread.", $url, 3); } //-------------------------------------------- // View a single thread revision on its own. //-------------------------------------------- function revision(&$reg, &$req, &$resp) { $this->_genericThreadStuff($reg, $req, $resp); //-------------------------------------------- // Get the stuff. //-------------------------------------------- $thread = &$resp->getRef('thread'); $info = &new InformationDisplay($reg, $req, $resp); //-------------------------------------------- // get the revision. //-------------------------------------------- $finder = &$this->getFinder('thread_revisions'); $revision = &$finder->find($req->get('rev_id')); if($revision === NULL) { $info->text("The selected thread revision does not exist."); } //-------------------------------------------- // Parse the bbcode in the revision's body. //-------------------------------------------- $filter = &new K4BBParserFilter(); $revision->set('body', $filter->filter($revision->get('body'))); //-------------------------------------------- // Set all of the template stuff. //-------------------------------------------- $resp->assignRef('rev', $revision); $resp->assign('content', 'thread_revision_view.html'); $this->setLayout("forum_base.html"); $this->setPage("View Thread Revision"); } //-------------------------------------------- // Get all of a users threads. For the time being, // I'm leaving it able to get threads with the guest // ID (K4_GUEST_ID == 1). //-------------------------------------------- function user(&$reg, &$req, &$resp) { $info = &new InformationDisplay($reg, $req, $resp); $user = &$reg->get('user'); //-------------------------------------------- // Check permissions //-------------------------------------------- if(!$user->canDo('view', 'threads')) { $info->display('permsRequired'); } //-------------------------------------------- // Does the user exist? //-------------------------------------------- $finder = &$this->getFinder('users'); $member = &$finder->find($req->get('user_id')); if($member === NULL) { $info->text("That member doesn't exist!"); } //-------------------------------------------- // Get this member's posts, if necessary. //-------------------------------------------- if($member->get('num_threads') > 0) { $finder = &$this->getFinder('threads'); $threads = &$finder->findAllBy('user_id', $member->getId()); $resp->assignRef('threads', $threads); } //-------------------------------------------- // Finish off with all the usual :D //-------------------------------------------- $resp->assignRef('member', $member); $resp->assign('content', 'thread_view_all_by_member.html'); $this->setLayout("forum_base.html"); $this->setPage("View All: ". $member->get('name')); } } ?>