Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RTM] Image and Picture as services #342

Merged
merged 65 commits into from Aug 4, 2016

Conversation

ausi
Copy link
Member

@ausi ausi commented Sep 8, 2015

This is a very early draft of the image handling as a service. Here are my ideas:

The new classes Contao\CoreBundle\Image\Image and Contao\CoreBundle\Image\Picture work similar to the current classes, but with dependency injection and without the create and legacy methods. The new Image class uses Imagine to manipulate image data. The Image and Picture objects are created via a factory which is registered in the service container.

The old classes Contao\Image and Contao\Picture are wrappers around the new classes and services to keep backwards compatibility.

Does that make sense?

Questions

  • How do we handle the the hooks executeResize and getImage? To be 100% backwards compatible we would have to pass an instance of the Contao\Image class.
  • Should we still use the Contao\File class?
  • ImageFactory and PictureFactory or Factory with createImage and createPicture methods?
  • Should we split the functionality of how the replaced images are saved/cached into a separate contao.image.cache service?
  • Is the imagine_class configuration node the right way to make the used Imagine class configurable?
  • We would need something like a contao.adapter.model_repository service to get access to the files and image size models.

@ausi ausi changed the title Image and Picture as services [WIP] Image and Picture as services Sep 8, 2015
@aschempp
Copy link
Member

aschempp commented Sep 8, 2015

To tell you my opinion on the basic questions:

  • we should not use Contao\File
  • Two factories is better, each should only have one create method
  • The contao.image.imagine service looks pretty valid to me

Regarding the model_repository, I guess you misunderstood me on that. Each class which currently has a static method should get it's own adapter. So in your case you would probably need contao.adapter.files_model and contao.adapter.image_sizes services.

Also, we should use a compiler pass to automatically detect the available Imagine options and choose the best (= only fallback to GD2 if Imagick is not supported).

@Toflar
Copy link
Member

Toflar commented Sep 9, 2015

Regarding the model_repository, I guess you misunderstood me on that. Each class which currently has a static method should get it's own adapter. So in your case you would probably need contao.adapter.files_model and contao.adapter.image_sizes services.

Thinking about this, I think a general model_repository would be more intelligent. It would also cover non-core models.

@ausi
Copy link
Member Author

ausi commented Sep 9, 2015

Thinking about this, I think a general model_repository would be more intelligent. It would also cover non-core models.

For the image service we would have to inject three models: ImageSizeModel, ImageSizeItemModel and FilesModel. Therefore I think a general model_repository would make it cleaner.

@aschempp
Copy link
Member

aschempp commented Sep 9, 2015

Just think about Doctrine. Each entity has it's repository…

@Toflar
Copy link
Member

Toflar commented Sep 9, 2015

but only one entity manager ;)

@ausi
Copy link
Member Author

ausi commented Sep 9, 2015

But I can inject doctrine and call ->getRepository('...') on it. IMO it would be great to have a single service to get any Contao model from.

@Toflar
Copy link
Member

Toflar commented Sep 9, 2015

But I can inject doctrine and call ->getRepository('...') on it. IMO it would be great to have a single service to get any Contao model from.

👍

@aschempp
Copy link
Member

aschempp commented Sep 9, 2015

But I can inject doctrine and call ->getRepository('...') on it. IMO it would be great to have a single service to get any Contao model from.

True! It just means we will improve our model stuff while we actually wanted to prefer Doctrine ^^

@ausi
Copy link
Member Author

ausi commented Sep 9, 2015

Also, we should use a compiler pass to automatically detect the available Imagine options and choose the best (= only fallback to GD2 if Imagick is not supported).

Like so aaf12ec?

@ausi
Copy link
Member Author

ausi commented Sep 9, 2015

we should not use Contao\File

Where should we put the code for Contao\File::__get('imageSize') then? Into the new Image class itself?

@ausi
Copy link
Member Author

ausi commented Sep 9, 2015

Can I start working on it with the class structure described above?
Or do we need to discuss something before I start?

