1

I have developed a simple shortcode plugin that essentially gets txt files from the url provided in the shortcode and parses a specific piece of data from them (date the file was last modified). I am trying to use WP transients to cache the parsed data for 24-48 hours before re-fetching the txt file again. The code I have works for the first call out to the file, and the parsed data successfully gets stored in a transient, but the transient never seems to expire so new data can be fetched. This is my first foray into using transients, so I apologize if it is something silly I am missing.

I am using redis object cache, but even when I disable redis the transients seem to not expire. The only way I can force an update is to change the site's redis cache key (so it essentially sees an empty cache). So, I don't think caching is the problem, but it could be...

The full code is on GitHub here, but the relevant code (I think) to help me with this bug is copied below.

    // wp shortcode [lastmodified url="url-value"]
    function lastmodified_func( $atts ) {
        $a = shortcode_atts( array(
            'url' => '',
        ), $atts );
        return filemtime_remote( $a['url'] );
    }
    add_shortcode( 'lastmodified', 'lastmodified_func' );

    // check the last modified value of a url
    function filemtime_remote( $url ) {
      $moddate = get_transient( 'mod_' . esc_url( $url ) );
      // if list date is due for refresh and max date refreshes for this page request have not been reached
      if( false === $moddate ) {
        $list = file_get_contents( $url , null , null , 0 , 480 );

        // parsing code omitted on stackexchange for brevity

        // set random transient timeout between 24 and 48 hrs
        $timeout = mt_rand( DAY_IN_SECONDS , DAY_IN_SECONDS * 2 );
        // set transient for url updated date
        set_transient( 'mod_' . esc_url( $url ), $moddate , $timeout );
      }
      return $moddate;
    }
  • does it work if you hardcode it to 5 seconds? did you check that the timeout you pass is not zero? – Mark Kaplun Apr 8 '16 at 17:03
1

Not clear about what exactly is wrong but few comments about things you are doing wrongish

  1. transients cache values up to a time so your random game can actually be totally pointless especially if a url is not being frequently fetched, since you use redis the value might expire as part of the memory cleanup when new values need to be added to it. In other words, the randomness in a way is already part of using a transient and your code might be pointless.

  2. An option name can be up to 64 characters, this means that for long urls you will end up with the same cached values for urls which starts with the same 64 (actually due to the transient prefix, even less) letters. Actually this might be a limitation on non redis implementation that save the transient to the DB, but I would just nut risk it - just use md5 or another hashing function in stead of escaping the URL.

  3. use a much better prefix for your transients, mod is way too generic and your code might colide with some other plugin.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.