Wordpress - Can't extract and set SVG dimensions

I solved it!!! The filter in fix #3 (above) wasn't working because of the third condition of this if statement that triggers the dimension extraction and attachment:

if (is_array($image) && preg_match('/\.svg$/i', $image[0]) && $image[1] == 1)

$image[1] in the third condition is the reported width of the SVG file as WP sees it before it enters the filter. Since I know that its value, the width, is 0 (from the "zero-division error" described above) I suspected that this value needed to be changed to match it. I changed the final 1 on that if condition to a 0 and..voila! The division error went away and the image is displaying, and beautifully so I might ad!

I was able to spot this because in many forums people complain that SVGs are incorrectly getting assigned widths of 1px. This was probably the case in some versions of WP, but in my WP 4.7.2 media library, no dimension for the SVG, not even 1px is posted, as a dimension. Instead there was simply no metadata regarding dimensions in my case.

I think a flexible version of the filter would allow it to be applied if the width is 1 or 0, for people who had the 1px problem and for people like me, who had a width of 0. Below I included the fix, using $image[1] <= 1as the third condition of the if statement instead of $image[1] == 1 but I suppose you could use this, too: ( ($image[1] == 0) || ($image[1] == 1) )

The working filter

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

Thank you everyone for your help it was really a team effort!


It is hard to guess exactly what may be the problem for the WordPress enthusiast like me but since you pinged me in the Loop...

Just to mention you haven't shared the theme files...

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

This part with:

@list( $width, $height ) = getimagesize( $src_file );

Looks like the problem since SVG images don't have the size info. They just fit the container.

So you may create your own version of wp_get_attachment_image_src where you can somehow set the size.