Smarty Forum Index Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon.

{safecache} block function to make sql queries safe

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> Tips and Tricks
View previous topic :: View next topic  
Author Message
jtm
Smarty Rookie


Joined: 13 Nov 2003
Posts: 9

PostPosted: Fri Nov 21, 2003 8:26 am    Post subject: {safecache} block function to make sql queries safe Reply with quote

It's easy to fetch some data from a SQL database using smarty template functions but what if the database backend is down? We can't just display some cryptic errors to the user. A message "Sorry, database is down" isn't also wery pretty Sad

The following block function let's you do the following:

Code:


{safecache id="sql fetch" template=$smarty.template" ttl=60}

  {fetch some data from database and do something}

  {* If the sql fetch encountered an error (for example, database is down)
       the {fetch} function can set $smarty->sql_error = true; and return.
       This makes the safecache use the last cache available *}

{/safecache}



The contents inside safecache block is only processed if the cache is expired (or there isn't any cache available).

So to make this work the database needs to be up once so that the cache file is generated. Then after that the cache is rewrited only if the code inside safecache block didn't set $smarty->sql_error to true. This way you can fall back to the last known working result of the database fetch.

NOTE: This only caches the final html code. This also uses own caching functions so this doesn't support non-cacheable functions etc. Only HTML code is cached (but at least for me, it's sufficent).

Note also that the functions which you use to fetch data from database etc must support this by setting $smarty->sql_error to true in case of error.

The block function safecache and function sql_error which can be used in templates.

Code:

/*
 * block function safecache:
 *
 * To use you must add two variables to Smarty.class.php:
 * variable 1: $smarty->default_safecache_ttl - default ttl for caches in seconds.
 * variable 2: $smarty->cacheroot - directory where cache files are stored.  This should be different than normal smarty cache directory. Member to add '/' into the cacheroot variable in the end.
 *
 *
 * @param id Id of safecache block. This must be unique inside one template
 * @param template template name. get this from $smarty.template
 */
smarty_block_safecache($params, $content, &$smarty, &$repeat)
{
  // validation
  global $dsp;

  extract ($params);
  foreach (array('id', 'template') as $required) {
    if (!isset($$required)) {
      $smarty->trigger_error("safecache block: $$required param missing. Aborted.");
      return;
    }
  }

  if (!isset($ttl)) {
    $ttl = $smarty->default_safecache_ttl;
  }

  $unique_id = md5($template . $id);

  $filename = $smarty->cacheroot . $unique_id;

  if (!isset($content)) {
    // first iteration through block, so no content was processed
    // try and read from the cache (if succeeds, do not re-enter block)

    if (file_exists($filename)) {
      if ((filemtime($filename) > (time() - $ttl))) {

        $content = file_get_contents($filename);
        $repeat = 0;
        echo $content;
        return $content;
      }
    }

    // reset sql error state
    $smarty->sql_error = false;

  } else {

    // cache-miss

    // If there were an error
    if ($smarty->sql_error == true) {
      if (file_exists($filename)) {
        $content = file_get_contents($filename);
        $repeat = 0;
        return $content;
      } else {
        die("fatal error, no cache");
      }

      // cache miss but we regenerated the content without errors, so save it to the cache.
    } else {

      if (!is_dir($dsp->cacheroot)) {
        mkdir($dsp->cacheroot);
      }

      $fp = fopen($filename, 'w');
      fwrite($fp, $content);
      fclose($fp);

      return $content;
    }

    die("fatal error, we should not be here");
  }
}

/*
 * sql_error
 *
 * Triggers sql error condition to true which makes safecache to fallback into last known cache.
 */
function smarty_function_sql_error($params, &$smarty) {
  $smarty->sql_error = true;
}


Hope this helps Smile

- jtm
Back to top
View user's profile Send private message
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> Tips and Tricks All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP