Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Can I add functions to Image class using DataObjectDecorator?


Reply


4 Posts   1928 Views

Avatar
JonoM

Community Member, 103 Posts

8 October 2010 at 1:37pm

Hello,

I've previously extended Image using this method http://doc.silverstripe.org/recipes:customising_image but it seems to cause headaches - I think because it changes the class in the File table from 'Image' to 'Page_Image'. I end up with broken/missing images if images are used in different ways throughout the site - i.e. used as a standard 'Image' in page content and a 'Page_Image' elsewhere.

I would like to keep all the images using the standard 'Image' class but allow some custom resizing functions to be called on any image - so in the template something like '$Image.ZoomedImage' which returns my image with custom gd functions applied.

Is this possible perhaps using a DataObjectDecorator? I played around with it but I just can't work it out - if anyone can help me out I'd be really grateful!

Avatar
carlos

Community Member, 41 Posts

8 October 2010 at 2:52pm

Hi JonoM,

yes you can add function by a decorator.

you need to do a few things...

in _config.php:

DataObject::add_extension('Image', 'MyImage');

then create the decorator:

<?php
class MyImage extends DataObjectDecorator {
   
   function extraStatics() {
      return array(
         'db' => array(),
         'has_one' => array()
      );
   }
   
   function MyImageFunc(){
      // do something here ...
   }
   
}

then you can call the functions in the decorator

hope it helps

cheers

Avatar
JonoM

Community Member, 103 Posts

8 October 2010 at 5:53pm

Thanks Carlos,

That's basically what I tried - so here's what I have in CustomImage.php:

class CustomImage extends DataObjectDecorator {

function generateZoomedImage($gd) {
$gd->setQuality(90);
$height = $gd->getHeight();
$width = $gd->getWidth();
if ($height > 600 || $width > 600) return $gd->resizeRatio(600,600);
else return $gd;
}
   
}

But if I then call say $Photo.ZoomedImage in a template where $Photo is an image object I don't get any output... any ideas?

Avatar
wmk

Community Member, 46 Posts

26 January 2011 at 5:12am

Hi JonoM,

you unfortunately need two functions Foo() and generateFoo() inside the decorator, because the base class doesn't seem to be aware of the decorated functions:

function generateWebsiteThumbnail($gd) {
$gd->setQuality(85);
return $gd->resizeRatio(150,150);
}

function WebsiteThumbnail() {
return $this->owner->getFormattedImage('WebsiteThumbnail');
}

I guess it's a bug but for now this hack should do.

As you can see in sapphire/core/Object.php the function getAllMethodNames() has a parameter $custom which is default set to false. So image class isn't aware of the decorated functions. You could try to set getAllMethodNames(true) in sapphire/model/Image.php (untested), this would do the trick with only one function.