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've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

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