Search code examples
ajaxwordpressparsingpreg-replacedomparser

Simple Dom Parser Returns Empty via Ajax


I'm using Simple HTML Dom Parser to correct some links in my output to good effect but have found some strange behaviour when calling content via Ajax. I'm using the parser on a WordPress site so feed the $content variable into the following function:

function add_trailing_slash( $content ) {

    $content = str_get_html( $content );
    if( $content ):
        foreach( $content->find('a') as $a ):

            if( isset( $a->href ) && '' !== $a->href && '#' !== $a->href ):

                // replace http with https on all link hrefs
                $a->href = str_replace('http:', 'https:', $a->href);

                // checks if link lacks trailing slash and appends it if no extension (file)
                $ext = pathinfo( $a->href, PATHINFO_EXTENSION );
                if( '/' !== substr( $a->href, -1 ) && ! $ext ) $a->href = $a->href . '/';

            endif;

        endforeach;
    endif;
    return $content;
}

This is working great when added to the_content filter with add_filter( 'the_content', 'add_trailing_slash' ) and even when called directly like return add_trailing_slash( $output ) however, when I call the same function via Ajax I get a 'success' response but which is completely empty. Stranger still, I found that if I return the output via wpautop( $output ) it comes back just fine. wpautop (link) is essentially a bunch of preg_replace functions to replace double line breaks with <p> tags so I tested returning my output via return preg_replace('<blah>', '', $content) and it worked!

Oh, I also tested removing all my changes from the add_trailing_slash() function above and the same issue persisted so I guess that something to do with the way str_get_html( $content ) parses the input makes it not play well with the Ajax callback. But why does preg_replace make it returnable?

function add_trailing_slash( $content ) {

    $content = str_get_html( $content );
    return $content;
}

I'm wondering if anyone else has come across this issue, whether I'm missing something and this is expected or whether this is a bug? I could leave in my preg_replace which appears to 'fix' the issue but it feels like something of a hack.


Solution

  • The only thing that come to my mind is that when you do $content = str_get_html( $content ); you are getting an object as result. Maybe when it goes through wp functions it get interpreted like a string but when you are json_encoding it, something may go wrong and kill it. You can either try to force-cast it to string with

    return (string) $content;
    

    or try to use

    // Dumps the internal DOM tree back into string
    $str = $html->save();
    

    as described in the docs