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

How can I create a censor add-on?

AndyB

Well-known member
#1
Hello,

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

pic001.jpg

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.
 

AndyB

Well-known member
#2
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.
 

cclaerhout

Well-known member
#5
@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:

AndyB

Well-known member
#6
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.
 

AndyB

Well-known member
#7
This is what I have done so far:

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

pic001.jpg

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.
 

AndyB

Well-known member
#9
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:

AndyB

Well-known member
#10
Step 2 completed.

pic001.jpg

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
		}
	}	
}
 

cclaerhout

Well-known member
#11
The listeners arguments are still missing. Check the example I gave you and read the XenForo listener explanations with their signatures.
 

AndyB

Well-known member
#13
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:

cclaerhout

Well-known member
#16
pic001_mod.jpg
Example:
Wrong:
PHP:
public static function frontControllerPreDispatch()
Correct:
PHP:
public static function frontControllerPreDispatch(XenForo_FrontController $fc, XenForo_RouteMatch &$routeMatch)
 

AndyB

Well-known member
#17
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. :)
 

AndyB

Well-known member
#19
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.
 

cclaerhout

Well-known member
#20
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.