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.

We're retiring the forums!

The SilverStripe forums have passed their heyday. They'll stick around, but will be read only. We'd encourage you to get involved in the community via the following channels instead:

General Questions /

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

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

Can I add functions to Image class using DataObjectDecorator?


Go to End


4 Posts   2620 Views

Avatar
JonoM

Community Member, 130 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, 42 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, 130 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, 87 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.