web-dev-qa-db-ja.com

フィルタで抽出した後にSVGファイルにメディアメタデータ(すなわち、「ディメンション」フィールド)を設定します

私の質問は、SVGから正常に抽出されたサイズの寸法をどのようにしてファイルに関連付けられたWP 'dimensions'フィールドにアタッチし、メディアライブラリに表示されるかについてです。

注:これはではありません私が投稿したこの以前の質問 と同じです。その質問で、私はディメンション値を抽出する方法を尋ねました。しかし、メディアライブラリに表示されるように、その値を永続的にSVGに設定する方法は誰にもわかりませんでした。

寸法を抽出する場所

フィルタを使用してSVGから画像の寸法を抽出します。このフィルタを使うと、SVGをロゴとしてではなく、注目の画像として表示することができます。私が使用するフィルタは、SVGファイルの中からSVGのサイズを識別して、wp_get_attachment_image_src()によって返される配列のimage[1]$image[2]の値をリセットします。

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:    }

これは私がその関数に適用するフィルタで、これは$image[1]$image[2]の値(すなわちそれぞれ画像の幅と高さ)を変更します。

 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;
} 

フィルタは機能しますが、メディアライブラリは抽出されたデータを表示しません

フィルタが機能し、私が$image[1]$image[2]でこの情報を伝えることができることから配置されたSVGの要素のhtml幅と高さに割り当てられています。しかし、下の画像でわかるように、フィルタはWPデータベース内の画像のdimensionsフィールドを更新しているようには見えません。

library view of SVG vs PNG

私の質問は要約しました:

フィルタが取得したこれらの寸法値をどのように取得して、メディアライブラリ内の寸法を表示できるようにデータベース自体の画像ファイルに添付するにはどうすればよいですか。

ありがとうございます。

2

wp_update_attachment_metadataフィルタは、メディアライブラリを介して画像をアップロードするたびに(特にwp_update_attachment_metadata関数が呼び出されるたびに)起動されます。

そのため、svgファイルがアップロードされると、ファイルに目的のメタデータ、幅と高さがあるかどうかを確認します。そうでない場合は、wp_get_attachment_image_srcフィルタで行ったようにメタデータを生成します。メタデータが保存されたので、wp_get_attachment_image_srcのような関数を呼び出して、それらの関数をフィルタリングする必要なしにメタダを取得することができます。

最新のWordpressバージョン(4.7.2)で svgファイルをアップロードする の問題に注意してください。 4.7.3で修正されるはずです

最後に、svgファイルが公開する潜在的なセキュリティリスク(XSS攻撃)について警告します。もっと here そして here

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