- Issue created by @flyke
- 🇫🇷France DrDam
It seems the bug is caused by the end of the image name " (1)" which are encoded to "%20%281%29".
- 🇧🇪Belgium flyke
Yes, If I upload a new image to the Media library with a simple filename like 'Naamloos.png' and use that, still the same problem.
Broken image src =https://mywebsite.com/sites/default/files/contextual/styles/crop_hero/public/uploads/Naamloos.png?itok=zbqO4E0b
manually opening that in browser redirects to:https://mywebsite.com/nl/sites/default/files/contextual/styles/crop_hero/public/uploads?itok=zbqO4E0b
but thats a 404 page not found. No image is generated. There is a sites/default/files/contextual folder now (from the previous test where I forced the parameters insite the Controller) but its empty. - 🇫🇷France DrDam
Can you confirm me Images URL ? (as they are written in sources)
because :
https://mywebsite.com/sites/default/files/contextual/styles/crop_hero/pu...
are broken due the fact there is no "contextual id" in URL.
A good URL would be :
https://mywebsite.com/sites/default/files/contextual/styles/crop_hero/[I...
=> if it's the case, the bug are in the formater
In the first message, the error may are in the PathProcessor ...
so i'm confused...
- 🇧🇪Belgium flyke
I can confirm that the Image URLs I pasted here are real and unmodified exept for the 'mywebsite.com' part.
If you check to proposed resolution part of the issue, you will see that I already noticed that 'file' and 'contextual_crop' query parameters are missing inside the process() function, and that if I manually set something there for those parameters, then everything works.
So the problem is that the 'file' and 'contextual_crop' parameters are missing inside the process() function. They are available inside the processInbound() function, but they are missing from the process() function of the Controller. - 🇫🇷France DrDam
Ok, I does not understand why the parameters in the request not passe to the controller...
Can you make a dsm on other parameters of the controller ?
- 🇫🇷France DrDam
That seem logic.
So, in the PathProcessorImageStyles, can you put some dsm :
// Get the image style, scheme and path. if (substr_count($rest, '/') >= 4) { => dsm($rest); [$style_separator, $image_style, $context, $scheme, $file] = explode('/', $rest, 5); => dsm([$style_separator, $image_style, $context, $scheme, $file]); // Set the file & context as query parameter. $request->query->set('file', $file); $request->query->set('contextual_crop', $context); => dsm($path_prefix . $style_separator . '/' . $image_style . '/' . $context . '/' . $scheme); return $path_prefix . $style_separator . '/' . $image_style . '/' . $context . '/' . $scheme; }
- 🇧🇪Belgium flyke
I refreshed the page, and then you see the expected number of output / dpms. That is probably less confusing.
- 🇫🇷France DrDam
There is the problem, the "rest" url will be "styles/[style_name]/[context_id]/[scheme]/[file path] and in your case, the context_id are absent.
can you add another dsm at the line 33
else { return $path; } => dsm($path) // Strip out path prefix. $rest = preg_replace('|^' . preg_quote($path_prefix, '|') . '|', '', $path);
- 🇫🇷France DrDam
can you confirme that is the URL in the HTML source ?
If it's the case, the error are in the URL generation - 🇧🇪Belgium flyke
Yes, looks the same to me. Where might the URL generation be wrong ? any way to trouble shoot that further ?
- 🇧🇪Belgium flyke
It seems that inside generateContextualizedImage() function, $plugin->saveCrop returns NULL.
- 🇫🇷France DrDam
So, can you add dsm in
Drupal\media_contextual_crop_iwc_adapter\Plugin\MediaContextualCrop/ImageWidgetCrop::save_crop
foreach ($style_dependencies as $dep) { if (strstr($dep[0], 'crop.type')) { $croptype = str_replace('crop.type.', '', $dep[0]); } } => dsm($croptype); => dsm($crop_settings['crop_wrapper']); // Filter to the concerned crop setting. foreach ($crop_settings['crop_wrapper'] as $crop_type => $container) { // Get Crop value. if ($croptype != $crop_type) { continue; }
- 🇧🇪Belgium flyke
I will in a moment. I am now debugging
media_contextual_crop_iwc_adapter/src/Plugin/MediaContextualCrop/ImageWidgetCrop.php
.
I can see there that $croptype gets the value 'hero' (which is indeed the applied crop style).
But inside $crop_settings['crop_wrapper'], there is only the '16_9' crop type, which is the first of the available crop types, but not the correct one.
So this part of the code:if ($croptype != $crop_type) { continue; }
never yields a result, because 'hero' is never equal to '16_9'.
That causes the code to never retrieve or create a crop, and thus returning NULL instead of a crop ID. - 🇧🇪Belgium flyke
added screenshot with arrow in image 1 for the part that we want to reach but never reach.
- 🇫🇷France DrDam
In fact, the
$crop_settings['crop_wrapper']
contain only the 16_9 and no hero here. (see #21)ok, so go to the media_contextual_crop.mode in the "template_preprocess_image_contextual_formatter" function, Line 241
function template_preprocess_image_contextual_formatter(&$variables) { \Drupal::moduleHandler()->loadInclude('image', 'field.inc'); template_preprocess_image_formatter($variables); => dsm($variables['item']) // Find the competent plugin to process this image. $use_case_plugin_manager = \Drupal::service('plugin.manager.media_contextual_crop_use_case'); /** @var \Drupal\media_contextual_crop\MediaContextualCropUseCasePluginBase $use_case_plugin */ $use_case_plugin = $use_case_plugin_manager->findCompetent($variables['item']);
Sorry for the "debuging method"
- 🇧🇪Belgium flyke
No problem at all, I am actually glad I can be of assistance and that you are willing to help troubleshoot this.
- 🇫🇷France DrDam
Ok, and in the
dsm($variables['item']['values']['image_crop']['crop_wrapper'])
- 🇧🇪Belgium flyke
And here is the more detailed output from
dpm($variables['item']->image_crop);
- 🇫🇷France DrDam
And if you modifiy this crop, and resave the content ? the missing value are added ? (I imagine not ... )
- 🇫🇷France DrDam
The bug can came from
Drupal\media_contextual_crop_iwc_adapter\Plugin\MediaContextualCrop\ImageWidgetCrop::processFieldData
Can you add a
dsm
Line 114 & 158public static function processFieldData($field_data) { => dsm($field_data) // Filter to the concerned crop setting. foreach ($field_data['crop_wrapper'] as $crop_type => $container) { // Get Crop value. $crop_values = $container['crop_container']['values']; if ($crop_values['crop_applied'] == 0) { unset($field_data['crop_wrapper'][$crop_type]); } } if (count($field_data['crop_wrapper']) == 0) { return NULL; } else { =>dsm($field_data) return $field_data; } }
- 🇧🇪Belgium flyke
I offer you my apologies, It seems that I have in all that testing switched from applying a hero crop to actually applying a 16_9 crop.
So the crop_applied = 1 is correct for the 16_9 crop at the moment. - 🇫🇷France DrDam
Can you test, to be sure the crop is applied. I don't know how IWC really work...
And, if it's the case, an image must be processed ... even if no crop are provided...
- 🇧🇪Belgium flyke
I can edit the image, set a crop, save the page.
The image is not shown as we already saw in numerous previous screenshots.
I can then edit the page and the image again, and I can see while editing that the crop is in exactly the same place as when I previously saved it. So on the Edit side, eveything works ?But on the page itself, the image is not working because in media_contextual_crop_iwc_adapter/src/Plugin/MediaContextualCrop/ImageWidgetCrop.php in saveCrop it compare $croptype ('hero') to $crop_type (16_9);
Maybe because of some old crop data or something ? Can I clear all existing crops somehow to test this ? - 🇫🇷France DrDam
now, in Drupal\media_contextual_crop_iwc_adapter\Plugin\MediaContextualCrop\ImageWidgetCrop::processFieldData
public static function processFieldData($field_data) {
// Filter to the concerned crop setting.
foreach ($field_data['crop_wrapper'] as $crop_type => $container) {
// Get Crop value.
$crop_values = $container['crop_container']['values'];
=>dsm($crop_values)
if ($crop_values['crop_applied'] == 0) {
unset($field_data['crop_wrapper'][$crop_type]);
}
}if (count($field_data['crop_wrapper']) == 0) {
return NULL;
}
else {return $field_data;
}}
the "crop_values['crop_applied']" for the "hero" crop still have 0 as value ?
- 🇧🇪Belgium flyke
I found the reason why it did not work, where the 'hero' comes from and so also how to fix it.
I am sorry for your time. The frustrating thing about current implementation of cropping is that while you can select multiple possible cropping types on the Form Display, you are still required to set a single crop image style in the Manage display settings of the 'Contextual Crop Image' widget.
And apparently the crop I was trying to apply did not match the crop image style of the Manage display settings of the 'Contextual Crop Image' widget.
So everything works now, cropped image is generated and visible. A thousand times thank you for your time.I have a way around this problem in other projects, I just removed it because it did no longer apply for Drupal 10. But I will try to refactor it for D10.
- Create a new 'Automatic crop' image style. It is empty without any operations.
- use preprocessing for this image style, get the crop type and hardwire a corresponding crop image style for each crop type
- apply that image style. this means that applying 'automatic_crop' image style for a 16_9 crop will actually apply the '16_9_crop' image style, while applying 'automatic_crop' image style for a 'hero' crop will actually apply the 'hero_crop' image style. - 🇫🇷France DrDam
No worry, there is this kinde of "issues" that show there really have something broken.
The frustrating thing about current implementation of cropping is that while you can select multiple possible cropping types on the Form Display, you are still required to set a single crop image style in the Manage display settings of the 'Contextual Crop Image' widget.
I don't understand the use_case here ...
In the media, you have a view_mode, and for the field_image you want have multiple style to be applied on the image ? Did you tried to use a Responsive_Image_Style instead of an "image_style" ?
- Status changed to Closed: works as designed
11 months ago 1:11pm 24 January 2024 - 🇧🇪Belgium flyke
Hi DrDam: Please look at the screenshot about what the use case is:
- User can apply a 16:9 crop
- OR user can apply a 16:9 small image crop
- OR user can apply a 80:39 crop
- OR user can aaply a Hero crop
- OR user can apply a square crop
BUT
only when het applies the 16:9 crop it will work, because that is the image style that is selected for the Contextual Crop Image in Manage Display. It is that fact that you have to choose an image style there that screws up the possibility of giving the user the choice of what crop type he applies to the image. - 🇫🇷France DrDam
It is that fact that you have to choose an image style there that screws up the possibility of giving the user the choice of what crop type he applies to the image.
If I understood correctly, you use CROP to impose some "image formats" (and the user is free to select the area), but the user "in addition" has the ability to choose which format he wants. want for its image (from the node form)?
Something like this module → but applied to media with crop ?
- 🇧🇪Belgium flyke
Hi, what I mean is: make the screenshot 'multiple possible crops.png' work, so user can choose any of the crops on the left side of that screenshot. But thats not possible because of screenshot 'manage display - set contextual crop image style.png' because we are forced to set a crop image style there. In this example, the 'Crop 16:9' image style is selected.
Only if the user chooses to use the 16:9 crop it will work because of that image style.
But if the user chooses to use any other crop (see the left side with possible crop options available to him), the image will be broken because it does not match that 'Crop 16:9' image style.Therefor, I would like that that the manage display - Contextual Crop Image - Image style option is removed completely. So we dont need to set it. Instead the code from the Contextual Crop Image widget could figer out which image style to apply based on the selected crop type.
- 🇫🇷France DrDam
OK,
The scenario you want for the use case :
Step 1 : Insert Media in content
Step 2 : crop the media "what ever you want"
Step 3 : the image are display "as she is croped"In fact, you don't even care about the type of crop : "display image as the user crop her"
- 🇧🇪Belgium flyke
Yes, I think thats what I mean :-). So If the user crops a Media with a 1:1 crop or a 16:9 crop or a 4:4 crop, It will work and the crop will be generated and displayed without me having to bother to set an image style in the Manage Display.
Of course, If I have a 1:1 crop type, a 1:1 crop image style needs to exist. And if I have a 16:9 crop type, a 16:9 image style needs to exist. But I should not have to explicitly set a crop image style in Manage Display. It should automatically shoose the correct one. - 🇧🇪Belgium flyke
Sorry to bother again, Its not working on a fresh try :-(
I tried to crop from a clean start, So I deleted all existing crops:
drush php-eval '$crops = \Drupal::entityTypeManager()->getStorage("crop")->loadMultiple(); foreach ($crops as $crop) { $crop->delete(); }'
I went to sites/default/files and deleted all cropped and crop duplicate images I could find.
I deleted the existing image blocks. I added 2 image blocks next to each other, both showing the same Media image, no cropping applied.
See 01 - before cropping.pngI then edited image 1 and added cropping to that image, see:
02 - cropping only 1 image.pngThe cropped image is broken unfortunatly, see image:
03 - broken image after cropping.pngBut, the image src now does contain a contextual id I think (289): https://mywebsite.com/sites/default/files/contextual/styles/crop_16_9/28...
Also, it passes the
if ($croptype != $crop_type) {
statement (because '16_9' == '16_9') which is also good.
A Crop entity is created and the function does return a valid crop ID.I can DPM the Crop entity, see 04 - crop entity.png
So I think more is working than at the beginning of this issue, but somehow still no working image on this fresh try.
- Status changed to Active
11 months ago 3:13pm 24 January 2024 - 🇫🇷France DrDam
Did you have any error in drupal watchdog ?
The URL in 03 are correct, so can you make a dsm for parameters of
MediaContextualCropService::createContextualizedDerivativePath
- 🇧🇪Belgium flyke
I will look further into this tomorrow if I find the time, new urgent stuff for other clients have came up.
But in the meantime I created a fix for the process function for when the necessary request query parameters are missing:
public function process(Request $request, $context, ImageStyleInterface $image_style, $scheme) { // Set 'contextual_crop' parameter if its missing. if (is_null($request->query->get('contextual_crop')) && is_numeric($context)) { $request->query->set('contextual_crop', $context); } // Set 'file' parameter if its missing. if (is_null($request->query->get('file')) && is_numeric($context)) { // Load Crop entity. $crop = \Drupal::service('entity_type.manager')->getStorage('crop')->load($context); // Get value for the file parameter. $crop_uri = $crop->uri->value; $crop_uri = str_replace($scheme . '://', '', $crop_uri); $request->query->set('file', $crop_uri); } $target = $request->query->get('file'); ...
- 🇧🇪Belgium flyke
It might not be pretty code but it's working for now with this code so I can focus on other urgent assignments.
I do hope to find the actual cause and I do hope I find the time to checkMediaContextualCropService::createContextualizedDerivativePath
for you.
Will report back if I do. - 🇫🇷France DrDam
In fact, you are right, if I have the context, the file are not mandatory...
- Status changed to Closed: works as designed
11 months ago 10:27am 26 January 2024