DarkSign
Active member
Hello XF developers! I am a new coder, so I hope I won't bother you guys so much. I already have read almost all threads here on the dev section.
So, I am writting an add-on that will auto-lock a thread after X posts. I probably am doing it wrong, because I just want to add my custom code on the extended class, and use the parent method to actually save the data.
Here is my try at coding it.
as you can see, I had to rewrite all the parent's method on that extended class. It does the job, but... is it really necessary?
Oh, any other comments on my code is welcomed. I know I am not doing it properly, but again, I am learning PHP OO, and getting help using the XF code itself.
And as it is now, it only locks 1 thread. I want to extend it to use a custom template that will add the checkbox 'Auto lock after' and a text box to put the maxium posts allowed, into that Thread Tools for admins and mods only. So any advice on how to do it would be nice too.
Thank you for your time.
So, I am writting an add-on that will auto-lock a thread after X posts. I probably am doing it wrong, because I just want to add my custom code on the extended class, and use the parent method to actually save the data.
Here is my try at coding it.
Code:
<?php
class DS_AutoLockThreads_ControllerPublic_AutoLockThreads extends XFCP_DS_AutoLockThreads_ControllerPublic_AutoLockThreads
{
public function actionAddReply()
{
$threadOpened = $this->_input->filterSingle('discussion_open', XenForo_Input::UINT); //checking if the thread is locked
if ($threadOpened) //1 for Locked, so that returns true here
{
//no reason to continue, throw Exception
return $this->responseNoPermission();
}
//extracting the Options
$Options = XenForo_Application::get('options');
$this->_assertPostOnly();
if ($this->_input->inRequest('more_options'))
{
return $this->responseReroute(__CLASS__, 'reply');
}
$threadId = $this->_input->filterSingle('thread_id', XenForo_Input::UINT);
//Getting the Model to check the last post
$limitPost = $this->_getPostModel()->getLastPostInThread($threadId);
$visitor = XenForo_Visitor::getInstance();
$ftpHelper = $this->getHelper('ForumThreadPost');
$threadFetchOptions = array('readUserId' => $visitor['user_id']);
$forumFetchOptions = array('readUserId' => $visitor['user_id']);
list($thread, $forum) = $ftpHelper->assertThreadValidAndViewable($threadId, $threadFetchOptions, $forumFetchOptions);
$this->_assertCanReplyToThread($thread, $forum);
if (!XenForo_Captcha_Abstract::validateDefault($this->_input))
{
return $this->responseCaptchaFailed();
}
$input = $this->_input->filter(array(
'attachment_hash' => XenForo_Input::STRING,
'watch_thread_state' => XenForo_Input::UINT,
'watch_thread' => XenForo_Input::UINT,
'watch_thread_email' => XenForo_Input::UINT,
'_set' => array(XenForo_Input::UINT, 'array' => true),
'discussion_open' => XenForo_Input::UINT,
'sticky' => XenForo_Input::UINT,
));
$input['message'] = $this->getHelper('Editor')->getMessageText('message', $this->_input);
$input['message'] = XenForo_Helper_String::autoLinkBbCode($input['message']);
$writer = XenForo_DataWriter::create('XenForo_DataWriter_DiscussionMessage_Post');
$writer->set('user_id', $visitor['user_id']);
$writer->set('username', $visitor['username']);
$writer->set('message', $input['message']);
$writer->set('message_state', $this->_getPostModel()->getPostInsertMessageState($thread, $forum));
$writer->set('thread_id', $threadId);
$writer->setExtraData(XenForo_DataWriter_DiscussionMessage::DATA_ATTACHMENT_HASH, $input['attachment_hash']);
$writer->preSave();
if (!$writer->hasErrors())
{
$this->assertNotFlooding('post');
}
$writer->save();
$post = $writer->getMergedData();
$this->_getThreadWatchModel()->setVisitorThreadWatchStateFromInput($threadId, $input);
$threadUpdateData = array();
if (($limitPost['position']+2 >= $Options->maxPosts) && ($threadId == $Options->threadId))
{
//For some reason, I need to use that +2 hack, so it actually works
//Here is the trick! We lock the thread if the requirements are ok
$input['_set']['discussion_open'] = 1;
}
if (!empty($input['_set']['discussion_open']))
{
if ($thread['discussion_open'] != $input['discussion_open'])
{
$threadUpdateData['discussion_open'] = $input['discussion_open'];
}
}
// discussion sticky state - moderator permission required
if (!empty($input['_set']['sticky']) && $this->_getForumModel()->canStickUnstickThreadInForum($forum))
{
if ($thread['sticky'] != $input['sticky'])
{
$threadUpdateData['sticky'] = $input['sticky'];
}
}
if ($threadUpdateData)
{
$threadWriter = XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread');
$threadWriter->setExistingData($thread['thread_id']);
$threadWriter->bulkSet($threadUpdateData);
$threadWriter->save();
}
$canViewPost = $this->_getPostModel()->canViewPost($post, $thread, $forum);
$page = floor(($thread['reply_count'] + 1) / XenForo_Application::get('options')->messagesPerPage) + 1;
// this is a standard redirect
if (!$this->_noRedirect() || !$this->_input->inRequest('last_date') || !$canViewPost)
{
$this->_getThreadModel()->markThreadRead($thread, $forum, XenForo_Application::$time, $visitor['user_id']);
if (!$canViewPost)
{
$return = XenForo_Link::buildPublicLink('threads', $thread, array('page' => $page, 'posted' => 1));
}
else
{
$return = XenForo_Link::buildPublicLink('posts', $post);
}
return $this->responseRedirect(
XenForo_ControllerResponse_Redirect::SUCCESS,
$return,
new XenForo_Phrase('your_message_has_been_posted')
);
}
else
{
// load a selection of posts that are newer than the last post viewed
$threadModel = $this->_getThreadModel();
$postModel = $this->_getPostModel();
// the max number of posts we want to fetch
$limit = 3;
$postPermissionOptions = $postModel->getPermissionBasedPostFetchOptions($thread, $forum);
$postFetchOptions = $postPermissionOptions + array(
'limit' => ($limit + 1),
'join' => XenForo_Model_Post::FETCH_USER | XenForo_Model_Post::FETCH_USER_PROFILE,
);
if (!empty($postPermissionOptions['deleted']))
{
$postFetchOptions['join'] |= XenForo_Model_Post::FETCH_DELETION_LOG;
}
$lastDate = $this->_input->filterSingle('last_date', XenForo_Input::UINT);
$posts = $postModel->getNewestPostsInThreadAfterDate(
$threadId, $lastDate, $postFetchOptions
);
// We fetched one more post than needed, if more than $limit posts were returned,
// we can show the 'there are more posts' notice
if (count($posts) > $limit)
{
$firstUnshownPost = $postModel->getNextPostInThread($threadId, $lastDate, $postPermissionOptions);
// remove the extra post
array_pop($posts);
}
else
{
$firstUnshownPost = false;
}
// put the posts into oldest-first order
$posts = array_reverse($posts, true);
$posts = $postModel->getAndMergeAttachmentsIntoPosts($posts);
$permissions = $visitor->getNodePermissions($thread['node_id']);
foreach ($posts AS &$post)
{
$post = $postModel->preparePost($post, $thread, $forum, $permissions);
}
// mark thread as read if we're showing the remaining posts in it or they've been read
if ($visitor['user_id'])
{
if (!$firstUnshownPost || $firstUnshownPost['post_date'] <= $thread['thread_read_date'])
{
$this->_getThreadModel()->markThreadRead($thread, $forum, XenForo_Application::$time, $visitor['user_id']);
}
}
$viewParams = $this->_getDefaultViewParams($forum, $thread, $posts, $page, array(
'firstUnshownPost' => $firstUnshownPost,
'lastPost' => end($posts),
));
return $this->responseView(
'XenForo_ViewPublic_Thread_ViewNewPosts',
'thread_reply_new_posts',
$viewParams
);
}
}
}
as you can see, I had to rewrite all the parent's method on that extended class. It does the job, but... is it really necessary?
Oh, any other comments on my code is welcomed. I know I am not doing it properly, but again, I am learning PHP OO, and getting help using the XF code itself.
And as it is now, it only locks 1 thread. I want to extend it to use a custom template that will add the checkbox 'Auto lock after' and a text box to put the maxium posts allowed, into that Thread Tools for admins and mods only. So any advice on how to do it would be nice too.
Thank you for your time.