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

Modify img bbcode

#1
I am trying to initiate myself into the dev side of xenforo and could use some help with a small and straight forward addon.

I intend to run xenforo on a ssl enabled host, the problem as you likely know, is that mixed content warnings appear when for example images are remotely hosted, on non ssl enabled hosts.

I have setup an asset proxy that fetches the images and proxies them, thus making them available over ssl.

I seek to (re)construct the img url's users have and will submit(ted) from :

IMG http://classic.http.image.host.url/image.jpg /IMG

to

IMG https://our-domain/asset-proxy/hash/encoded.classic.image.url /IMG


e.g : https://domain/asset-proxy/712ad3d5...e61736f66742e636f6d2f76697065727369672e6a7067


$hash= hash_hmac('sha1', $url, $key);
$encoded= bin2hex($url);


I'm open to any and all offers.
 
#2
The entire idea of https is that you can't get around https. That said, if the issue is only graphics (jpegs, etc.) then you probably can get around it, by 'under the hood' and transparent to the user, storing the image locally or in the database, and in the hooks that display the avatar simply do a database lookup on the url, and use the field with the image code that is in the database.

Keep in mind, you are responsible for any images hosted on your server, so doing the above makes vigilant image checks important.
 
#3
The entire idea of https is that you can't get around https. That said, if the issue is only graphics (jpegs, etc.) then you probably can get around it, by 'under the hood' and transparent to the user, storing the image locally or in the database, and in the hooks that display the avatar simply do a database lookup on the url, and use the field with the image code that is in the database.

Keep in mind, you are responsible for any images hosted on your server, so doing the above makes vigilant image checks important.
It isn't to get around https, it's to pipe remotely hosted images over our own https connection. avatars are not the problem. Everything works and is set up except for the url hashing and encoding part.

If you have questions, please ask them.
 

xfrocks

Well-known member
#5
You can use load_class_bb_code to extends XenForo_BbCode_Formatter_Base and its method renderTagImage. Just let it render the IMG tag then you can grab the image url using regular expression or something similar. After some magic (calculate your hash and save it to your database and such), replace the image url with your hashed url and return the new <img /> :D
 
#6
You can use load_class_bb_code to extends XenForo_BbCode_Formatter_Base and its method renderTagImage. Just let it render the IMG tag then you can grab the image url using regular expression or something similar. After some magic (calculate your hash and save it to your database and such), replace the image url with your hashed url and return the new <img /> :D
I will give that a try, can I bother you if it doesn't work out?
 

Jeremy

Well-known member
#10
Just reply here. And you should read King Kovifor guide, he's the master of BBCode-land :D
Not the master... Yet. ;) Self-proclaimed expert, yes. :p I attempt to empower the masses... And will attempt to help when I can.

I will do that, thank you.
The guide will explain how to accomplish extending it. Overwriting renderTagImg() is your best bet. Also, seeing as its your program, you can add as many helper functions as you need. These functions are usually protected members of the same class and start with an _, as seen by XenForo's standards.
 
#11
Not the master... Yet. ;) Self-proclaimed expert, yes. :p I attempt to empower the masses... And will attempt to help when I can.


The guide will explain how to accomplish extending it. Overwriting renderTagImg() is your best bet. Also, seeing as its your program, you can add as many helper functions as you need. These functions are usually protected members of the same class and start with an _, as seen by XenForo's standards.
Before your replies I tried modifying the Base.php in the Xen bbcode formatter (to see if i could get anything to work). If it is any indication of how I am struggling:

protected $_imageTemplate ='<img src="/asset-proxy/'. hash_hmac('sha1', '%1$s', $key) . '/' . bin2hex('%1$s') . '" class="bbCodeImage%2$s" alt=""/>';

This is what I tried... Needless to say it didn't work. I will try extending the renderTagImg() function as you said once i'm back from the store and got myself some caffeine.
 

Jeremy

Well-known member
#12
Extending is always the way to go, as it'll survive upgrades. Based on your snippet, I'm not sure what your attempting to do (code wise). I am on my phone, so won't be much help tonight. Sorry! Post any questions and I'll be sure to look after classes.
 

