Problem/Motivation
Steps to reproduce:
Add this to a custom module:
function mymodule_media_source_info_alter(&$sources) {
$sources['audio_oembed'] = [
'id' => 'audio_oembed',
'label' => t('Remote audio'),
'description' => t('Use audio from remote sources.'),
'allowed_field_types' => ['string'],
'default_thumbnail_filename' => 'no-thumbnail.png',
'providers' => ['SoundCloud'],
'class' => 'Drupal\media\Plugin\media\Source\OEmbed',
];
}
Set up a media type using the source.
When you try to save a new media item pointing to soundcloud, you get the following error:
"The provided URL does not represent a valid oEmbed resource."
This is because soundcloud specifies type float for their oembed version, and Symfony's xml parser returns an array for floats.
Proposed resolution
Patch attached which makes it work, but not sure what the best solution is here.
Remaining tasks
User interface changes
API changes
Data model changes
| Comment | File | Size | Author |
|---|---|---|---|
| #21 | interdiff-2982372-20-21.txt | 451 bytes | phenaproxima |
| #21 | 2982372-21.patch | 2.83 KB | phenaproxima |
| #20 | interdiff-2982372-17-20.txt | 972 bytes | phenaproxima |
| #20 | 2982372-20.patch | 3.11 KB | phenaproxima |
| #17 | 2982372-17.patch | 3.13 KB | phenaproxima |
Comments
Comment #2
catchComment #3
plachLooks good and works well, but we need tests.
Comment #5
phenaproximaComment #6
phenaproximaIt turns out that our existing tests were already perfectly poised to catch this bug. Here ya go!
Comment #7
catch#6 looks good to me.
Comment #8
phenaproximaComment #10
b_sharpe commentedWorks great and tests fail pass as they should, RTBC!
Comment #11
larowlancan you point me to some docs about this?
Comment #12
phenaproximaUnfortunately not; the behavior is undocumented as far as I can tell. Here's the offending line from Symfony's XmlEncoder::decode():
The only condition this is hidden behind is that the text value of the node is returned directly if, and only if, there are no attributes. If there are attributes, this is what we get. Sucks that it's not documented, though!
Comment #13
alexpottWhat about if type or some other attribute is added to the title element in the XML? Do we need a more generic thing to normalise
$data?Comment #14
alexpottStep debugged through the Symfony code. The code that's responsible for this in our case is:
As far as I can see there is no way around this. And if we continue to use XMLEncoder we're going to be fragile if any oembed provider adds an attribute to any element.
I think what we should do here is to commit a workaround here but not do it as we've done here. It should be an ugly hack that does not add a protected method so there is no API change at all and we should open a follow-up to harden this code or use a different way to get XML into an array.
Comment #15
alexpottThe hack could look something like this:
in \Drupal\media\OEmbed\ResourceFetcher::fetchResource()
Alternatively if we want to fix this reliably here we could do something like
... well probably move that into a protected method in \Drupal\media\OEmbed\ResourceFetcher()
Comment #16
phenaproximaI like the second approach better. This also explains why an older iteration of the oEmbed system did exactly that -- convert XML to JSON and then back again. I didn't know why it did that previously (there was no comment about it) so I removed it. Now it's bitten us in the butt, so I'll restore it in a protected method. Patch forthcoming today.
Comment #17
phenaproximaHow's this look?
Comment #19
alexpottThis will fail.
This looks weird... either we do
json_encode()/json_decode()orJson::encode()/Json::decode()but mising them feels awkward. Let's go withJson::as that's what we're using for the json variant.Comment #20
phenaproximaUgh, sorry. Didn't have enough of a caffeine jolt this morning. All fixed.
Comment #21
phenaproximaHey look, I'm still a moron.
Comment #23
catchThis looks a lot happier.
Comment #24
alexpottCommitted and pushed 6ca0cd27aa to 8.7.x and faa28e8e08 to 8.6.x. Thanks!