@leofeyer leofeyer added this to the 4.1.0 milestone Sep 9, 2015
@aschempp
Copy link
Member

I would love to discuss the topic on today's Contao call. The compiler pass looks pretty good.

@ausi
Copy link
Member Author

ausi commented Sep 10, 2015

I will be there.

@ausi
Copy link
Member Author

ausi commented Sep 29, 2015

I added some classes :)

The current proposal would work like this:

$imageFactory->create('foo.jpg') creates an Image and returns it.

$imageFactory->create('foo.jpg', 2) creates an Image, fetches the image size 2 from the database and passes the data to the Resizer. The Resizer passes the configuration to the ResizeCalculator and resizes the image according to the result and returns it.

$pictureFactory->create('foo.jpg', 2) creates an Image, fetches the image size 2 from the database and passes the data to the PictureGenerator. The PictureGenerator uses the Resizer to resize the images and returns a Picture object with the results.

@contao/developers what do you think?


try {
new $class();
break;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realized this can be simplified a lot. Simply return $class here, then you also don't need the if-condition below (just throw the exception).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@Toflar
Copy link
Member

Toflar commented Sep 29, 2015

I think I like the basic approach :-) The only thing I would change to bring even more interoperability would be to use things like ResizerInterface and type hint this instead of a fixed dependency on Resizer so we can easily exchange those :)

@ausi
Copy link
Member Author

ausi commented Sep 29, 2015

@Toflar thanks. I agree we should add some interfaces, but I would like to get a working implementation and then adding the interfaces, to better understand which interfaces could be useful.

$relative = false
) {
$this->size = $size;
$this->relative = (bool) $relative;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is a relative image dimension?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For images with a ratio, but no absolute size. E.g. a SVG image with width="100%" height="100%".
See the difference between File->imageSize and File->imageViewSize in contao/core#7882.

@aschempp
Copy link
Member

I also like the approach in general. I just wonder if the Image class should be mutable at all? Also, I think the factory should not accept an ID of an image configuration (from DB) but directly it's configuration.

@ausi
Copy link
Member Author

ausi commented Sep 29, 2015

I just wonder if the Image class should be mutable at all?

You suggest to add $importantPart as a constructor argument?
I tried to follow the approach to add required attributes to the constructors and optional attributes as setters.

I think the factory should not accept an ID of an image configuration (from DB) but directly it's configuration.

Where should we put the code for that than?

@ausi ausi mentioned this pull request Oct 1, 2015
1 task
@aschempp
Copy link
Member

Now that the adapters are finally merged, I think we can continue with that?

@ausi
Copy link
Member Author

ausi commented Jul 23, 2016

This should be ready for comments now :)

One thing I’d like to discuss before merging is, what should be the Symfony-way alternative to the image hooks executeResize and getImage? In my project I can now easily replace one of the services to add custom behavior, but how can I do that as a Contao bundle?

Note to myself: After this gets merged I should take a look at some other image related feature requests:

@ausi ausi changed the title [WIP] Image and Picture as services [RFC] Image and Picture as services Jul 23, 2016
@ausi ausi changed the title [RFC] Image and Picture as services [RTM] Image and Picture as services Jul 25, 2016
@leofeyer leofeyer added this to the 4.3.0 milestone Jul 28, 2016
public function process(ContainerBuilder $container)
{
$container->setParameter(
'contao.root_dir',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code does not what the phpDoc comment says. Also, we should not add a contao.root_dir parameter.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a way to inject "%contao.root_dir%/%contao.image.target_path%" into the resizer service. Should I use the %kernel.root_dir% instead?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not so easy. I have created a working implementation, but I need to discuss this with you on Mumble.

@leofeyer leofeyer merged commit a9fb428 into contao:develop Aug 4, 2016
@leofeyer leofeyer self-assigned this Aug 4, 2016
@leofeyer
Copy link
Member

leofeyer commented Aug 4, 2016

Merged in 9b6694f.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants