1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
|
<?php
// traitement avant enregistrement dans le fichier submit.php
// cette fonction extrait les liens pointant vers des medias embarqués
// (liste de sites) et les restituent nus, sans les balises
function mediaSubmit($chaine)
{
// liste de sites concernés par les fonctions de ce fichiers
$listeMedia = "youtube.com|vimeo.com|dailymotion.com|spotify.com|soundcloud.com|instagram.com|twitter.com|flickr.com|facebook.com|fb.watch|deezer.com|openstreetmap.org|goo.gl/maps|google.com/maps|itunes.apple.com|wordpress.com";
// sites gérés manuellement (l'éditeur semble ne pas les connaître)
$regexListeNonGeree = 'https://open.spotify.com/embed/\w+/\w+';
// à faire plus tard
//https://www.openstreetmap.org.*layer=mapnik
//global $listeMedia; // avec global, au lieu de créer une variable locale, on crée une référence vers celle à l'extérieur
//global $regexListeNonGeree;
//echo($chaine . "\n");
// pour embarquer spotify, l'url doit ressembler à https://open.spotify.com/embed/...
// on ajoute "/embed" si necessaire
$chaine = preg_replace('#spotify.com(?!/embed)#', '$0/embed', $chaine);
// adaptation pour les sites non gérés par l'éditeur
// on gère deux cas: celui ou l'éditeur ne fait rien (lien nu) et celui où l'utilisateur a créé un lien <a>
// on vire les balises <a> et ce qu'il y a entre les deux pour ne garder que les liens
// on pourra ensuite traiter ensemble les url avec et sans balises <a>
// (?:) permet de matcher sans capturer, donc de retirer des choses
// pour la variable $tolere, on met:
// \w = [a-zA-Z0-9_], espace ' ', tabulation \t, CR et LF \r\n,
// /, @, %, deux-points ';', virgule ',' et point-virgule ;
// et devant être échappés: . # ( ) ] { } ? ! | et le tiret qui est placé au début ou la fin
$tolere = '\w\s\t\n\r/,;:éèàçù€\#@%\.\(\)[\]\{\}\?\!\|-';
$pattern = '#(?:<a href=")([' . $tolere . ']{1,})?(' . $regexListeNonGeree . ')([' . $tolere . ']{1,})?(?:">[' . $tolere . ']+</a>)#';
$chaine = preg_replace($pattern, '$2', $chaine);
//echo($chaine . "\n");
// on met les balises <span>
$pattern = '#' . $regexListeNonGeree . '#';
$remplacement = '<span class="media_embed">$0</span>';
$chaine = preg_replace($pattern, $remplacement, $chaine);
// c'est quoi cette merde?
// l'API DOM de PHP bien sur!! pour manipuler le "document object model"
// c'est du complètement calqué sur le javascript, avec une syntaxe PHP
// et en plus elle est super vieille, elle ne connaît pas les balises HTML5 !
// mais une balise c'est une balise donc ça marche quand même
// https://www.php.net/manual/fr/book.dom.php
$dom = new DOMDocument;
// pour ne pas s'arrêter sur les erreurs à cause des "nouvelles" balises
libxml_use_internal_errors(true);
if($dom->loadHTML($chaine)) // et non load() tout court qui sert à charger du XML
{
// <figure>
// détecter <figure class="media"><oembed url="http://...">
// puis extraire le lien et supprimer les balises autour
if(preg_match("#<figure class=\"media\"><oembed url=\".+\"></oembed></figure>#", $chaine))
{
$nbFigures = $dom->getElementsByTagName('figure')->length;
$j = 0;
for($i = 0; $i < $nbFigures ; $i++) // boucle foreach impossible, une <figure> disparaît à chaque tour
{
$balisesFigure = $dom->getElementsByTagName('figure');
$figure = $balisesFigure->item($j); // l'item 1 devient 0 au deuxième passage, etc
$parent = $figure->parentNode;
if($figure->getAttribute("class") == 'media')
{
$oembed = $figure->getElementsByTagName('oembed'); // tableau d'une seule case
$div = $figure->getElementsByTagName('div'); // tableau d'une seule case
if($oembed->length > 0) // si taille = 0, c'est que la balise figure contient autre chose qu'une oembed
{
$lien = $oembed->item(0)->getAttribute('url') . ' '; // un espace pour ne pas coller deux adresses
$span = $dom->createElement('span', $lien);
$class = $dom->createAttribute('class');
$class->value = 'media_embed';
$span->appendChild($class);
$parent->replaceChild($span, $figure);
}
elseif($div->length > 0) // cette div créée par le ckeditor contient notre lien, plus bas se trouve une iframe
{
$lien = $div->item(0)->getAttribute('data-oembed-url') . ' ';
$span = $dom->createElement('span', $lien);
$class = $dom->createAttribute('class');
$class->value = 'media_embed';
$span->appendChild($class);
$parent->replaceChild($span, $figure);
}
else
{
$j++; // la balise <figure> n'est pas supprimée, on incrémente l'indice du tableau pour ne pas boucler à l'infini
}
}
}
}
// <iframe>
// détecter <iframe src="http://..." et remplacer par le lien nu, comme au dessus
// site sans oembed?
if(preg_match("#<iframe src=\".+\"></iframe>#", $chaine))
{
$nbIframes = $dom->getElementsByTagName('iframe')->length;
for($i = 0; $i < $nbIframes ; $i++)
{
$balisesIframe = $dom->getElementsByTagName('iframe');
$iframe = $balisesIframe->item(0);
$parent = $iframe->parentNode;
$lien = $iframe->getAttribute('src') . ' ';
$span = $dom->createElement('span', $lien);
$class = $dom->createAttribute('class');
$class->value = 'media_embed';
$span->appendChild($class);
$parent->replaceChild($span, $$iframe);
}
}
// <a>
// pour tout les sites multimedia, remplacer les balises <a> par les liens nus
// en effet, en revenant dans l'éditeur les liens ne déclenchent pas automatiquement "l'embarquement"
// cliquer à la fin d'un lien et passer à la ligne a pour effet de créer des balises <a>
// ça pose un problème parce que la bibliothèque "embera" ne gère pas les liens dans des balises
if(preg_match("#<a href=\".+\">.*</a>#", $chaine))
{
$nbA = $dom->getElementsByTagName('a')->length;
$j = 0;
for($i = 0; $i < $nbA ; $i++)
{
$balisesA = $dom->getElementsByTagName('a');
$a = $balisesA->item($j);
$parent = $a->parentNode;
$lien = $a->getAttribute('href') . ' ';
// seules les liens pointant vers une des adresses de la liste sont concernés
if(preg_match("#" . $listeMedia . "#", $lien))
{
$span = $dom->createElement('span', $lien);
$class = $dom->createAttribute('class');
$class->value = 'media_embed';
$span->appendChild($class);
$parent->replaceChild($span, $a);
}
else
{
$j++; // la balise <a> n'est pas supprimée, on incrémente l'indice du tableau pour ne pas boucler à l'infini
}
}
}
// pour nettoyer tous les warnings qu'on vient de produire et purifier nos fichiers log
libxml_clear_errors();
// pour au contraire pouvoir les regarder, remplacer la ligne au dessus par celles en dessous
//~ $errors = libxml_get_errors();
//~ var_dump($errors);
// mettre à jour le DOM et enlever le DOCTYPE et les balises <html> et <body>
$chaine = $dom->saveHTML($dom);
$pattern = array ('#<!DOCTYPE.*>#', '#<html><body>#', '#</html></body>#');
$remplacement = array ('', '', '');
$chaine = preg_replace($pattern, $remplacement, $chaine);
}
else
{
echo "Impossible de charger le HTML";
}
// détecter soundcloud
// normallement il n'y a rien à faire ici mais on sait jamais (une mise à jour du ckeditor?)
if(preg_match("#soundcloud.com#", $chaine))
{}
// détecter facebook (éventuellement fb.watch)
// je crois que ça va être compliqué ici
if(preg_match("#facebook.com|fb.watch#", $chaine))
{}
return($chaine); // = $contenu
}
// embarquement !!
function mediaEmbed($chaine)
{
//require("../Embera/src/Autoloader.php");
//$embera = new Embera\Embera();
//$chaine = $embera->autoEmbed($chaine);
$pattern = '#<span class="media_embed">(.+)</span>#';
$remplacement = '<iframe src="$1" frameborder="0" allowtransparency="true"></iframe>';
$chaine = preg_replace($pattern, $remplacement, $chaine);
// requête oembed
//~ echo('<br/><br/>');
//~ print_r($embera->getUrlData([
//~ 'https://vimeo.com/374131624',
//~ 'https://www.flickr.com/photos/bees/8597283706/in/photostream',
//~ ]));
return($chaine); // = $contenu
}
|