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

[Dependency Injection] [Filter] Implement filter service abstraction for creating images #922

Merged
merged 28 commits into from Nov 27, 2017
Merged

Conversation

rpkamp
Copy link
Contributor

@rpkamp rpkamp commented May 5, 2017

Q A
Branch? 2.0
Bug fix? no
New feature? no
BC breaks? yes
Deprecations? no
Tests pass? yes
Fixed tickets
License MIT
Doc PR

This PR splits all the image manipulation from the ImagineController and ResolveCacheCommand classes to a new FilterService class, which was on the roadmap for 2.x:

Move Controller Business Logic into Service (Allow for use of service without Request)

The advantages of this are:

  • Controller is only concerned with HTTP infrastructure
  • Command is only concerned with CLI I/O
  • Controller and command are easier to read, more highlevel
  • Functionality is easier to use and extend in custom controllers/command from third parties
  • FilterManager#applyFilter is only called in one spot throughout the entire codebase, making it easier to allow for multiple filter implementations later on

This PR is missing tests for the FilterService class, but I intend to add those once everyone agrees on a general direction of this PR. I did test the functionality in the browser (by using it in a separate test project) and that works as expected.

Discussion
In the FilterService the method createFilteredImage is closely tied to getUrlOfFilteredImage, but the first is to create the image and the latter is to retrieve the URL of the created image. Same thing goes for createFilteredImageWithRuntimeFilters and getUrlOfFilteredImageWithRuntimeFilters.
I split these out because of the CQS principle, but have now introduced a temporal coupling between the two. A more pure CQS approach would be to generate a URL first and then pass it to createFilteredImage as the desired URL for the image. However, it would be a mayor overhaul at this point to accomplish that, if indeed it is at all possible.

An alternative could be to let createFilteredImage return the URL of the resulting image (whether is was obtained from cache or not) in kind of find-or-create pattern way. This breaks CQS, but might be easier to understand and is less verbose in usage because one would only need one call instead of two to create a filtered image and obtain its URL.

@rpkamp rpkamp changed the title Image service Introduce FilterService as abstraction for creating images May 5, 2017
* @param array|null $runtimeFilters
* @return \Liip\ImagineBundle\Binary\BinaryInterface
* @throws \Liip\ImagineBundle\Exception\Imagine\Filter\NonExistingFilterException
*/
Copy link
Collaborator

Choose a reason for hiding this comment

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

All doc blocks need their CS fixes such that they are ordered param, throws, return, each type is separated by a two newlines, and have their param variables aligned. We also use short class names, even if they aren't used in the current file a and require an additional use statement.

/**
 * @param string     $path
 * @param string     $filter
 * @param array|null $runtimeFilters
 *
 * @throws \Liip\ImagineBundle\Exception\Imagine\Filter\NonExistingFilterException
 *
 * @return \Liip\ImagineBundle\Binary\BinaryInterface
 */

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm confused regarding using short class names, as you said the complete opposite in this comment: https://github.com/liip/LiipImagineBundle/pull/908/files/f9cb8243475a1e492cb77ac5e639d306381fe9a8#diff-3edb79e074a2b20890b43396b316b5d3L60

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Or is the short class name only used for @param but not for @throws and @return?

Copy link
Collaborator

@robfrawley robfrawley May 5, 2017

Choose a reason for hiding this comment

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

My bad, regarding the referenced comment, I thought that was a @covers which is where we've been adding leading backslashes. That, too, should be fixed, I just skimmed over what it was too fast. :-(

Copy link
Collaborator

Choose a reason for hiding this comment

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

We have a php-cs-fixer require-dev requirement as well as the associated style settings; I would just run that, which will take care of everything but the FQCNs.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Erm, looks like our fixer rules are out of date and most of them are skipped, so that isn't a sure-fire bet either...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is this what you mean? 4bce009

Copy link
Collaborator

Choose a reason for hiding this comment

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

Short of the FQCNs that still exist, yes.

Copy link
Collaborator

@robfrawley robfrawley May 5, 2017

Choose a reason for hiding this comment

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

