How can I create a censor add-on?

AndyB

Well-known member
Hello,

I would like to create an add-on which does primarily the same thing as seen here:

pic001.webp

The reason I don't use want to use the default Censoring Option is that I would like to be able to censor by User Group, this way I can have for example the word "cat" changed to "***" only for the Unregistered/Unconfirmed user group.

My question is which is the best class to extend if I would like to change the final HTML output.

Thank you.
 
I found that I can add the following code to achieve what I wanted to do.

library/XenForo/Helper/String.php

PHP:
    public static function censorString($string, array $words = null, $censorString = null)
    {
        //########################################
        // start hack
        //########################################
       
        $userId = XenForo_Visitor::getUserId();   
       
        if ($userId > 0)
        {
            return $string;   
        }
   
        //########################################
        // end hack
        //########################################
...

Unfortunately this is a static function so I don't think it's possible to extend this class and therefore I won't be able to make this an add-on.
 
Couldn't you overwrite the function?

I mean, its bad practice... but it could be done.
 
@Andy
Use two listeners:
1) front_controller_pre_dispatch
Get the controler response type and save it inside a static variable ; example:
PHP:
self::$_responseType = $routeMatch->getResponseType();

2) front_controller_post_view
Modify the global output wrapping this modification between a conditional that will check if the response type is a html one (not a json or anything else)
PHP:
if(self::$_responseType == 'html')
{
//Change output
}

P.S : be sure your "censor" replacement doesn't modify any html tags if you don't want your page to be broken.
 
Last edited:
Thank you, cclaerhout. This is exactly the information I needed, I thought there had to be a way to alter the final HTML of a message.
 
This is what I have done so far:

1) Create a new add-on called Censor.
2) Create a Code Event Listener:

pic001.webp

3) Create a Listener.php file:

PHP:
<?php

class Andy_Censor_Listener
{
	public static function frontControllerPreDispatch() 
	{
 		self::$_responseType = $routeMatch->getResponseType(); 
	}
}

The Listener.php file has a problem, this line:

self::$_responseType = $routeMatch->getResponseType();

produces a fatal error when I view my forum.
 
Thank you, cclaerhout.

The Listener.php file now looks like this:

PHP:
<?php

class Andy_Censor_Listener
{
    protected static $_responseType = NULL;
  
    public static function frontControllerPreDispatch()
    {      
         self::$_responseType = $routeMatch->getResponseType();
    }
}

I no longer get the fatal error.
 
Last edited:
Step 2 completed.

pic001.webp

Listener.php

PHP:
<?php

class Andy_Censor_Listener
{
	protected static $_responseType = NULL;
	
	public static function frontControllerPreDispatch() 
	{		
 		self::$_responseType = $routeMatch->getResponseType(); 
	}
	
	public static function frontControllerPostView() 
	{		
		if (self::$_responseType == 'html')
		{
			//Change output
		}
	}	
}
 
The listeners arguments are still missing. Check the example I gave you and read the XenForo listener explanations with their signatures.
 
The listeners arguments are still missing. Check the example I gave you and read the XenForo listener explanations with their signatures.

I read every line very carefully, yet still not sure what I need to add to my Listener.php file.
 
If I enable the Censor add-on, I get the following fatal error:

Fatal error: Call to a member function getResponseType() on a non-object in /home/southbay/www/forums/library/Andy/Censor/Listener.php on line 9
 
Last edited:
I read every line very carefully, yet still not sure what I need to add to my Listener.php file.
PHP:
frontControllerPreDispatch()
=> where are the function arguments ? :rolleyes: Same thing for the one below. You should code less and take a nap ;)
 
pic001_mod.webp
Example:
Wrong:
PHP:
public static function frontControllerPreDispatch()
Correct:
PHP:
public static function frontControllerPreDispatch(XenForo_FrontController $fc, XenForo_RouteMatch &$routeMatch)
 
Exactly the information I needed, thank you cclaerhout.

PHP:
<?php

class Andy_Censor_Listener
{
	protected static $_responseType = NULL;
	
	public static function frontControllerPreDispatch(XenForo_FrontController $fc, XenForo_RouteMatch &$routeMatch)
	{		
 		self::$_responseType = $routeMatch->getResponseType(); 
	}
	
	public static function frontControllerPostView() 
	{		
		if (self::$_responseType == 'html')
		{
			//Change output
		}
	}	
}

No more fatal errors. :)
 
My current Listener.php file:

PHP:
<?php

class Andy_Censor_Listener
{
	protected static $_responseType = NULL;
	
	public static function frontControllerPreDispatch(XenForo_FrontController $fc, XenForo_RouteMatch &$routeMatch)
	{		
 		self::$_responseType = $routeMatch->getResponseType(); 
	}
	
	public static function frontControllerPostView($fc, &$output) 
	{		
		if (self::$_responseType == 'html')
		{
			$userId = XenForo_Visitor::getUserId();  
			
			if ($userId == 0)
			{
				//Change output
			}
		}
	}	
}

I've tried several variables in place of "//Change output" but not able to find the correct one which would be the post message.
 
Look at the signature, the output variable is passed by reference. So just modify it, you should see the modifications.

And be sure what you want to search/replace is enough specific to avoid to modify any important code source.
 
Top Bottom