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

Create a thread prefix with php

tenants

Well-known member
#2
I'm not really sure what it is you would like to do

If you actually want to "create" a thread prefix with php, the thread prefix ids and phrases are stored in the database, look at this file to show how they are created: XenForo_DataWriter_ThreadPrefix. You'll notice that this datawriter is used on line 145 of XenForo_ControllerAdmin_ThreadPrefix as an example of how it's used

But I don't think you actually want to "create" one, a bit more detail of what you've done already and how you intend to use the prefixes might be helpful,

I have played with prefixes quite a lot

If you have the thread prefix id, you can get the prefix phrase using:


Code:
$threadprefix = new XenForo_Phrase($prefixModel->getPrefixTitlePhraseName($thread['prefix_id']));
If you want to get a list of all the prefix ids available to a forum you can use this:

Code:
$prefixIds = array_keys($prefixModel->getPrefixesInForum($forumId));
The first place I would look is the prefix model, and from there you can figure out what is available to you for retrieving/ playing with thread prefixes: xenforo\library\XenForo\Model\ThreadPrefix.php
 

Lu Jia

Active member
#3
I'll try to give you more info :)
At the moment I'm using this code

PHP:
$writer = XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread');
        $writer->set('user_id', $visitor['user_id']);
        $writer->set('username', $visitor['username']);
        $writer->set('title', $input['subject']);
                $postWriter = $writer->getFirstMessageDw();
        $postWriter->set('message', $input['message']);
 
        $writer->set('node_id', $forumId);
                $writer->preSave();
                $writer->save();
                $thread = $writer->getMergedData();
                  return $this->responseRedirect(
                XenForo_ControllerResponse_Redirect::SUCCESS,
                $this->getDynamicRedirect(),
                new XenForo_Phrase('your_message_has_been_sent')
            );
to create a thread.
I want to know a similar code for thread prefix.
Thanks in advance
 

tenants

Well-known member
#4
okay, so you really do want to create a prefix. Look at the code on line 145 of XenForo_ControllerAdmin_ThreadPrefix (inside public function actionSave() ):

PHP:
$dw = XenForo_DataWriter::create('XenForo_DataWriter_ThreadPrefix');
if ($prefixId)
{
$dw->setExistingData($prefixId);
}
$dw->bulkSet(array(
'prefix_group_id' => $input['prefix_group_id'],
'display_order' => $input['display_order'],
'css_class' => $input['css_class'],
'allowed_user_group_ids' => $allowedGroupIds
));
$dw->setExtraData(XenForo_DataWriter_ThreadPrefix::DATA_TITLE, $input['title']);
$dw->save();
 
$this->_getPrefixModel()->updatePrefixForumAssociationByPrefix($dw->get('prefix_id'), $input['node_ids']);
The data writer it's self will tell you what params you need to supply: XenForo_DataWriter_ThreadPrefix
 

tenants

Well-known member
#6
$input is what has been sent to the action via a post request

PHP:
$input = $this->_input->filter(array(
'title' => XenForo_Input::STRING,
'prefix_group_id' => XenForo_Input::UINT,
'display_order' => XenForo_Input::UINT,
'css_class' => XenForo_Input::STRING,
'usable_user_group_type' => XenForo_Input::STRING,
'user_group_ids' => array(XenForo_Input::UINT, 'array' => true),
'node_ids' => array(XenForo_Input::UINT, 'array' => true),
));
node_ids it's self is sent as an array.
 

Lu Jia

Active member
#7
PHP:
                $writer = XenForo_DataWriter::create('XenForo_DataWriter_ThreadPrefix');
                    $writer->set('title', $minTitle);
                    $writer->set('prefix_group_id', 1);
                    $writer->set('css_class', 'prefix prefixPrimary');
                    $writer->set('node_ids', $node_ids);
                    $writer->preSave();
                    $writer->save();
Return an error:

Code:
The field 'title' was not recognised.
The field 'node_ids' was not recognised.
I guess my code is wrong, someone knows the right code to do it?
 

Lu Jia

Active member
#8
If I remove
PHP:
                    $writer->set('title', $minTitle);
                    $writer->set('node_ids', $node_ids);
It works but the prefix name is: thread_prefix_4. Where 4 is the prefix_id. Any idea how to set title and node where the prefix is usable?

I found the way to insert the title
PHP:
                    $writer->setExtraData(XenForo_DataWriter_ThreadPrefix::DATA_TITLE, $minTitle);
Just node_ids left :)
I tried something and found this error:

Fatal error: Call to undefined method JvCMS_ControllerPublic_Staff_Blog_Admin::_getPrefixModel() in /.../Staff/Blog/Admin.php on line 199

PHP:
$this->_getPrefixModel()->updatePrefixForumAssociationByPrefix($writer->get('prefix_id'), $node_ids);
 

tenants

Well-known member
#9
It might be better if you tell me what you are trying to accomplish, from the looks for it you want to create prefixes for your own custom blog plugin?

In which case, you might be better off creating your own datawriter

