How to make changes to the thread title?

AndyB

Well-known member
I would like to create an add-on that will limit the number of characters in thread titles. Unfortunately it's not possible to extend XenForo/DataWriter/Discussion.php file because it's an abstract class.

What the add-on would do is simply trim the characters at the end of a thread title that is about to be saved.

Does anyone know which file I can extend?

Thank you.
 
XenForo_DataWriter_Discussion_Thread should be extends this if you want to change some things in table `xf_thread` ;)
 
There should already be an option to limit the number of characters in a thread title in the Admin CP.
 
You mean this?

PHP:
	protected function _discussionPreSave()
	{
		if ($this->get('prefix_id') && $this->isChanged('node_id'))
		{
			if (!$this->_getPrefixModel()->getPrefixIfInForum($this->get('prefix_id'), $this->get('node_id')))
			{
				$this->set('prefix_id', 0); // invalid prefix
			}
		}
	}
 
You mean this?

PHP:
    protected function _discussionPreSave()
    {
        if ($this->get('prefix_id') && $this->isChanged('node_id'))
        {
            if (!$this->_getPrefixModel()->getPrefixIfInForum($this->get('prefix_id'), $this->get('node_id')))
            {
                $this->set('prefix_id', 0); // invalid prefix
            }
        }
    }
Yep! To get thread title you should be call: $this->get('title');
 
Your information is fantastic, Nobita.Kun. Thank you.

Now I just need to figure out how to put the modified title back into the variable that needs to be updated.
 
Last edited:
I assume I need to look at this function for an example:

XenForo/DataWriter/Discussion.php

PHP:
	protected final function _preSave()
	{
		if ($this->isInsert() && $this->getOption(self::OPTION_REQUIRE_INSERT_FIRST_MESSAGE) && !$this->_firstMessageDw)
		{
			throw new XenForo_Exception('A discussion insert was attempted without the required first message.');
		}

		if ($this->isInsert() && !$this->isChanged('discussion_state'))
		{
			$this->set('discussion_state', 'visible');
		}

		$this->_setDynamicFieldDefaults();
		$this->_discussionPreSave();

		if ($this->_firstMessageDw)
		{
			$this->_syncFirstMessageDw();
			$this->_preSaveFirstMessageDw();
		}
	}
 
Unfortunately it's not possible to extend XenForo/DataWriter/Discussion.php file because it's an abstract class.
Sure? Have you tried it?;) (EDIT: ok i've seen this => http://xenforo.com/community/threads/extending-datawriter_discussion.14368/ BUT I'M 100% sure, that i've done it in the past and that i was able to use
PHP:
if ($this instanceOf ...)

2. There's already a method for this:p

PHP:
  /**
    * Verifies that the discussion title is valid
    *
    * @param string
    *
    * @return boolean
    */
   protected function _verifyTitle(&$title)
   {
     // TODO: send these to callbacks to allow hookability?

     switch ($this->getOption(self::OPTION_ADJUST_TITLE_CASE))
     {
       case 'ucfirst': // sentence case
         $title = utf8_ucfirst(utf8_strtolower($title));
         break;

       case 'ucwords': // title case
         $title = utf8_ucwords(utf8_strtolower($title));
         break;
     }

     if ($this->getOption(self::OPTION_TRIM_TITLE))
     {
       $table = reset($this->_fields);
       $title = XenForo_Helper_String::wholeWordTrim($title, $table['title']['maxLength'] - 5);
     }

     return true;
   }
You could customize $table['title']['maxLength'] (just saying)
 
Last edited:
Hi Andy,

there are some classes that can not be extended within the xenforo system. However most classes are meant to be extended. The idea of an abstract class is to provide a basic foundation for other classes, that extend the abstract one.

And it's also true that whenever you take a look at your existing addon, you might find one more specific method already existing in xenforo which makes your addon act in a more straight forward way. As the phantom is pointing out here.
 
I'M 100% sure, that i've done it in the past and that i was able to use
PHP:
if ($this instanceOf ...)

Interesting. That's something to keep in mind for future add-on that I'm not able to extend easily.

As always, thank you kindly for your help.
 
Hi Andy,

there are some classes that can not be extended within the xenforo system. However most classes are meant to be extended. The idea of an abstract class is to provide a basic foundation for other classes, that extend the abstract one.

Thank you, Marcus. I was wondering about that. I'm sill so amazed at how well XenForo was thought out by the developers.
 
Interesting. That's something to keep in mind for future add-on that I'm not able to extend easily.

As always, thank you kindly for your help.
I hadn't time to check if the abstract proxy extending is working (and/or why it was working for me) but while a quick search in my addons code, i've seen that i've used it this way:
PHP:
  /**
    * addon data related datawriters
    * @devtools verify_array_post_xfupgrade
    * @devtools_msg "**new addon data relevant datawriters available?**"
    *
    * @return array
    */
   public static function getAddonDataWriters(){
     return [
       'XenForo_DataWriter_AddOn',
       'XenForo_DataWriter_AdminNavigation',
       'XenForo_DataWriter_AdminPermission',
       'XenForo_DataWriter_AdminTemplate',
       'XenForo_DataWriter_AdminTemplateModification',
       'XenForo_DataWriter_CodeEventListener',
       'XenForo_DataWriter_CodeEvent',
       'XenForo_DataWriter_CodeEventListener',
       'XenForo_DataWriter_CronEntry',
       'XenForo_DataWriter_EmailTemplate',
       'XenForo_DataWriter_EmailTemplateModification',
       'XenForo_DataWriter_Option',
       'XenForo_DataWriter_OptionGroup',
       'XenForo_DataWriter_Permission',
       'XenForo_DataWriter_PermissionGroup',
       'XenForo_DataWriter_PermissionInterfaceGroup',
       'XenForo_DataWriter_Phrase',
       'XenForo_DataWriter_RoutePrefix',
       'XenForo_DataWriter_StyleProperty',
       'XenForo_DataWriter_StylePropertyDefintion',
       'XenForo_DataWriter_StylePropertyGroup',
       'XenForo_DataWriter_Template',
       'XenForo_DataWriter_TemplateModification',
     ];
  }
  

public static function loadClassDatawriter($class, &$extend){
  if (
  #!self::$baseExtended &&
  in_array($class, self::getAddonDataWriters())){
  #  self::$baseExtended = true;
  $extend[] = 'Devtools_Extend_XenForo_DataWriter';
  }



// and inside my proxyclass i'm able to run e.g.
  protected function _preSave(){
  parent::_preSave();

  // xenforo doesn't check if the class exists, bugreport was moved to "feature request" .....
  if ($this instanceof XenForo_DataWriter_RoutePrefix){
  if ($this->isChanged('route_class'))
  {
  $class = $this->get('route_class');

  if (!XenForo_Application::autoload($class))
  {
  $this->error(new XenForo_Phrase('please_enter_valid_callback_method_x_y', array('class' => $class)), 'route_class');
  }
  }
  }
  }
 
Last edited:
Thank you, xf_phantom. You're knowledge of XenForo has me humbled. Thank you for sharing and it's great to know that just about anything is possible in XenForo, just have to search for the solution and hopefully get some help from experts like yourself.
 
Top Bottom