xfrocks

Well-known member
#13
protected $_imageTemplate ='<img src="/asset-proxy/'. hash_hmac('sha1', '%1$s', $key) . '/' . bin2hex('%1$s') . '" class="bbCodeImage%2$s" alt=""/>';
You just can't edit $_imageTemplate. There are 2 reasons
  1. What if someone else also edit $_imageTemplate?
  2. (this one is more important) $_imageTemplate is used in sprintf so obviously it won't work
You should do something like I said below :p

You can use load_class_bb_code to extends XenForo_BbCode_Formatter_Base and its method renderTagImage. Just let it render the IMG tag then you can grab the image url using regular expression or something similar. After some magic (calculate your hash and save it to your database and such), replace the image url with your hashed url and return the new <img /> :D
 
#14
You just can't edit $_imageTemplate. There are 2 reasons
  1. What if someone else also edit $_imageTemplate?
  2. (this one is more important) $_imageTemplate is used in sprintf so obviously it won't work
You should do something like I said below :p
You make it sound so easy, meanwhile i'm stuck at step 4

I have:

PHP:
<?php
 
class CamoUrl_EventListener_BbCode
{
    public static function listen($class, array &$extend)
    {
        if ($class == 'XenForo_BbCode_Formatter_Base')
        {
            $extend[] = 'renderTagImage';
        }
    }
}
in : community/library/CamoUrl/EventListener$

nothing (yet) in : community/library/CamoUrl/CamoUrl/Formatter


When I select this in the Code Event Listeners:

listen to event: loud_class_bb_code
Execute Callback: CamoUrl_EventListener_BbCode :: renderTagImage

addon : the one I just created

I get :
Error
Please enter a valid callback method.

:unsure:
I am way out of my comfort zone here.
 

Jeremy

Well-known member
#16
You make it sound so easy, meanwhile i'm stuck at step 4

I have:

PHP:
<?php
 
class CamoUrl_EventListener_BbCode
{
    public static function listen($class, array &$extend)
    {
        if ($class == 'XenForo_BbCode_Formatter_Base')
        {
            $extend[] = 'renderTagImage';
        }
    }
}
in : community/library/CamoUrl/EventListener$

nothing (yet) in : community/library/CamoUrl/CamoUrl/Formatter


When I select this in the Code Event Listeners:

listen to event: loud_class_bb_code
Execute Callback: CamoUrl_EventListener_BbCode :: renderTagImage

addon : the one I just created

I get :
Error
Please enter a valid callback method.

:unsure:
I am way out of my comfort zone here.
You have misread the extend. You're callback is CamoUrl_EventListener_BbCode::listen(). The $extend[] property is the name of the class where your renderTagImage() overwrite is built. So it should be something like this:
PHP:
<?php
 
class CamoUrl_EventListener_BbCode
{
    public static function listen($class, array &$extend)
    {
        if ($class == 'XenForo_BbCode_Formatter_Base')
        {
            $extend[] = 'CamoUrl_CamoUrl_Formatter';
        }
    }
}
And CamoUrl/CamoUrl/Formatter.php includes the class used to extend ($extend[]) with renderTagImage in there as well.
 
#17
I don't mean to be pedantic, but i tried finding renderTagImg() to no avail, i thought i would be able to lift the existing code into the addon i am (trying to) making.

Is the function by any chance called:

library/XenForo/BbCode/Formatter/Text.php:87:

handleTagImg() ??



/community$ grep -R -i -n 'TagImg' *

library/XenForo/Html/Renderer/BbCode.php:29: 'img' => array('filterCallback' => array('$this', 'handleTagImg')),
library/XenForo/Html/Renderer/BbCode.php:516: public function handleTagImg($text, XenForo_Html_Tag $tag)
library/XenForo/BbCode/Formatter/Text.php:18: 'img' => array('$this', 'handleTagImg'),
library/XenForo/BbCode/Formatter/Text.php:87: public function handleTagImg(array $tag, array $rendererStates)
 
#18
This doesn't do anything :( At some point it did break the possibility to submit threads when I had a " too much in the :

