Skip to content

Commit

Permalink
Improve caching to be more robust
Browse files Browse the repository at this point in the history
  • Loading branch information
vampy committed Jul 31, 2014
1 parent 55db55a commit 24dace8
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 80 deletions.
6 changes: 3 additions & 3 deletions image.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
* You should have received a copy of the GNU General Public License
* along with stkaddons. If not, see <http://www.gnu.org/licenses/>.
*/

require_once(__DIR__ . DIRECTORY_SEPARATOR . "config.php");

$type = (isset($_GET['type'])) ? $_GET['type'] : null;
Util::resizeImage($_GET['pic'], $type);
$size = empty($_GET['size']) ? null : $_GET['size'];
$file = empty($_GET['pic']) ? null : $_GET['pic'];
Util::resizeImage($file, (int)$size);
2 changes: 1 addition & 1 deletion include/Addon.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -1483,7 +1483,7 @@ public static function filterMenuTemplate($addons, $type)
// Make sure an icon file is set for kart
if ($addon->getImage(true) != 0)
{
$im = Cache::getImage($addon->getImage(true), ['size' => 'small']);
$im = Cache::getImage($addon->getImage(true), SImage::SIZE_SMALL);
if ($im['exists'] && $im['approved'])
{
$icon = $im['url'];
Expand Down
4 changes: 2 additions & 2 deletions include/AddonViewer.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public function fillTemplate($template)
}

// Get image url
$image = Cache::getImage($this->addon->getImage(), ['size' => 'big']);
$image = Cache::getImage($this->addon->getImage(), SImage::SIZE_BIG);
if ($this->addon->getImage() != 0 && $image['exists'] == true && $image['approved'] == true)
{
$tpl['image_url'] = $image['url'];
Expand Down Expand Up @@ -181,7 +181,7 @@ public function fillTemplate($template)
$image_files_db = $this->addon->getImages();
foreach ($image_files_db as $image)
{
$imageCache = Cache::getImage($image['id'], ['size' => 'medium']);
$imageCache = Cache::getImage($image['id'], SImage::SIZE_MEDIUM);
$image['thumb']['url'] = $imageCache['url'];
$image['url'] = DOWNLOAD_LOCATION . $image['file_path'];
$image['approved'] = (bool)$image['approved'];
Expand Down
77 changes: 36 additions & 41 deletions include/Cache.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,16 @@
class Cache
{


/**
* Empty the cache folder, leave certain files in place
*
* @param string $exclude_regex files to exclude regex
*
* @return bool
*/
public static function clear()
public static function clear($exclude_regex = '/^(cache_graph_.*\.png)$/i')
{
$exclude_regex = '/^(cache_graph_.*\.png)$/i';
File::deleteDir(CACHE_PATH, $exclude_regex);
mkdir(CACHE_PATH);

Expand All @@ -51,12 +53,8 @@ public static function clear()
{
continue;
}
DBConnection::get()->query(
'DELETE FROM `' . DB_PREFIX . 'cache`
WHERE `file` = :file',
DBConnection::NOTHING,
[':file' => $cache_item['file']]
);

DBConnection::get()->delete("cache", "`file` = :file", [':file' => $cache_item['file']]);
}
}
catch(DBException $e)
Expand All @@ -70,7 +68,7 @@ public static function clear()
/**
* Clear the addon cache files
*
* @param string $addon
* @param string $addon the addon id
*
* @return bool
*/
Expand All @@ -94,20 +92,16 @@ public static function clearAddon($addon)
foreach ($cache_list AS $cache_item)
{
unlink(CACHE_PATH . $cache_item['file']);
DBConnection::get()->query(
'DELETE FROM `' . DB_PREFIX . 'cache`
WHERE `file` = :file',
DBConnection::NOTHING,
[':file' => $cache_item['file']]
);
}

return true;
DBConnection::get()->delete("cache", "`file` = :file", [':file' => $cache_item['file']]);
}
}
catch(DBException $e)
{
return false;
}

return true;
}

