Extensions

eAccelerator caching

    Developer:

    a. Reduce load on the DB server

    This is based on the caching technique described on https://www.zenphoto.org/2008/01/hacks/ We'll use eAccelerator shm cache instead of storing the query results on disk.
    1. Edit the functions-db.php under zp-core directory.
    2. Search function query_single_row, change it to:
    function query_single_row($sql, $noerrmsg=false) {
    if ($cache = get_cache($sql))
    return $cache;
    $result = query($sql, $noerrmsg);
    if ($result) {
    $data = mysql_fetch_assoc($result);
    store_cache($sql, $data);
    return $data;
    }
    else {
    return false;
    }
    }

    3. Search function query_full_array, change it to:
    function query_full_array($sql, $noerrmsg = false) {
    if ($cache = get_cache($sql))
    return $cache;
    $result = query($sql, $noerrmsg);
    if ($result) {
    $allrows = array();
    while ($row = mysql_fetch_assoc($result))
    $allrows[] = $row;
    store_cache($sql, $allrows);
    return $allrows;
    }
    else {
    return false;
    }
    }

    4. Last thing, add two functions in functions-db.php. You could change “cachedirectory” to your cache directory, and change $cache_time_out to the expire time you want.
    function store_cache($query, $result_cache) {
    $cache_time_out = 600;
    if (preg_match("/^(insert|delete|update|replace)\s+/i",$query))
    return;
    if (stristr($query, "ORDER BY RAND"))
    return;
    $key = 'sql_' . md5($query);
    $val = serialize($result_cache);
    eaccelerator_put($key, $val, $cache_time_out);
    }


    function get_cache($query) {
    if (preg_match("/^(insert|delete|update|replace)\s+/i",$query))
    return;
    if (stristr($query, "ORDER BY RAND"))
    return;
    $key = 'sql_' . md5($query);
    $val = eaccelerator_get($key);
    if ( $val != NULL )
    return unserialize($val);
    }

    b. Bypassing directory traversal

    ZP scans the albums directory every time the script is executed. Since disk operations are expensive, we can try to limit disk-based I/O to make it load faster. We'll be using eAccelerator to cache our stuff, but you can easily adopt this code for APC, XCache, memcached or even a disk-file.
    1. Open class-album.php in zp-core directory.
    2. Put the following code at the beginning of the script:
    function store_filenames_cache($dir, $has_dir, $pic_cache, $vid_cache) {
    $cache_time_out = 600;
    if ($has_dir) {
    $pic_key = 'dp_' . md5($dir);
    $vid_key = 'dv_' . md5($dir);
    }
    else {
    $pic_key = 'fp_' . md5($dir);
    $vid_key = 'fv_' . md5($dir);
    }
    $pic_val = serialize($pic_cache);
    $vid_val = serialize($vid_cache);
    eaccelerator_put($pic_key, $pic_val, $cache_time_out);
    eaccelerator_put($vid_key, $vid_val, $cache_time_out);
    }
    function get_filenames_cache($dir, $has_dir, &$pic_cache, &$vid_cache) {
    if ($has_dir) {
    $pic_key = 'dp_' . md5($dir);
    $vid_key = 'dv_' . md5($dir);
    }
    else {
    $pic_key = 'fp_' . md5($dir);
    $vid_key = 'fv_' . md5($dir);
    }
    $pic_cache = eaccelerator_get($pic_key);
    $vid_cache = eaccelerator_get($vid_key);
    if ( $pic_cache != NULL ) {
    $pic_cache = unserialize($pic_cache);
    }
    else {
    return FALSE;
    }
    if ( $vid_cache != NULL ) {
    $vid_cache = unserialize($vid_cache);
    }
    else {
    return FALSE;
    }
    return TRUE;
    }

    3. Locate the loadFileNames() function, and replace it with this:
    function loadFileNames($dirs=false) {
    if ($this->isDynamic()) { // there are no 'real' files
    return array();
    }
    $albumdir = getAlbumFolder() . $this->name . "/";
    if (!is_dir($albumdir) || !is_readable($albumdir)) {
    $msg = gettext("Error: The 'albums' directory")." (" . $this->albumdir . ") ";
    if (!is_dir($this->albumdir)) {
    $msg .= gettext("cannot be found.");
    } else {
    $msg .= gettext("is not readable.");
    }
    die($msg);
    }
    //masroore - cache these results
    if (get_filenames_cache($albumdir, $dirs, $files, $videos) === FALSE) {
    $dir = opendir($albumdir);
    $files = array();
    $videos = array();
    while (false !== ($file = readdir($dir))) {
    if ($dirs && (is_dir($albumdir.$file) && (substr($file, 0, 1) != '.') || hasDyanmicAlbumSuffix($file))) {
    $files[] = $file;
    } else if (!$dirs && is_file($albumdir.$file)) {
    if (is_valid_video($file)) {
    $files[] = $file;
    $videos[] = $file;
    } else if (is_valid_image($file)) {
    $files[] = $file;
    }
    }
    }
    closedir($dir);
    store_filenames_cache($albumdir, $dirs, $files, $videos);
    }
    if (count($videos) > 0) {
    $video_thumbs = array();
    foreach($videos as $video) {
    $video_root = substr($video, 0, strrpos($video,"."));
    foreach($files as $image) {
    $image_root = substr($image, 0, strrpos($image,"."));
    if ($image_root == $video_root && $image != $video) {
    $video_thumbs[] = $image;
    }
    }
    }
    $files = array_diff($files, $video_thumbs);
    }
    return $files;
    }

    This extension has been abandoned by the ZenphotoCMS team and we provide it for archival purposes on our "unsuppported-plugins-offical" GitHub repository "as is". .

    Info & download (GitHub)

    For questions and comments please use the forum or discuss on the social networks.


    More by author:

    • Nothing else available by Invarbrass

    Related items