phpBB (ou autre) : remplacer les url Vimeo par le lecteur
12 juillet 2008 par zero-zombie

Pour ce billet, je vais parler un peu plus du sujet de départ du blog : le code PHP avec un cas concret.
A l’heure du web vidéo, il est fréquent que les visiteurs postent des liens vers des vidéos. Comme pour des raisons de sécurité, il n’est pas possible de les laisser librement utiliser les codes <object>, une solution consiste à transformer automatiquement les URL des pages de services vidéo bien connus (YouTube, pour ne citer que lui) par le lecteur.Le cas suivant s’applique à phpBB, forum on ne peut plus répandu, qui a utilise de méthodes d’encodage/décodage des messages : les URL sont transformées en liens HTML avant que le message soit stocké en base de données, et le message est décodé et les liens HTML sont retraduits en simples URL en texte lorsqu’on souhaite éditer un message.
Les méthodes qui s’en chargent sont dans le fichier $phpbb_path/includes/functions_content.php ($phpbb_path est le chemin de votre installation de phpBB) et se nomment decode_message et make_clickable.
Il y a une petite subtilité : les vidéos Vimeo n’ont pas toutes les mêmes dimensions. Vimeo propose un service d’interrogation de leur base qui fournit des renseignements sur une vidéo, mais malheureusement ça n’est pas suffisant : on n’y trouve pas la hauteur et la largeur. Il faut donc trouver une autre solution : lire la page réelle de la vidéo et y récupérer ses dimensions.
Il faudra donc :
- Trouver les références aux vidéos
- Récupérer les dimensions
- Remplacer les URL par le code du lecteur
Trouver les références aux vidéos
On utilisera bien sûr les RegExp, ces formules vodoos pour le néophyte qui deviennent rapidement le couteau suisse indispensable du programmeur un fois les bases maîtrisées.
$magic_vimeo_match = ‘#(^|[\s])http:\/\/([w]*.|)vimeo.com\/([0-9]+)#i’;
On cherche une adresse qui débute une chaîne ^ ou | suit un ou plusieurs retours à la ligne, tabulations ou espaces [\s], puis on passe à l’url proprement dite : http:// (on doit protéger les slashes), éventuellement des www. ou rien ([w]*\.|), le nom de domaine et un slash vimeo.com/ et une suite de chiffres, qui est l’id de la vidéo [0-9]+ le tout sans tenir compte de la casse (option de recherche s).
On exécute la recherche dans la chaîne $text et on stocke le résultat dans $video_matches :
preg_match_all($magic_vimeo_match, $text, $vimeo_matches);
Récupérer les dimensions
$url = ‘http://www.vimeo.com/’ . $clip_id; // avec $clip_id = l’id trouvé avec preg_match_all
$contents = @file_get_contents($url); // si PHP est configuré pour pouvoir utiliser des URL comme des fichiers, sinon il faut utiliser cURL
Le lecteur est dans un div dont l’id est vimeo_player. On ne garde que le code de la page depuis cette position :
$contents = substr($contents, strpos($contents,' <p id="vimeo_player'));</pre> <p>puis on voit que les dimensions sont les premiers attributs width et height. On se fait une petite fonction pour récupérer les attributs html facilement :</p> <p>// fin zzzombie vimeo</pre> <p>et juste après la fonction make_clickable :</p> <pre lang=">// zzzombie function get_html_attribute_param($html, $attribute) { $match_numeric_attribute = '#(^|[\s])' . $attribute . '([\s]*|)="(.*?)"#is'; preg_match($match_numeric_attribute, $html, $attribute); return $attribute[3]; } // fin zzzombie
et hop ! on récupère :
$width = get_html_attribute_param($contents, 'width'); $height = get_html_attribute_param($contents, 'height');
Remplacer les URL par le code du lecteur
Bon… eh bien c’est fini, il suffit de procéder à la substitution, non sans oublier de mettre un marqueur pour simplifier le décodage ultérieur. Pour bien s’intégrer dans le process phpBB, on va faire ça en expression régulière, mais on pourrait faire ça plus rapidement avec des str_replace, puisqu’on sait exactement quelle chaine remplacer (c’est le premier élément d’un tableau de résultats, c’est pour ça que les ensembles matchés commencent à 1), et par quoi la remplacer.
Voilà le code final, prêt à l’emploi pour phpBB 3
Dans la fonction make_clickable, juste avant la ligne
// relative urls for this board
insérez
// zzzombie vimeo // factorisation de paramètres du lecteur. On pourrait aussi mettre l'autoplay, le fullscreen... $show_title = 1; $show_byline = 1; $color = "00FFFF"; $magic_vimeo_match = '#(^|[\s])http:\/\/([w]*.|)vimeo.com\/([0-9]+)#i'; preg_match_all($magic_vimeo_match, $text, $vimeo_matches); foreach ($vimeo_matches[3] as $clip_id) { $url = 'http://www.vimeo.com/' . $clip_id; $contents = @file_get_contents($url); $pos = strpos($contents,'<div id="vimeo_player'); if ($pos !== FALSE) { $contents = substr($contents, strpos($contents,'<div id="vimeo_player')); $width = get_html_attribute_param($contents, 'width'); $height = get_html_attribute_param($contents, 'height'); // la largeur max des vidéos est de 400px pour les lecteurs exportés // en pratique, ça passe pourtant très bien avec la largeur de vimeo.com, // alors la mise au format est désactivée (false && => jamais vérifié) if (false && $width>400) { $height = floor($height*400/$width); $width = 400; } $magic_url_match[] = '#(^|[\s])http:\/\/([w]*.|)vimeo.com\/' . $clip_id . '#i'; $magic_url_replace[] = "\$1" . '<!-- vimeo --><object height="' . $height . '" width="' . $width . '">' . '<param name="allowfullscreen" value="true"><param name="allowscriptaccess" value="always"><param name="autoplay" value="0">' . '<param name="movie" value="http://www.vimeo.com/moogaloop.swf?clip_id=' . $clip_id . '&server=www.vimeo.com&show_title=' . $show_title . '&show_byline=' . $show_byline . '&show_portrait=0&color=' . $color . '&fullscreen=1">' . '<embed src="http://www.vimeo.com/moogaloop.swf?clip_id=' . $clip_id . '&autoplay=0&server=www.vimeo.com&show_title=' . $show_title . '&show_byline=' . $show_byline . '&show_portrait=0&color=' . $color . '&fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" height="' . $height . '" width="' . $width . '">' . '</object><!-- vimeo -->'; $i++; } } // fin zzzombie vimeo
et juste après la fonction make_clickable :
// zzzombie function get_html_attribute_param($html, $attribute) { $match_numeric_attribute = '#(^|[\s])' . $attribute . '([\s]*|)="(.*?)"#is'; preg_match($match_numeric_attribute, $html, $attribute); return $attribute[3]; } // fin zzzombie
Pour décoder les messages, c’est encore une regexp, alors inutile de s’étendre et voici le code : dans la fonction decode_message, sous
$message = str_replace($match, $replace, $message);
insérez :
// zzzombie $match = array('#<!--\-\- vimeo \-\-->.*?clip_id=(.*?)\&.*?<!--\-\- vimeo \-\-->#'); $replace = array('http://www.vimeo.com/\1'); $message = preg_replace($match, $replace, $message); // fin zzzombie
Vous remarquerez que toutes les modifs sont encadrées de
// zzzombie
// fin zzzombie
C’est une bonne habitude à prendre quand vous modifiez des produits open source : en utilisant un commentaire spécial, vous pourrez localiser facilement vos modifications sans devoir faire des comparaisons avec les fichiers originaux.
Voilà, c’est tout pour cet épisode qui j’espère vous aura été utile.

