web-dev-qa-db-fra.com

Définissez les métadonnées de média (format "dimensions") sur un fichier SVG après l'avoir extra avec un filtre

Ma question concerne la manière de joindre les dimensions de taille que j'ai extraites avec succès d'un fichier SVG et de les forcer dans le champ WP 'dimensions' associé au fichier, afin que les dimensions apparaissent dans la médiathèque.

Remarque: ceci est not identique à cette question précédente que j'ai postée . Dans cette question, j'ai demandé comment extraire la valeur de la dimension. Cependant, personne n'a compris comment le définir. valeur permanente au SVG pour qu’il apparaisse dans la médiathèque.

Où j'extrais les dimensions

J'extrais les dimensions de l'image de SVG à l'aide d'un filtre. Ce filtre me permet d'afficher les fichiers SVG, non seulement sous forme de logos, mais également sous forme d'images. Le filtre que j'utilise identifie la taille du fichier SVG depuis l'intérieur du fichier SVG, puis réinitialise les valeurs des valeurs image[1] et $image[2] dans le tableau renvoyé par wp_get_attachment_image_src(). Cette fonction est la suivante:

File: wp-includes/media.php
804: /**
805:  * Retrieve an image to represent an attachment.
806:  *
807:  * A mime icon for files, thumbnail or intermediate size for images.
808:  *
809:  * The returned array contains four values: the URL of the attachment image src,
810:  * the width of the image file, the height of the image file, and a boolean
811:  * representing whether the returned array describes an intermediate (generated)
812:  * image size or the original, full-sized upload.
813:  *
814:  * @since 2.5.0
815:  *
816:  * @param int          $attachment_id Image attachment ID.
817:  * @param string|array $size          Optional. Image size. Accepts any valid image size, or an array of width
818:  *                                    and height values in pixels (in that order). Default 'thumbnail'.
819:  * @param bool         $icon          Optional. Whether the image should be treated as an icon. Default false.
820:  * @return false|array Returns an array (url, width, height, is_intermediate), or false, if no image is available.
821:  */
822: function wp_get_attachment_image_src( $attachment_id, $size = 'thumbnail', $icon = false ) {
823:    // get a thumbnail or intermediate image if there is one
824:    $image = image_downsize( $attachment_id, $size );
825:    if ( ! $image ) {
826:        $src = false;
827: 
828:        if ( $icon && $src = wp_mime_type_icon( $attachment_id ) ) {
829:            /** This filter is documented in wp-includes/post.php */
830:            $icon_dir = apply_filters( 'icon_dir', ABSPATH . WPINC . '/images/media' );
831: 
832:            $src_file = $icon_dir . '/' . wp_basename( $src );
833:            @list( $width, $height ) = getimagesize( $src_file );
834:        }
835: 
836:        if ( $src && $width && $height ) {
837:            $image = array( $src, $width, $height );
838:        }
839:    }

C’est le filtre que j’applique à cette fonction, qui modifie les valeurs de $image[1] et $image[2] (c’est-à-dire la largeur et la hauteur de l’image, respectivement).

 add_filter( 'wp_get_attachment_image_src', 'fix_wp_get_attachment_image_svg', 10, 4 );  /* the hook */

 function fix_wp_get_attachment_image_svg($image, $attachment_id, $size, $icon) {
    if (is_array($image) && preg_match('/\.svg$/i', $image[0]) && $image[1] <= 1) {
        if(is_array($size)) {
            $image[1] = $size[0];
            $image[2] = $size[1];
        } elseif(($xml = simplexml_load_file($image[0])) !== false) {
            $attr = $xml->attributes();
            $viewbox = explode(' ', $attr->viewBox);
            $image[1] = isset($attr->width) && preg_match('/\d+/', $attr->width, $value) ? (int) $value[0] : (count($viewbox) == 4 ? (int) $viewbox[2] : null);
            $image[2] = isset($attr->height) && preg_match('/\d+/', $attr->height, $value) ? (int) $value[0] : (count($viewbox) == 4 ? (int) $viewbox[3] : null);
        } else {
            $image[1] = $image[2] = null;
        }
    }
    return $image;
} 

Le filtre fonctionne, mais la médiathèque ne montre pas les données extraites

Le filtre fonctionne, et d'après ce que je peux dire, ces informations dans $image[1] et $image[2] sont attribuées à la largeur et à la hauteur html de l'élément du fichier SVG placé. Mais, comme vous pouvez le voir dans l'image ci-dessous, le filtre ne semble pas mettre à jour le champ dimensions de l'image dans la base de données WP.

 library view of SVG vs PNG 

Ma question a résumé:

Comment puis-je prendre ces valeurs de dimension, que mon filtre récupère, et les attacher au fichier image dans la base de données elle-même d'une manière qui me permet d'afficher les dimensions dans la médiathèque?

Merci!!

2
CoderScissorhands

Le filtre wp_update_attachment_metadata se déclenche chaque fois que vous téléchargez une image dans une bibliothèque multimédia (plus précisément à chaque appel de la fonction wp_update_attachment_metadata).

Ainsi, lorsqu'un fichier svg est chargé, nous vérifions s'il contient les métadonnées souhaitées, à savoir la largeur et la hauteur. Sinon, nous générons les métadonnées comme vous l'avez fait dans votre filtre wp_get_attachment_image_src. Maintenant que les métadonnées sont enregistrées, nous pouvons appeler des fonctions telles que wp_get_attachment_image_src et obtenir les métadonnées sans avoir à filtrer ces fonctions.

Soyez conscient du problème de uploading svg files dans la dernière version de Wordpress (4.7.2). Il est supposé être corrigé dans 4.7.3

Enfin, je voudrais vous avertir des risques potentiels pour la sécurité (attaques XSS) que les fichiers svg exposent. Plus ici et ici .

function svg_meta_data($data, $id){

    $attachment = get_post($id); // Filter makes sure that the post is an attachment
    $mime_type = $attachment->post_mime_type; // The attachment mime_type

    //If the attachment is an svg

    if($mime_type == 'image/svg+xml'){

        //If the svg metadata are empty or the width is empty or the height is empty
        //then get the attributes from xml.

        if(empty($data) || empty($data['width']) || empty($data['height'])){

            $xml = simplexml_load_file(wp_get_attachment_url($id));
            $attr = $xml->attributes();
            $viewbox = explode(' ', $attr->viewBox);
            $data['width'] = isset($attr->width) && preg_match('/\d+/', $attr->width, $value) ? (int) $value[0] : (count($viewbox) == 4 ? (int) $viewbox[2] : null);
            $data['height'] = isset($attr->height) && preg_match('/\d+/', $attr->height, $value) ? (int) $value[0] : (count($viewbox) == 4 ? (int) $viewbox[3] : null);
        }

    }

    return $data;

}

add_filter('wp_update_attachment_metadata', 'svg_meta_data', 10, 2);
4
Laxmana