/**
Expand Down Expand Up @@ -177,22 +171,22 @@ public static function fileExists($path)
/**
* Get image properties for a cacheable image
*
* @param integer $id
* @param array $props
* @param int $id the id of the file
* @param int $size image size, see SImage::SIZE_
*
* @return array
* @throws CacheException
*/
public static function getImage($id, $props = [])
public static function getImage($id, $size = null)
{
try
{
$result = DBConnection::get()->query(
$file = DBConnection::get()->query(
'SELECT `file_path`, `approved`
FROM `' . DB_PREFIX . 'files`
WHERE `id` = :id
LIMIT 1',
DBConnection::FETCH_ALL,
DBConnection::FETCH_FIRST,
[':id' => $id],
[':id' => DBConnection::PARAM_INT]
);
Expand All @@ -202,7 +196,8 @@ public static function getImage($id, $props = [])
throw new CacheException('Failed to look up image file.');
}

if (empty($result))
// image does with tha id does not exist in the database
if (empty($file))
{
return [
'url' => IMG_LOCATION . 'notfound.png',
Expand All @@ -212,22 +207,21 @@ public static function getImage($id, $props = [])
}

$return = [
'url' => DOWNLOAD_LOCATION . $result[0]['file_path'],
'approved' => (bool)$result[0]['approved'],
'url' => DOWNLOAD_LOCATION . $file['file_path'],
'approved' => (bool)$file['approved'],
'exists' => true
];

$cache_prefix = null;
if (array_key_exists('size', $props))
{
$cache_prefix = Cache::cachePrefix($props['size']);
$cache_prefix = $size ? Cache::cachePrefix($size) : "";

$return['url'] = SITE_ROOT . 'image.php?type=' . $props['size'] . '&amp;pic=' . $result[0]['file_path'];
// image exists in cache
if (Cache::fileExists($cache_prefix . basename($file['file_path'])))
{
$return['url'] = CACHE_LOCATION . $cache_prefix . basename($file['file_path']);
}

if (Cache::fileExists($cache_prefix . basename($result[0]['file_path'])))
else // create new cache by resizing the image
{
$return['url'] = CACHE_LOCATION . $cache_prefix . basename($result[0]['file_path']);
$return['url'] = SITE_ROOT . 'image.php?size=' . $size . '&amp;pic=' . $file['file_path'];
}

return $return;
Expand All @@ -236,27 +230,28 @@ public static function getImage($id, $props = [])
/**
* @param string $size
*
* @return null|string
* @return string
*/
private static function cachePrefix($size)
public static function cachePrefix($size)
{
if (empty($size))
if (!$size)
{
return null;
return '';
}
if ($size === 'big')

if ($size === SImage::SIZE_BIG)
{
return '300--';
}
if ($size === 'medium')
if ($size === SImage::SIZE_MEDIUM)
{
return '75--';
}
if ($size === 'small')
if ($size === SImage::SIZE_SMALL)
{
return '25--';
}

return null;
return '100--';
}
}
7 changes: 3 additions & 4 deletions include/File.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public static function exists($path)
return 0;
}

if (empty($files))
if (empty($file))
{
return 0;
}
Expand Down Expand Up @@ -771,9 +771,8 @@ public static function getAllFiles()
}
$return_files[] = $db_file;
}
// fs_files now contains only files that do not exist in the database
// and exist only on disk
$fs_files = array_values($fs_files);
// fs_files now contains only files that do not exist in the database and exist only on disk
$fs_files = array_values($fs_files); // reset indices

// add files that exist on the disk but not in the database
foreach ($fs_files as $file_path)
Expand Down
15 changes: 15 additions & 0 deletions include/SImage.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,21 @@
*/
class SImage
{
/**
* @const int
*/
const SIZE_SMALL = 1;

/**
* @const int
*/
const SIZE_MEDIUM = 2;

/**
* @const int
*/
const SIZE_BIG = 3;

/**
* @var string
*/
Expand Down
75 changes: 51 additions & 24 deletions include/Util.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ public static function array_flatten(array $array, $preserve_keys = true)
/**
* A time is old enough if the current time is greater than the user time + the max age
*
* @param int $time current time in seconds
* @param int $time current time in seconds
* @param int $max_age max time in seconds
*
* @return bool
Expand Down Expand Up @@ -346,7 +346,7 @@ public static function getQueryVars($query)
foreach ($hashes as $hash)
{
$hash = explode("=", $hash);
// key => balue
// key => value
$vars[$hash[0]] = $hash[1];
}

Expand Down Expand Up @@ -609,46 +609,71 @@ public static function getRandomString(
/**
* Resize an image, and send the new resized image to the user with http headers
*
* @param string $file
* @param string|null the type of image
* @param string $file
* @param int $orig_size the size of the image
*
* @return null
*/
public static function resizeImage($file, $type = null)
public static function resizeImage($file, $orig_size = null)
{
// file is invalid
if (!$file)
{
header('HTTP/1.1 404 Not Found');
if (DEBUG_MODE)
{
echo "file is empty";
}

return;
}

// Determine image size
switch ($type)
switch ($orig_size)
{
case 'small':
case SImage::SIZE_SMALL:
$size = 25;
break;
case 'medium':

case SImage::SIZE_MEDIUM:
$size = 75;
break;
case 'big':

case SImage::SIZE_BIG:
$size = 300;
break;

default:
$size = 100;
break;
}
$cache_name = $size . '--' . basename($file);
$local_path = UP_PATH . $file;

// Check if image exists, and if it does, check its format
$cache_name = Cache::cachePrefix($orig_size) . basename($file);
$local_path = UP_PATH . $file; // all images should be in our upload directory

// Check if image exists in the database
$orig_file = File::exists($file);
if ($orig_file)
if (!$orig_file)
{
if (!file_exists(ROOT_PATH . $file))
header('HTTP/1.1 404 Not Found');
if (DEBUG_MODE)
{
header('HTTP/1.1 404 Not Found');

return;
echo sprintf("%s does not exist in the database", $file);
}
else

return;
}

// file does not exist on disk
if (!file_exists($local_path))
{
header('HTTP/1.1 404 Not Found');
if (DEBUG_MODE)
{
$local_path = ROOT_PATH . $file;
echo sprintf("%s does not exist on the disk", $file);
}

return;
}

// Check if a cached version is available
Expand All @@ -661,21 +686,23 @@ public static function resizeImage($file, $type = null)
}

// Start processing the original file
$image_info = @getimagesize($local_path);
$image_info = getimagesize($local_path);
switch ($image_info[2])
{
default:
$source = imagecreatefrompng(IMG_LOCATION . 'notfound.png');
$format = 'png';
break;
case IMAGETYPE_PNG:
$source = imagecreatefrompng($local_path);
$format = 'png';
break;

case IMAGETYPE_JPEG:
$source = imagecreatefromjpeg($local_path);
$format = 'jpg';
break;

default:
$source = imagecreatefrompng(IMG_LOCATION . 'notfound.png');
$format = 'png';
break;
}

// Get length and width of original image
Expand Down
Loading

0 comments on commit 24dace8

Please sign in to comment.