1. 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?

Discussion in 'XenForo Development Discussions' started by AndyB, Dec 9, 2014.

  1. AndyB

    AndyB Well-Known Member

    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.
     
  2. AndyB

    AndyB Well-Known Member

    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.
     
  3. Jaxel

    Jaxel Well-Known Member

    Couldn't you overwrite the function?

    I mean, its bad practice... but it could be done.
     
  4. Jeremy

    Jeremy XenForo Moderator Staff Member

    You can't overwrite a static function.
     
  5. cclaerhout

    cclaerhout Well-Known Member

    @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: Dec 10, 2014
    AndyB likes this.
  6. AndyB

    AndyB Well-Known Member

    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.
     
  7. AndyB

    AndyB Well-Known Member

    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.
     
  8. cclaerhout

    cclaerhout Well-Known Member

    You didn't create your static variable $_responseType.

    Take a look at this example.
     
  9. AndyB

    AndyB Well-Known Member

    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: Dec 10, 2014
  10. AndyB

    AndyB Well-Known Member

    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
            
    }
        }    
    }
     
  11. cclaerhout

    cclaerhout Well-Known Member

    The listeners arguments are still missing. Check the example I gave you and read the XenForo listener explanations with their signatures.
     
  12. AndyB

    AndyB Well-Known Member

    I read every line very carefully, yet still not sure what I need to add to my Listener.php file.
     
  13. AndyB

    AndyB Well-Known Member

    If I enable the Censor add-on, I get the following fatal error:

     
    Last edited: Dec 10, 2014
  14. cclaerhout

    cclaerhout Well-Known Member

    PHP:
    frontControllerPreDispatch()
    => where are the function arguments ? :rolleyes: Same thing for the one below. You should code less and take a nap ;)
     
  15. AndyB

    AndyB Well-Known Member

    Unfortunately this is all over my head. If I understand correctly, the Listener.php file needs additional code added.
     
    Last edited: Dec 10, 2014
  16. cclaerhout

    cclaerhout Well-Known Member

    pic001_mod.jpg
    Example:
    Wrong:
    PHP:
    public static function frontControllerPreDispatch() 
    Correct:
    PHP:
    public static function frontControllerPreDispatch(XenForo_FrontController $fcXenForo_RouteMatch &$routeMatch
     
  17. AndyB

    AndyB Well-Known Member

    Exactly the information I needed, thank you cclaerhout.

    PHP:
    <?php

    class Andy_Censor_Listener
    {
        protected static 
    $_responseType NULL;
        
        public static function 
    frontControllerPreDispatch(XenForo_FrontController $fcXenForo_RouteMatch &$routeMatch)
        {        
             
    self::$_responseType $routeMatch->getResponseType(); 
        }
        
        public static function 
    frontControllerPostView() 
        {        
            if (
    self::$_responseType == 'html')
            {
                
    //Change output
            
    }
        }    
    }
    No more fatal errors. :)
     
  18. cclaerhout

    cclaerhout Well-Known Member

    Not yet, but soon:

    PHP:
    frontControllerPostView()
    :coffee: ; same logic than above.
     
  19. AndyB

    AndyB Well-Known Member

    My current Listener.php file:

    PHP:
    <?php

    class Andy_Censor_Listener
    {
        protected static 
    $_responseType NULL;
        
        public static function 
    frontControllerPreDispatch(XenForo_FrontController $fcXenForo_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.
     
  20. cclaerhout

    cclaerhout Well-Known Member

    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.
     

Share This Page