Overriding Image Helper to pass all image URLs through another domain

Permalink
Hi All,

I am trying to figure out the best way to load all images via CDN which will use a different url than the main site so that only images are loaded from CDN to speed up performance using cloudflare.

We only want images via CDN as concrete5 admin area doesn't work behind the default cloudflare CDN setup without configuration which we haven't looked at yet, this seems like the simplest approach.

Domain setup will simply be site.com.au and images.site.com.au wheres images.site.com.au is parked on top of site.com.au.

I have been able to get this functionality by editing the /concrete/src/Html/Image.php file and adding '//images.site.com.au' with the $path variables in the __construct function but I am unable to figure out how to override only this file.

I have followed examples inhttps://documentation.concrete5.org/tutorials/override-almost-any-co...
and other guides such ashttps://www.jero.co.nz/blog/overriding-concrete-57-core-service/...
but have had no luck in finding a guide for what i specifically want to do.

I am using Concrete 8.2.1

I updated /application/config/app.php with:
return array(
'providers' => array(
'core_html' => '\Application\Src\Html\HtmlServiceProvider'
)
);

I copied /concrete/src/Html/HtmlServiceProvider.php to /application/src/Html/HtmlServiceProvider.php and updated:
<?php
namespace Application\Src\Html;

use Concrete\Core\Foundation\Service\Provider as ServiceProvider;

class HtmlServiceProvider extends ServiceProvider
{
public function register()
{

$this->app->bind('html/image', '\Application\Src\Html\Image');
}
}

I copied /concrete/src/Html/Image.php to /application/src/Html/Image.php and updated the namespace:
<?php
namespace Application\Src\Html;

I get the following error:
Fatal error: Class '\Application\Src\Html\HtmlServiceProvider' not found in /home/cws/public_html/concrete/src/Foundation/Service/ProviderList.php on line 32

I would greatly appreciate any assistance, thanks in advance.

 
mnakalay replied on at Permalink Reply
mnakalay
I'm afraid my knowledge of CDNs is limited but have you looked into this add-onhttp://www.concrete5.org/marketplace/addons/use-cdn...
memedia replied on at Permalink Reply
Thanks for the suggestion mate it appears to do the job for now

Really would appreciate a Concrete5 Guru who can describe how to override this image helper correctly as it would help me and probably many others as I cannot find anything on the forums or in any concrete5 guides regarding this.
mnakalay replied on at Permalink Best Answer Reply
mnakalay
my knowledge of overrides is a bit better than of CDNs :)

It's a bit of a pain but you need to put your files in 'application\src\Concrete\Html'

Make sure you respect the upper case and lower case

And then the namespaces must be 'Application\Concrete\Html'

That will work.
memedia replied on at Permalink Reply
Awesome, thanks mate!
Can you explain why i havent seen that explained anywhere or why we have to do it like that?

For anyone wanting to override the image helper to force all images to use a different CDN domain for performance reasons, here is a simplified guide:
1) Create the /application/src/Concrete/Html/ directory, then copy/paste Image.php from /concrete/src/Html/ into this directory

2) edit the namespace on line 2
from
namespace Concrete\Core\Html;
to
namespace Application\Concrete\Html;

3) Create and/or edit the /application/bootstrap/app.php file and add the following to override the helper.
$this->app->bind('html/image', '\Application\Concrete\Html\Image');
This will overwrite the binding which is set in /concrete/src/Html/HtmlServiceProvider.php
In my testing, my image helper override worked without having to override anything else.

4) Everything should be working as normal without errors.
Next we want to add our domain to the front of the relative path being used on the site.
If your site is using a full domain, eghttp://site.com.au/....image.jpg,... you will need to do a str_replace or preg_replace function on the domain.
( Note: Template, CSS images will have to be updated to the CDN url manually )
edit line 62:
$this->tag = \Concrete\Core\Html\Object\Picture::create($sources, '//images.site.com.au' . $fallbackSrc);
edit line 69:
$this->tag = \HtmlObject\Image::create('//images.site.com.au' . $path);

Note: For this setup you will need to create a CNAME record of images.site.com.au which points to site.com.au

And in cpanel, add images.site.com.au as a parked domain on top of your site.

Then turn on CDN within cloudflare for just images.site.com.au, now all your images are cached on the CDN reducing your servers load, and hopefully improving your load times.

Of course clear cache when doing this as well.

If anyone has anything useful to add, feel free.
A3020 replied on at Permalink Reply
A3020
Thanks for sharing your solution memedia. I'm thinking about this, but it seems already quite complicated. Can't Cloudflare cache the images automatically? I mean, if your HTML is also cached by CF, they might as well manipulate it and change the image paths?

I don't quite get yet why you'd want to hardcode this in a project. It seems like your site(s) will become less flexible and more 'vendor' locked in with this approach.
mnakalay replied on at Permalink Reply
mnakalay
Aha!!!, the reason it is like that is very simple and makes so much sense once you understand the underlying philosophy behind... nah... I got nothing.

It's like that because the core team made it like that and here's the doc explaining it:https://documentation.concrete5.org/developers/extending-concrete5-w...