Site icon Code Solution

Convert code – not work

The question:

There is a code.

add_filter( 'the_content', 'adding_image_dimensions' );

function adding_image_dimensions( $content ) {

    preg_match_all( '/<img[^>]+>/i', $content, $images);

    if (count($images) < 1)
        return $content;

foreach ($images[0] as $image) {
    preg_match_all( '/(alt|title|src|width|class|id|height)=("[^"]*")/i', $image, $img );

    if ( !in_array( 'src', $img[1] ) )
        continue;

    if ( !in_array( 'width', $img[1] ) || !in_array( 'height', $img[1] ) ) {
        $src = $img[2][ array_search('src', $img[1]) ];
        $alt = in_array( 'alt', $img[1] ) ? ' alt=' . $img[2][ array_search('alt', $img[1]) ] : '';
        $title = in_array( 'title', $img[1] ) ? ' title=' . $img[2][ array_search('title', $img[1]) ] : '';
        $class = in_array( 'class', $img[1] ) ? ' class=' . $img[2][ array_search('class', $img[1]) ] : '';
        $id = in_array( 'id', $img[1] ) ? ' id=' . $img[2][ array_search('id', $img[1]) ] : '';

        list( $width, $height, $type, $attr ) = getimagesize( str_replace( """, "" , $src ) );
        $html = '';

        if (($width != 0) || ($height != 0)) {
            $html = ' width="%d" height="%d" ';
        }

        $image_tag = sprintf( '<img loading="lazy" src=%s%s%s%s%s' . $html . '/>', $src, $alt, $title, $class, $id, $width, $height );
        $content = str_replace($image, $image_tag, $content);
    }
}

return $content;
}

I changed it a little. So that everything fits into the database at once, and not constantly generated on the fly.

add_action( 'wp_insert_post_data', 'adding_image_dimensions' );

function adding_image_dimensions( $content ) {

$content = $content['post_content'];

    preg_match_all( '/<img[^>]+>/i', $content, $images);

    if (count($images) < 1)
        return $content;

foreach ($images[0] as $image) {...

But the code doesn’t work for some reason 🙁

Im use WordPress 5.7.2, Classic Editor. And in my articles I have a lot of pictures so inscribed.

<a href="https://....jpg" target="_blank" rel="nofollow" title="test title"><img class="test class" alt="test alt" src="https://....jpg"></a>

Sorry for my English.

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

I changed it a little.

But the code doesn’t work for some reason 🙁

You should explain what exactly happened or did not happen that should have happened, rather than simply saying “doesn’t work”.

But anyway, if the first and fifth lines below were the only changes you applied in the code:

add_action( 'wp_insert_post_data', 'adding_image_dimensions' );

function adding_image_dimensions( $content ) {

$content = $content['post_content'];

Then that indeed would not give you the expected outcome (e.g. no <img> tag would be replaced because the second preg_match_all() call would fail), and here’s why:

  1. The function is now hooked on the wp_insert_post_data filter, so the function should return an array of post data, and yet in your code, the fifth line (i.e. $content = $content['post_content'];) actually changes the return value to a string.

  2. The $content['post_content'] value is slashed (e.g. src="..." becomes src="..."), so you should first unslash the value and then slash it back after the image tags are processed.

How can you fix the issues

To make the adding_image_dimensions() function works with the wp_insert_post_data filter instead, you can try the following:

// 1: Rename the $content to $data
function adding_image_dimensions( $data ) {
    // 2: Unslash the post content.
    $content = wp_unslash( $data['post_content'] );

    preg_match_all( '/<img[^>]+>/i', $content, $images);

    if (count($images) < 1) {
        // 3: Return the $data and not $content.
        return $data;
    }

    foreach ($images[0] as $image) {
        // ... your code here.
    }

    // 4: Slash back the post content.
    $data['post_content'] = wp_slash( $content );

    // 5: Return the $data and not $content.
    return $data;
}

Alternate Solution (without having to “convert” or modify the custom function)

  1. Remove the add_filter( 'the_content', 'adding_image_dimensions' );

  2. Call the original adding_image_dimensions() function in the wp_insert_post_data hook:

    // * use add_filter() and not add_action()
    add_filter( 'wp_insert_post_data', 'my_wp_insert_post_data' );
    
    function my_wp_insert_post_data( $data ) {
        $content = adding_image_dimensions( wp_unslash( $data['post_content'] ) ); // pass an *unslashed* content
        $data['post_content'] = wp_slash( $content ); // then slash back the content
        return $data;
    }
    


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Exit mobile version