Skip to content

Commit

Permalink
Add a cached thumbnail system for page images
Browse files Browse the repository at this point in the history
  • Loading branch information
geekwright committed Mar 24, 2013
1 parent 112f9b9 commit 7c8fc97
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 13 deletions.
6 changes: 3 additions & 3 deletions ajaximglist.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ function cleaner($string) {

for ($i = 0; $i < $xoopsDB->getRowsNum($result); $i++) {
$image = $xoopsDB->fetchArray($result);
$image['link']=XOOPS_URL . '/uploads/' . $dir . '/' . $image['image_file'];

// $image['link']=XOOPS_URL . '/uploads/' . $dir . '/' . $image['image_file'];
$image['link']=XOOPS_URL . '/modules/' . $dir . '/getthumb.php?page='.$image['keyword'].'&name='.$image['image_name'];
$images[]=$image;
}

$jsonimages=json_encode($images);
echo $jsonimages;
exit;
?>
?>
12 changes: 7 additions & 5 deletions blocks/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* @license GNU General Public License (GPL)
* @since 1.0
* @author Richard Griffith [email protected]
* @package qr
* @package gwiki
* @version $Id$
*/

Expand Down Expand Up @@ -196,11 +196,12 @@ function b_gwiki_teaserblock_show($options) {
$block['template']= 'db:'.$wikiPage->getTemplateName();

if($options[3]) {
$sql = 'SELECT image_file, image_alt_text FROM ' . $xoopsDB->prefix('gwiki_page_images') ;
$sql = 'SELECT * FROM ' . $xoopsDB->prefix('gwiki_page_images') ;
$sql .= ' WHERE keyword = "'.$page.'" AND use_to_represent = 1 ';
$result = $xoopsDB->query($sql);
if($myrow = $xoopsDB->fetchArray($result)) {
$block['image_file'] = XOOPS_URL .'/uploads/' . $dir . '/' . $myrow['image_file'];
// $block['image_file'] = XOOPS_URL .'/uploads/' . $dir . '/' . $myrow['image_file'];
$block['image_file'] = XOOPS_URL . '/modules/' . $dir . '/getthumb.php?page='.$page.'&name='.$myrow['image_name'];
$block['image_alt_text'] = $myrow['image_alt_text'];
}
}
Expand Down Expand Up @@ -255,7 +256,7 @@ function b_gwiki_recentblock_show($options) {

$keywords=array();

$sql = 'SELECT p.keyword, image_file, image_alt_text FROM ' . $xoopsDB->prefix('gwiki_pages') . ' p ';
$sql = 'SELECT p.keyword, image_file, image_alt_text, image_name FROM ' . $xoopsDB->prefix('gwiki_pages') . ' p ';
$sql .= ' left join ' . $xoopsDB->prefix('gwiki_page_images') . ' i on p.keyword=i.keyword and use_to_represent = 1 ';
$sql .= ' WHERE active=1 AND show_in_index=1 AND p.keyword like "'.$prefix.'" ';
$sql .= ' AND lastmodified > "'.$maxage.'" ORDER BY lastmodified desc';
Expand Down Expand Up @@ -286,7 +287,8 @@ function b_gwiki_recentblock_show($options) {
$gwiki['mayEdit'] = $wikiPage->checkEdit();
$gwiki['template'] = 'db:'.$wikiPage->getTemplateName();
if(!empty($keyimg['image_file'])) {
$gwiki['image_file'] = XOOPS_URL .'/uploads/' . $dir . '/' . $keyimg['image_file'];
// $gwiki['image_file'] = XOOPS_URL .'/uploads/' . $dir . '/' . $keyimg['image_file'];
$gwiki['image_file'] = XOOPS_URL . '/modules/' . $dir . '/getthumb.php?page='.$keyimg['keyword'].'&name='.$keyimg['image_name'];
$gwiki['image_alt_text'] = $keyimg['image_alt_text'];
}
$gwiki['pageurl'] = sprintf($wikiPage->getWikiLinkURL(),$gwiki['keyword']);
Expand Down
25 changes: 24 additions & 1 deletion classes/gwikiPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -1072,7 +1072,7 @@ public function getImageLib($keyword)
return array_unique($lib);;
}

private function getPageImage($keyword,$name)
public function getPageImage($keyword,$name)
{
global $xoopsDB;

Expand Down Expand Up @@ -1116,6 +1116,18 @@ private function renderImage($source)
if (strcasecmp('siteurl:', substr($link,0,8)) == 0) { // explicit reference to our site
$link=XOOPS_URL.substr($link,8);
}
$showthumb=false;
if (strcasecmp('thumb:', substr($link,0,6)) == 0) { // explicit reference to our site
$revertlink=$link;
$link=substr($link,6);
$showthumb=true;
}
$showthumblink=false;
if (strcasecmp('thumblink:', substr($link,0,10)) == 0) { // explicit reference to our site
$revertlink=$link;
$link=substr($link,10);
$showthumblink=true;
}
$alttext = empty($parms[0])?'':$parms[0];
$align = empty($parms[1])?'':$parms[1];
$maxpx = empty($parms[2])?'':intval($parms[2]).'px';
Expand All @@ -1142,13 +1154,24 @@ private function renderImage($source)
$link = XOOPS_URL . '/uploads/' . $this->wikiDir . '/' . $image['image_file'];
if(empty($alttext)) $alttext = $image['image_alt_text'];
}
else {
// thumbs don't apply, so put everything back the way it was
if($showthumb) { $link=$revertlink; $showthumb=false; }
if($showthumblink) { $link=$revertlink; $showthumblink=false; }
}

$alt='';
// $alttext=htmlspecialchars($alttext);
if(!empty($alttext)) $alt=" alt=\"{$alttext}\" title=\"{$alttext}\" ";

if(!empty($maxpx)) $maxpx=" style=\"max-width:{$maxpx}; max-height:{$maxpx}; width:auto; height:auto;\" ";

if($showthumb) {
$thumbsize=150; // TODO make module parameter
if(!empty($maxpx)) $thumbsize=$maxps;
$link=XOOPS_URL.'/modules/'.$this->wikiDir.'/getthumb.php?page='.$image['keyword'].'&name='.$image['image_name'].'&size='.$thumbsize;
}

$ret="<img class=\"wikiimage{$alignparm}\" src=\"{$link}\" {$alt}{$maxpx} />";

if($align=='center') $ret='<div style="margin: 0 auto; text-align: center;">'.$ret.'</div>';
Expand Down
169 changes: 169 additions & 0 deletions getthumb.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
<?php
/*
* blocks
*
* @copyright Geekwright, LLC http://geekwright.com
* @license GNU General Public License (GPL)
* @since 1.0
* @author Richard Griffith [email protected]
* @package gwiki
* @version $Id$
*
* Manage thumbnail cache. Expects gwiki_page_images keyword as page and
* image_name as name, also optional maximal pixel dimension as size.
*
* Thumbnails are generated for requested size on use, and then served
* from cache until source image is changed.
*
* Images which are smaller than requested size, or of an unsupported
* format (currently only jpeg, png and gif are supported,) are served
* as original source.
*
*/

include_once '../../mainfile.php';
$xoopsLogger->activated = false;
// provide error logging for our sanity in debugging (won't see xoops logger)
restore_error_handler();
error_reporting(-1);

//$xoopsOption['template_main'] = 'gwiki_view.html';
//include XOOPS_ROOT_PATH."/header.php";

$dir = basename( dirname( __FILE__ ) ) ;
include_once XOOPS_ROOT_PATH.'/modules/'.$dir.'/classes/gwikiPage.php';
$wikiPage = new gwikiPage;

$default_thumb_size=$xoopsModuleConfig['default_thumb_size'];

global $xoopsDB;

function errorExit($msg) {
header("Status: 500 Internal Error - ".$msg);
echo $msg;
exit;
}

function cleaner($string) {
$string=stripcslashes($string);
$string=html_entity_decode($string);
$string=strip_tags($string); // DANGER -- kills wiki text
$string=trim($string);
$string=stripslashes($string);
return $string;
}

function serveFile($name,$mime) {
$fp = fopen($name, 'rb');

header('Content-Type: ' . $mime);
header('Content-Disposition: inline; filename='. urlencode(basename($name)) );
header('Content-Length: ' . filesize($name) );

fpassthru($fp);
fclose($fp);
exit;
}

unset($page,$name,$size);
if (isset($_GET['page'])) $page = cleaner($_GET['page']);
if (isset($_GET['name'])) $name = cleaner($_GET['name']);
if (isset($_GET['size'])) $size = intval($_GET['size']);
if (empty($page) || empty($name)) errorExit("parameter missing");
if (empty($size) || $size==0) $size=$default_thumb_size;

$strategy=0;
$strategy_no_thumb=1; // no thumb possible or needed - pass original image
$strategy_old_thumb=2; // send existing thumbnail image
$strategy_new_thumb=3; // generate and pass new thumbnail

$image = $wikiPage->getPageImage($page,$name);
if(!$image) errorExit("invalid parameters");

$file=$image['image_file'];
$i=strrpos($file,'/');
if($i===false) errorExit("malformed path");
$file_pre=substr($file,0,$i);
$file_post=substr($file,$i);

$filename=XOOPS_ROOT_PATH.'/uploads/'.$dir.'/'.$file;
$thumbpath=XOOPS_ROOT_PATH.'/uploads/'.$dir.'/'.$file_pre.'/'.$size;
$thumbname=$thumbpath.$file_post;
//echo $filename.'<br />'.$thumbpath.'<br />'.$thumbname;

if (file_exists($thumbname) && (filemtime($thumbname) > filemtime($filename))) {
$strategy=$strategy_old_thumb;
$info = getimagesize($thumbname);
$img_width=$info[0];
$img_height=$info[1];
$img_mime=$info['mime'];
}
else { // (!file_exists($thumbname) || (file_exists($thumbname) && (filemtime($filename) > filemtime($thumbname))))
$info = getimagesize($filename);
$img_width=$info[0];
$img_height=$info[1];
$img_mime=$info['mime'];

if(($size >= $img_width) && ($size >= $img_height)) {
$thumb_width = $img_width;
$thumb_height = $img_height;
$strategy=$strategy_no_thumb;
}
else {
$ratio=max($img_width,$img_height) / $size;
$thumb_width = ceil($img_width / $ratio);
$thumb_height = ceil($img_height / $ratio);
$strategy=$strategy_new_thumb;
}

switch($info[2]) {
case IMAGETYPE_JPEG:
$img_type='jpg';
break;
case IMAGETYPE_PNG:
$img_type='png';
break;
case IMAGETYPE_GIF:
$img_type='gif';
break;
default:
$img_type='unsupported';
$strategy=$strategy_no_thumb;
break;
}
/*
echo '<br />Image Width: '.$img_width;
echo '<br />Image Height: '.$img_height;
echo '<br />Type: '.$info[2].' '.$img_type.' '.$img_mime;
echo '<br />Thumb Width: '.$thumb_width;
echo '<br />Thumb Height: '.$thumb_height;
*/
}

switch($strategy) {
case $strategy_new_thumb:
@mkdir($thumbpath,0755,true);
$data = file_get_contents($filename);
$im = imagecreatefromstring($data);
unset($data);
$ti = ImageCreateTrueColor($thumb_width, $thumb_height);
ImageCopyResampled($ti, $im, 0, 0, 0, 0, $thumb_width, $thumb_height, $img_width, $img_height);
imagedestroy($im);
if($img_type=='jpg') imagejpeg($ti, $thumbname, 80);
if($img_type=='png') imagepng($ti, $thumbname);
if($img_type=='git') imagegif($ti, $thumbname);
imagedestroy($ti);
serveFile($thumbname,$img_mime);
break;
case $strategy_old_thumb:
serveFile($thumbname,$img_mime);
break;
default:
serveFile($filename,$img_mime);
break;
}

errorExit('unknown condition');
//include XOOPS_ROOT_PATH."/footer.php";
?>
2 changes: 2 additions & 0 deletions language/english/modinfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
define('_MI_GWIKI_AJAX_ALLOW_ORIGIN_DESC', 'String to include in Access-Control-Allow-Origin: header for AJAX Wiki. Leave blank to disable, * to allow all, or specific host(s)');
define('_MI_GWIKI_ALLOW_CAMELCASE', 'Treat CamelCase as Link');
define('_MI_GWIKI_ALLOW_CAMELCASE_DESC', 'Treat CamelCase text in Wiki pages as a link to a same named page.');
define('_MI_GWIKI_DEFAULT_THUMB_SIZE', 'Default Thumbnail Size');
define('_MI_GWIKI_DEFAULT_THUMB_SIZE_DESC', 'Default maximal pixel dimension for thumbnail cache.');

// Wiki special pages
// Change these names, if you want a different homepage and error page
Expand Down
4 changes: 2 additions & 2 deletions module.css
Original file line number Diff line number Diff line change
Expand Up @@ -571,8 +571,8 @@ ul.wikitoclist > li { list-style: none; }
}
#wikieditimg_dd img, #wikieditfile_dd img
{
max-height: 120px;
max-width: 120px;
max-height: 150px;
max-width: 150px;
height: auto;
width: auto;
}
Expand Down
12 changes: 10 additions & 2 deletions xoops_version.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@
'description' => '_MI_GWIKI_ATTACH_EXT_BLACKLIST_DESC',
'formtype' => 'textbox',
'valuetype' => 'text',
'default' => 'ini,php,phtml,php4,php3,php5,phps,pl,pm,t,pod,ap,asa,asax,ascx,ashx,asmx,asp,aspx,asr,axd,jsp,jspx',
'default' => '', //'ini,php,phtml,php4,php3,php5,phps,pl,pm,t,pod,ap,asa,asax,ascx,ashx,asmx,asp,aspx,asr,axd,jsp,jspx',
'options' => array() );

$modversion['config'][]= array(
Expand All @@ -157,7 +157,7 @@
'description' => '_MI_GWIKI_ATTACH_EXT_WHITELIST_DESC',
'formtype' => 'textbox',
'valuetype' => 'text',
'default' => '',
'default' => 'pdf,doc,docx,xls,ppt,jpg,jpeg,png',
'options' => array() );

$modversion['config'][]= array(
Expand All @@ -177,6 +177,14 @@
'valuetype' => 'int',
'default' => '1');

$modversion['config'][]= array(
'name' => 'default_thumb_size',
'title' => '_MI_GWIKI_DEFAULT_THUMB_SIZE',
'description' => '_MI_GWIKI_DEFAULT_THUMB_SIZE_DESC',
'formtype' => 'textbox',
'valuetype' => 'int',
'default' => 150 );


// Blocks
$modversion['blocks'][1] = array(
Expand Down

0 comments on commit 7c8fc97

Please sign in to comment.