$src = $tag->"$prefix"hash_hmac('sha1',attribute('src'), $camokey). '/' . bin2hex(attribute('src'));

line.

Help?

file: addon_CamoUrl.xml

HTML:
<?xml version="1.0" encoding="utf-8"?>
<addon addon_id="CamoUrl" title="CamoUrl" version_string="1" version_id="1" url="" install_callback_class="" install_callback_method="" uninstall_callback_class="" uninstall_callback_method="">
  <admin_navigation/>
  <admin_permissions/>
  <admin_style_properties/>
  <admin_templates/>
  <code_events/>
  <code_event_listeners>
    <listener event_id="load_class_bb_code" execute_order="10" callback_class="CamoUrl_Listener_LoadClassController" callback_method="loadClassListener" active="1" description="Hooks into the IMG BbCode to re-write urls to a https enabled asset-proxy."/>
  </code_event_listeners>
  <cron/>
  <email_templates/>
  <optiongroups/>
  <permissions>
    <permission_groups/>
    <permissions/>
    <interface_groups/>
  </permissions>
  <phrases/>
  <route_prefixes/>
  <style_properties/>
  <templates/>
</addon>
file: library/CamoUrl/Listener/LoadClassController.php

PHP:
<?php
class CamoUrl_Listener_LoadClassController {
  public static function loadClassListener($class, &$extend) {
    if ($class == 'XenForo_BbCode_Formatter_Base') {
      $extend[] = 'CamoUrl_BbCode_Formatter_Base';
    }
  }
}
?>
file: library/CamoUrl/BbCode/Formatter/Base.php

PHP:
<?php
class CamoUrl_BbCode_Formatter_Base extends XFCP_CamoUrl_BbCode_Formatter_Base {
 
 
      /**
        * Handles IMG tags.
        *
        * @param string $text Child text of the tag (probably none)
        * @param XenForo_Html_Tag $tag HTML tag triggering call
        *
        * @return string
        */
        public function handleTagImg($text, XenForo_Html_Tag $tag)
        {
            if (($tag->attribute('class') == 'mceSmilie' || $tag->attribute('data-smilie')) && $tag->attribute('alt'))
                {
                        // regular image smilies
                        $output = $tag->attribute('alt');
                }
                else if (strpos($tag->attribute('class'), 'mceSmilieSprite') !== false && $tag->attribute('alt'))
                {
                        // sprite smilies
                        $output = $tag->attribute('alt');
                }
                else if (preg_match('#attach(Thumb|Full)(\d+)#', $tag->attribute('alt'), $match))
                {
                        if ($match[1] == 'Full')
                        {
                                $output = '[ATTACH=full]' . $match[2] . '[/ATTACH]';
                        }
                        else
                        {
                                $output = '[ATTACH]' . $match[2] . '[/ATTACH]';
                        }
                }
                else
              {
                                        $prefix = 'https://domain/asset-proxy/';
                                        $camokey = 'secret';
 
                        $src = $tag->"$prefix". hash_hmac('sha1',attribute('src'), $camokey) . '/' . bin2hex(attribute('src'));
                        $output = '';
 
                        if ($src)
                        {
                                if (XenForo_Application::isRegistered('smilies'))
                                {
                                        $smilies = XenForo_Application::get('smilies');
                                }
                                else
{
                                        $smilies = XenForo_Model::create('XenForo_Model_Smilie')->getAllSmiliesForCache();
                                        XenForo_Application::set('smilies', $smilies);
                                }
                                foreach ($smilies AS $smilie)
                                {
                                        if ($src == $smilie['image_url'])
                                        {
                                                $output = reset($smilie['smilieText']);
                                                break;
                                    }
                                }
 
                                if (!$output)
                                {
                                        $output =  "[IMG]" . $this->convertUrlToAbsolute($src) . "[/IMG]";
                                }
                        }
                }
            return $this->renderCss($tag, $output);
        }
 
 
 
 
}
?>
 

Jeremy

Well-known member
#19
In XenForo_BbCode_Formatter_Base, find get tags. Get the function name from the definition of img. How a tag is defined is described in my guide. Overwrite that function. I can take a look when I get home.