The datawriter that you are using is the core one (look at the file \library\XenForo\DataWriter\ThreadPrefix.php), so it expects the following:
PHP:
'prefix_id'              => array('type' => self::TYPE_UINT, 'autoIncrement' => true),
'prefix_group_id'        => array('type' => self::TYPE_UINT, 'default' => 0),
'display_order'          => array('type' => self::TYPE_UINT_FORCED, 'default' => 0),
'materialized_order'    => array('typpe' => self::TYPE_UINT_FORCED, 'default' => 0),
'css_class'              => array('type' => self::TYPE_STRING, 'maxLength' => 50, 'default' => ''),
'allowed_user_group_ids' => array('type' => self::TYPE_UNKNOWN, 'default' => '',
'verification' => array('$this', '_verifyAllowedUserGroupIds')
node_id and title is not present here (so this will throw an error if you try to use this datawriter to save them)... as you have seen

The $minTitle that you are trying to save I assume is the thread prefix title?

To make this easy to follow, just attempt to create a new thread_prefix (and see where the form gets submitted)
You will find the form gets submited to "admin.php?thread-prefixes/save"

We can look at the routes to see what file "thread-prefixes/save" is in, but a good guess might be that it's within a file name ThreadPrefixes using a function : actionSave() and that file is within the ControllerAdmin (since we are in the ACP)

hence: XenForo_ControllerAdmin_ThreadPrefix

And then find this function: actionSave()

(please look at this file, its all in there: library\XenForo\ControllerAdmin\ThreadPrefix.php)

So for the datawriter: XenForo_DataWriter_ThreadPrefix
you need to set:
Code:
$dw->bulkSet(array(
'prefix_group_id' => $input['prefix_group_id'],
'display_order' => $input['display_order'],
'css_class' => $input['css_class'],
'allowed_user_group_ids' => $allowedGroupIds
));
and then to set the title, you need to use
Code:
$dw->setExtraData(XenForo_DataWriter_ThreadPrefix::DATA_TITLE, $input['title']);
and then $dw->save();

You will also need to associate it to a forum node_id if you expect to use it within a give forum
Code:
$this->_getPrefixModel()->updatePrefixForumAssociationByPrefix($dw->get('prefix_id'), $input['node_ids']);
 

tenants

Well-known member
#10
It works but the prefix name is: thread_prefix_4. Where 4 is the prefix_id. Any idea how to set title and node where the prefix is usable?
That is correct, that is how prefixes are saved.. the titles are saved within phrases


As mentioned, to get this title you will need to use:

Code:
$threadprefix = new XenForo_Phrase($prefixModel->getPrefixTitlePhraseName($thread['prefix_id']));
If you look at your phrases and search through them, you will find a bunch of them named:
thread_prefix_1, thread_prefix_2 etc

if you look closer at the getPrefixTitlePhraseName function, you will see that it calls the phrase:


Code:
public function getPrefixTitlePhraseName($prefixId)
{
return 'thread_prefix_' . $prefixId;
}
 

Lu Jia

Active member
#11
Yeah, my code works fine. I just want to know hot to assign the thread_prefix to a node.

You will also need to associate it to a forum node_id if you expect to use it within a give forum

Code:
$this->_getPrefixModel()->updatePrefixForumAssociationByPrefix($dw->get('prefix_id'), $input['node_ids']);

How can I add this code in my custom addon?
 

Lu Jia

Active member
#12
That is correct, that is how prefixes are saved.. the titles are saved within phrases


As mentioned, to get this title you will need to use:

Code:
$threadprefix = new XenForo_Phrase($prefixModel->getPrefixTitlePhraseName($thread['prefix_id']));
If you look at your phrases and search through them, you will find a bunch of them named:
thread_prefix_1, thread_prefix_2 etc
This code works fine to assign a title to a thread prefix:

PHP:
$dw->setExtraData(XenForo_DataWriter_ThreadPrefix::DATA_TITLE, $input['title']);
 

tenants

Well-known member
#13
That depends on your custom add on, does you custom add-on use forum nodes, if so just pass the correct forum node into the updatePrefixForumAssociationByPrefix

If not, does it use nodes at all? Maybe in your case you don't even need to associate it to a node, but you need a way of retrieving it (I can't really say without knowing how your custom plugin works...)
 

Lu Jia

Active member
#14
My blog addon is a multi blog addon.
When you create a new blog the system will create a new thread pref'ix for the "news" forum. (that's what I need)
Whenever a user create a news the system will create a thread in the "news" forum with the created thread_prefix.

I tried updatePrefixForumAssociatonByPrefix but it return an error. Can you help me to fix it?

I tried something and found this error:

Fatal error: Call to undefined method JvCMS_ControllerPublic_Staff_Blog_Admin::_getPrefixModel() in /.../Staff/Blog/Admin.php on line 199

PHP:
$this->_getPrefixModel()->updatePrefixForumAssociationByPrefix($writer->get('prefix_id'), $node_ids);