The @cover instances should be the only examples of FQCNs (and I don't know that we have a real policy for @see yet), but we do always use short names for method doc blocks

https://github.com/liip/LiipImagineBundle/blob/1.0/Tests/Binary/Loader/FileSystemLoaderTest.php#L22

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah yes, that makes sense. Thanks.

@robfrawley robfrawley added this to the 2.0.0 milestone May 6, 2017
@robfrawley robfrawley added Attn: BC Break This issue or PR results in a backwards-compatibility break and therefore requires a major release. Level: Enhancement ✨ This item involves an enhancement to existing functionality. State: Reviewing This item is being reviewed to determine if it should be accepted. labels May 6, 2017
@robfrawley
Copy link
Collaborator

robfrawley commented May 6, 2017

The RST documentation (which is what is pushed to Symfony's online documentation website) requires changes and additional pertinent to this change, as well.

The general intention (and the vast majority of implementation) looks really great. I'll try to provide a full review by the end of this weekend with any comments I have. Thanks for this; it ticks off one of the larger TODO items from our 2.x roadmap.

@rpkamp
Copy link
Contributor Author

rpkamp commented May 8, 2017

I've merged this PR with master so I could use short array syntax again 🎉

@Koc
Copy link
Contributor

Koc commented May 8, 2017

Lets wait until #926 will be merged into 2.0

@Koc
Copy link
Contributor

Koc commented May 8, 2017

Also closes #806

@rpkamp
Copy link
Contributor Author

rpkamp commented May 9, 2017

Not sure what's going on with #926 since it's closed but not merged?

@robfrawley
Copy link
Collaborator

The 1.x branch will be merged with 2.0 once we release 1.8.0 (see #928).

@Koc
Copy link
Contributor

Koc commented May 10, 2017

You need apply your service also here https://github.com/liip/LiipImagineBundle/blob/2.0/Async/ResolveCacheProcessor.php
//cc @makasim

@robfrawley
Copy link
Collaborator

All branches up to date.

@rpkamp
Copy link
Contributor Author

rpkamp commented May 10, 2017

I've updated the ResolveCacheProcessor to make use of the new FilterService.
See 05afc99

@rpkamp
Copy link
Contributor Author

rpkamp commented May 14, 2017

Does anyone have any thoughts on the CQS vs Temporal Coupling discussion in my initial PR message?

The more I think about it, the more I think I'd rather have a CQS violation than temporal coupling, so instead of one method to query what the URL would be and a command to create the image, create one find-or-create method that creates the image if it doesn't exist and then return the URL, or if the image already existed just return the URL.
The reason I like it better is because it easier to understand and harder to get wrong for people starting out with this bundle.

@robfrawley
Copy link
Collaborator

@rpkamp

Let createFilteredImage return the URL of the resulting image (whether is was obtained from cache or not) in kind of find-or-create pattern way. This breaks CQS, but might be easier to understand and is less verbose.

Yes, I absolutely prefer this approach.

By coupling the creation of the filtered image to resolvig the URL
of the resolving image the use case of requesting the URL of a filtered
image that has not been created yet (temporal coupling issue) is no
longer possible. The current implementation breaks CQS, but this
is not as bad as the previous temporal coupling.
@rpkamp
Copy link
Contributor Author

rpkamp commented May 20, 2017

@robfrawley

Yes, I absolutely prefer this approach.

Done. This approach makes more sense for this project than the previous approach 😃

@rpkamp
Copy link
Contributor Author

rpkamp commented May 25, 2017

Could I get a review on this one please?

@Koc
Copy link
Contributor

Koc commented Aug 4, 2017

Nice PR, can anybody review?

@makasim
Copy link
Collaborator

makasim commented Aug 7, 2017

LGTM

@robfrawley
Copy link
Collaborator

This looks fine to me as well. I've been focused on getting 1.9 released before I worried about any 2.x PRs.

@rpkamp
Copy link
Contributor Author

rpkamp commented Nov 27, 2017

This PR has been open for a long time (since May of this year).
Anything I can do to advance the merging of this PR?

@makasim makasim merged commit b272ae3 into liip:2.0 Nov 27, 2017
@lsmith77 lsmith77 removed the State: Reviewing This item is being reviewed to determine if it should be accepted. label Nov 27, 2017
@makasim
Copy link
Collaborator

makasim commented Nov 27, 2017

@rpkamp Thank you for the contribution.

@rpkamp rpkamp deleted the image-service branch November 28, 2017 08:53
@robfrawley robfrawley changed the title Introduce FilterService as abstraction for creating images [Dependency Injection] [Filter] Implement filter service abstraction for creating images Mar 12, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Attn: BC Break This issue or PR results in a backwards-compatibility break and therefore requires a major release. Level: Enhancement ✨ This item involves an enhancement to existing functionality.
Projects
2.x Sprint 001
Awaiting triage
Development

Successfully merging this pull request may close these issues.

None yet

7 participants