• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

Get ID of new thread from actionAddThread in my class

infis

Well-known member
#1
I have a class that extends XenForo_Model_Forum, the method actionAddThread.
Unfortunately, I can not in my class to get a ID of new thread except from the
Code:
public function actionAddThread()
{
      $response = parent::actionAddThread();
      $threadLink = $response->redirectTarget;
...
Well, in principle, it can be used. But what if $response provides a link to the forum, not a new thread:
Code:
        if (!$this->_getThreadModel()->canViewThread($thread, $forum))
        {
            $return = XenForo_Link::buildPublicLink('forums', $forum, array('posted' => 1));
        }
        else
        {
            $return = XenForo_Link::buildPublicLink('threads', $thread);
        }
A fully copy of the actionEdit XenForo_ControllerPublic_Thread - is not correct.
What are some ways to get the ID of new thread that you just created?
 

Jake Bunce

XenForo moderator
Staff member
#2
Hmm. You could always pull it from your $threadLink variable with some string operations. Do a preg_match(). If it doesn't match the pattern for a thread link then you know it's not a thread link.
 
R

ragtek

Guest
#3
I have a class that extends XenForo_Model_Forum, the method actionAddThread.
I'm sure you're talking about XenForo_ControllerPublic_Forum ;)



I agree, it's a HUUUUUUGE problem with xenforo...
I really hope we'll get something better in 1.2 for this and more off the controller methods for defining the fetch variables (e.g. _getThreadFetchElements)


some time ago i used the way described by jake, but as you said, if the thread is moderated, it won't work...... :(
PHP:
          $return = parent::actionAddThread();
 
                $target = $return->redirectTarget;    //threads/title.id
 
                $pattern = '/(?P<threads>\w+).(?P<thread_id>\d+)/';
                preg_match($pattern, $target, $matches);
 
                $threadId = $matches['thread_id'];



NOW i'm using this for several customer add-ons:

Code:
select thread_id from xf_thread_read
where user_id = XFVisitor::getUserid()
AND thread_read_date = XenForo_Application::$time
at least for me it's working without problems for this method:)
 
R

ragtek

Guest
#5
But if $response return link to forum, not to thread?
Then we cab not use $return->redirectTarget.
that's why i wrote that i use
Code:
select thread_id from xf_thread_read
where user_id = XFVisitor::getUserid()
AND thread_read_date = XenForo_Application::$time
;)

the reason for this is:

inside of public function actionAddThread()

xf is marking the thread as read for the user
PHP:
$this->_getThreadModel()->markThreadRead($thread, $forum, XenForo_Application::$time);
 
....
 
$this->_getDb()->query('
INSERT INTO xf_thread_read
(user_id, thread_id, thread_read_date)
VALUES
(?, ?, ?)
ON DUPLICATE KEY UPDATE thread_read_date = VALUES(thread_read_date)
', array($userId, $thread['thread_id'], $readDate));
 
}
which means, that you have the thread_id ;)
 

infis

Well-known member
#6
This is not a reliable option, but it can run on a low-loaded forums. Theoretically, it can cause hard errors detected.
 

infis

Well-known member
#7
Thanks Yoskaldyr. He help me for right way.

We are can save in registry output from getMergedData in overrided XenForo_DataWriter_Discussion_Thread. And later get from registry saved output.

MyAddon_DataWriter_Discussion_Thread
PHP:
class MyAddOn_DataWriter_Discussion_Thread extends XFCP_MyAddOn_DataWriter_Discussion_Thread
{
    public function getMergedData($tableName = '')
    {
        $result = parent::getMergedData($tableName);
        XenForo_Application::set('last_thread', $result);
        return $result;
    }
}
MyAddOn_ControllerPublic_Forum
PHP:
class MyAddon_ControllerPublic_Forum extends XFCP_MyAddOn_ControllerPublic_Forum
{
    public function actionAddThread()
    {
        $response = parent::actionAddThread();
        $new_thread=XenForo_Application::get('last_thread');
        $threadId = $new_thread['thread_id'];
        return $response;
    }
}
 

guiltar

Well-known member
#8
For what you need thread id in the rest of controller?
If you want to add some extra fields to DataWriter you can put them to registry, than call parent and catch them in DataWriter.
If you want to do something after thread is created, there is a _postSave in DataWriter.

Also if go this way maybe use _postSave with condition $this->isInsert() instead of getMergedData.
Because getMergedData maybe called everywhere, not necessary after saving.
 

infis

Well-known member
#9
Function _postSave is final and can't be overriding.
Storing data from getMergedData in registry not critical in over calls them create thread.
 

infis

Well-known member
#11
Yes. It's working.
PHP:
class MyAddOn_DataWriter_Discussion_Thread extends XFCP_MyAddOn_DataWriter_Discussion_Thread
{
    protected function _discussionPostSave(array $messages)
    {
        parent::_discussionPostSave($messages);
        $threadId = $this->get('thread_id');
        XenForo_Application::set('last_thread',$threadId);
    }
}
And later we are use this as
PHP:
class MyAddon_ControllerPublic_Forum extends XFCP_MyAddOn_ControllerPublic_Forum
{
    public function actionAddThread()
    {
        $response = parent::actionAddThread();
        $threadId = XenForo_Application::get('last_thread');
        .....
        return $response;
    }
}
 
R

ragtek

Guest
#12
thx for this


seems to be IMO the best solution for this:)
works really nice, we have only to check that not other add-ons are using the same name registry key^^