0byt3m1n1
Path:
/
data
/
applications
/
aps
/
tikiwiki
/
14.1-0
/
standard
/
htdocs
/
lib
/
imagegals
/
[
Home
]
File: imagegallib.php
<?php // (c) Copyright 2002-2015 by authors of the Tiki Wiki CMS Groupware Project // // All Rights Reserved. See copyright.txt for details and a complete list of authors. // Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details. // $Id: imagegallib.php 53803 2015-02-06 00:42:50Z jyhem $ //this script may only be included - so its better to die if called directly. if (strpos($_SERVER["SCRIPT_NAME"], basename(__FILE__)) !== false) { header("location: index.php"); exit; } /** * */ class ImageGalsLib extends TikiLib { /** * */ function __construct() { parent::__construct(); global $prefs; $exts = get_loaded_extensions(); // Which GD Version do we have? if (in_array('gd', $exts)) { $this->havegd = true; if (function_exists("gd_info")) { $this->gdinfo = gd_info(); preg_match("/[0-9]+\.[0-9]+/", $this->gdinfo["GD Version"], $gdversiontmp); $this->gdversion = $gdversiontmp[0]; } else { //next try ob_start(); phpinfo(INFO_MODULES); if (preg_match('/GD Version.*2.0/', ob_get_contents())) { $this->gdversion = "2.0"; } else { // I have no experience ... maybe someone knows better $this->gdversion = "1.0"; } $this->gdinfo["JPG Support"] = preg_match('/JPE?G Support.*enabled/', ob_get_contents()); $this->gdinfo["PNG Support"] = preg_match('/PNG Support.*enabled/', ob_get_contents()); $this->gdinfo["GIF Create Support"] = preg_match('/GIF Create Support.*enabled/', ob_get_contents()); $this->gdinfo["WBMP Support"] = preg_match('/WBMP Support.*enabled/', ob_get_contents()); $this->gdinfo["XBM Support"] = preg_match('/XBM Support.*enabled/', ob_get_contents()); ob_end_clean(); } } else { $this->havegd = false; } // Do we have the imagick PECL module? // Module can be downloaded at http://pecl.php.net/package/imagick // Also check on 'imagick_rotate' function because the first check may detect imagick 2.x which has a completely different API if (in_array('imagick', $exts) && function_exists('imagick_rotate')) { $this->haveimagick = true; } else { $this->haveimagick = false; } //what shall we use? //$this->uselib = "gd"; $this->uselib = $prefs['gal_use_lib']; //Fallback to GD if ($this->uselib == "imagick" && $this->haveimagick == false) { $this->uselib = "gd"; $this->set_preference('gal_use_lib', 'gd'); } if ($this->uselib == "imagick") { $this->canrotate = true; } else { $this->canrotate = false; } // get variables to determine if we can upload and how many data // we can upload $this->file_uploads=ini_get('file_uploads'); $this->upload_max_filesize=ini_get('upload_max_filesize'); $this->post_max_size=ini_get('post_max_size'); if ($this->file_uploads==0) { $this->max_img_upload_size=0; } } /** * @return int */ function max_img_upload_size() { global $tikilib; $this->upload_max_filesize=$tikilib->return_bytes($this->upload_max_filesize); $this->post_max_size=$tikilib->return_bytes($this->post_max_size); if ($this->file_uploads==0) { return(0); } else { return(($this->post_max_size > $this->upload_max_filesize) ? $this->post_max_size : $this->upload_max_filesize); } } // Features /** * @return bool */ function canrotate() { return $this->canrotate; } // // Wrappers // /** * @return bool */ function validhandle() { if (isset($this->imagehandle)) { if ($this->uselib == "imagick") { // seems not to work in imagick 0.95 aahrgh if (imagick_iserror($this->imagehandle)) return false; return true; } else if ($this->uselib == "gd") { if (imagesx($this->imagehandle) == 0) return false; return true; } } return false; } /** * @return bool */ function readimagefromstring() { if (!isset($this->image)) { return false; } //avoid error messages if (isset($this->filetype)) { if (!$this->issupported($this->filetype)) { return false; } } if ($this->uselib == "imagick") { $this->imagehandle = imagick_blob2image($this->image); } else if ($this->uselib == "gd") { $this->imagehandle = imagecreatefromstring($this->image); } } function writeimagetostring() { if ($this->uselib == "imagick") { $this->image = imagick_image2blob($this->imagehandle); } else if ($this->uselib == "gd") { ob_start(); imagejpeg($this->imagehandle); $this->image = ob_get_contents(); ob_end_clean(); } } /** * @param $fname * @return bool */ function readimagefromfile($fname) { @$fp = fopen($fname, "rb"); if ($fp) { $size = filesize($fname); $this->image = fread($fp, $size); fclose($fp); // convert to imagehandle to be able to check if its // valid image data $this->readimagefromstring(); // check if imagehandle is a image: return($this->validhandle()); } else { return false; } } // for piping out a image /** * @param $fname */ function pipeimage($fname) { $fp = fopen($fname, "rb"); $size = filesize($fname); $this->image = fread($fp, $size); fclose($fp); $this->readimagefromstring(); if ($this->validhandle()) echo $data; } //Get sizes. Image must be loaded before function getimageinfo() { if ($this->uselib == "imagick") { $this->filetype = imagick_getmimetype($this->imagehandle); $this->xsize = imagick_getwidth($this->imagehandle); $this->ysize = imagick_getheight($this->imagehandle); } else if ($this->uselib == "gd") { $this->xsize = imagesx($this->imagehandle); $this->ysize = imagesy($this->imagehandle); } } //Repair Image info. Is called if someone inserts unsupported images (like gif) //and switches to imagick function repairimageinfo() { if (!isset($this->imageId)) die(); if (!$this->issupported($this->filetype)) die(); $this->getimageinfo(); //update $query = "update `tiki_images_data` set `xsize`=? , `ysize`=? where `imageId`=? and `type`=?"; $this->query($query, array((int)$this->xsize, (int)$this->ysize, (int)$this->imageId, $this->type)); } // GD can only get the mimetype from the file /** * @param $fname */ function getfileinfo($fname) { $this->filesize = filesize($fname); if ($this->uselib == "gd") { unset ($this->filetype); $imageinfo = getimagesize($fname); if ($imageinfo["0"] > 0 && $imageinfo["1"] > 0 && $imageinfo["2"] > 0) { if ($this->gdversion >= 2.0) { $this->filetype = $imageinfo["mime"]; } else { $mimetypes = array( "1" => "gif", "2" => "jpg", "3" => "png", "4" => "swf", "5" => "psd", "6" => "bmp", "7" => "tiff", "8" => "tiff", "9" => "jpc", "10" => "jp2", "11" => "jpx", "12" => "jb2", "13" => "swc", "14" => "iff" ); $this->filetype = "image/" . $mimetypes[$imageinfo["2"]]; } } } } // resize Image /** * @param $newx * @param $newy * @return bool */ function resizeImage($newx, $newy) { if (!isset($this->imagehandle)) { $this->readimagefromstring(); } if (!isset($this->xsize)) { $this->getimageinfo(); } if ($this->xsize * $this->ysize == 0) $this->repairimageinfo(); if ($this->uselib == "imagick") { if (!imagick_scale($this->imagehandle, $newx, $newy, "!")) { $reason = imagick_failedreason($handle); $description = imagick_faileddescription($handle); // todo: Build in error handler in imagegallib exit; } } else if ($this->uselib == "gd") { if ($this->gdversion >= 2.0) { $t = imagecreatetruecolor($newx, $newy); imagecopyresampled($t, $this->imagehandle, 0, 0, 0, 0, $newx, $newy, $this->xsize, $this->ysize); } else { $t = imagecreate($newx, $newy); $this->ImageCopyResampleBicubic($t, $this->imagehandle, 0, 0, 0, 0, $newx, $newy, $this->xsize, $this->ysize); } $this->imagehandle = $t; } // fill $this->image for writing or output $this->writeimagetostring(); // reget sizes $this->getimageinfo(); //set new sizes $this->xsize = $newx; $this->ysize = $newy; return true; } // rescale Image, almost the same as resize, but keeps apect ratio // bbx and bby give the boundary box /** * @param $bbx * @param $bby * @return bool */ function rescaleImage($bbx, $bby) { if (!$bbx || !$bby) return true; if (!isset($this->imagehandle)) { $this->readimagefromstring(); } if (!isset($this->xsize)) { $this->getimageinfo(); } if ($this->xsize * $this->ysize == 0) $this->repairimageinfo(); if ($this->xsize > $this->ysize) { $tscale = ((int)$this->xsize / $bbx); } else { $tscale = ((int)$this->ysize / $bby); } $newx = round($this->xsize / $tscale); $newy = round($this->ysize / $tscale); if ($newx > $this->xsize && $newy > $this->ysize) return true; return $this->resizeImage($newx, $newy); } /** * @param $angle */ function rotateimage($angle) { if ($this->uselib == "imagick") { //Imagick and GD have different opinion what is 90 degree. right or left? imagick_rotate($this->imagehandle, -$angle); } else if ($this->uselib == "gd") { if ($this->gdversion > 2.0) { //I know, it's PHP <= 4.3.0. It destroys images if u try to rotate them $this->imagehandle = imagerotate($this->imagehandle, $angle, 0); } } // update the $this->image $this->writeimagetostring(); //get new sizex, sizey $this->oldxsize = $this->xsize; $this->oldysize = $this->ysize; $this->getimageinfo(); } // function to determine supported image types // imagick has no function to get the supported image types /** * @param $imagetype * @return bool */ function issupported($imagetype) { if ($this->uselib == "imagick") { //imagick can read everything ... we assume return true; } else if ( $this->uselib == "gd" && $this->havegd == true ) { switch (strtolower($imagetype)) { case 'jpeg': case 'pjpeg': case 'jpg': case 'image/jpeg': case 'image/pjpeg': case 'image/jpg': return ((isset($this->gdinfo['JPG Support']) && $this->gdinfo['JPG Support']) || (isset($this->gdinfo['JPEG Support']) && $this->gdinfo['JPEG Support']) ); break; case 'png': case 'image/png': return ($this->gdinfo["PNG Support"]); break; case 'gif': case 'image/gif': return ($this->gdinfo["GIF Create Support"]); break; case 'bmp': case 'image/bmp': return ($this->gdinfo["WBMP Support"]); break; case 'xbm': case 'image/xbm': return ($this->gdinfo["XBM Support"]); break; default: return false; break; } } else { return false; } } // Batch image uploads todo /** * @param $galleryId * @param $file * @param $user * @return bool|int */ function process_batch_image_upload($galleryId, $file, $user) { global $prefs; $numimages = 0; include_once ('vendor_extra/pclzip/pclzip.lib.php'); $archive = new PclZip($file); // Read Archive contents $ziplist = $archive->listContent(); if (!$ziplist) return (false); // Archive invalid foreach ($ziplist as $zipfile) { $file = $zipfile["filename"]; if (!$zipfile["folder"]) { //copied $gal_info = $this->get_gallery($galleryId); $upl = 1; if (!empty($prefs['gal_match_regex'])) { if (!preg_match('/'.$prefs['gal_match_regex'].'/', $file, $reqs)) $upl = 0; } if (!empty($prefs['gal_nmatch_regex'])) { if (preg_match('/'.$prefs['gal_nmatch_regex'].'/', $file, $reqs)) $upl = 0; } //extract file $archive->extractByIndex( $zipfile["index"], $prefs['tmpDir'], dirname($file) ); //extract and remove (dangerous) pathname $file = basename($file); //unset variables unset ($this->filetype); unset ($this->xsize); unset ($this->ysize); //determine filetype and dimensions $this->getfileinfo($prefs['tmpDir'] . "/" . $file); $foo=explode(".", $file); $exp=end($foo); // read image and delete it after $this->readimagefromfile($prefs['tmpDir'] . "/" . $file); unlink($prefs['tmpDir'] . "/" . $file); if ($this->issupported($exp)) { // convert to handle $this->readimagefromstring(); if ($this->validhandle()) { $this->getimageinfo(); } } //if there is no mimetype, we don't got a image if (isset($this->filetype)) { if (!isset($this->xsize)) { $this->xsize = $this->ysize = 0; } $imageId = $this->insert_image( $galleryId, $file, '', $file, $this->filetype, $this->image, $this->filesize, $this->xsize, $this->ysize, $user, '', '', NULL, NULL, $gal_info ); $numimages++; } } } return $numimages; } /** * @param $id * @return bool */ function add_image_hit($id) { global $prefs, $user; if ($prefs['count_admin_pvs'] == 'y' || $user != 'admin') { $query = "update `tiki_images` set `hits`=`hits`+1 where `imageId`=?"; $result = $this->query($query, array((int)$id)); } if ($prefs['feature_score'] == 'y') { $this->score_event($user, 'igallery_see_img', $id); $query = "select `user` from `tiki_images` where `imageId`=?"; $owner = $this->getOne($query, array((int)$id)); $this->score_event($owner, 'igallery_img_seen', "$user:$id"); } return true; } /** * @param $id * @return bool */ function add_gallery_hit($id) { global $prefs, $user; if ($prefs['count_admin_pvs'] == 'y' || $user != 'admin') { $query = "update `tiki_galleries` set `hits`=`hits`+1 where `galleryId`=?"; $result = $this->query($query, array((int) $id)); } if ($prefs['feature_score'] == 'y') { $this->score_event($user, 'igallery_see', $id); $query = "select `user` from `tiki_galleries` where `galleryId`=?"; $owner = $this->getOne($query, array((int)$id)); $this->score_event($owner, 'igallery_seen', "$user:$id"); } return true; } /** * @param $dst_img * @param $src_img * @param $dst_x * @param $dst_y * @param $src_x * @param $src_y * @param $dst_w * @param $dst_h * @param $src_w * @param $src_h */ function ImageCopyResampleBicubic(&$dst_img, &$src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) { $palsize = ImageColorsTotal($src_img); for ($i = 0; $i < $palsize; $i++) { // get palette. $colors = ImageColorsForIndex($src_img, $i); ImageColorAllocate($dst_img, $colors['red'], $colors['green'], $colors['blue']); } $scaleX = ($src_w - 1) / $dst_w; $scaleY = ($src_h - 1) / $dst_h; $scaleX2 = (int)($scaleX / 2); $scaleY2 = (int)($scaleY / 2); for ($j = $src_y; $j < $dst_h; $j++) { $sY = (int)($j * $scaleY); $y13 = $sY + $scaleY2; for ($i = $src_x; $i < $dst_w; $i++) { $sX = (int)($i * $scaleX); $x34 = $sX + $scaleX2; $color1 = ImageColorsForIndex($src_img, ImageColorAt($src_img, $sX, $y13)); $color2 = ImageColorsForIndex($src_img, ImageColorAt($src_img, $sX, $sY)); $color3 = ImageColorsForIndex($src_img, ImageColorAt($src_img, $x34, $y13)); $color4 = ImageColorsForIndex($src_img, ImageColorAt($src_img, $x34, $sY)); $red = ($color1['red'] + $color2['red'] + $color3['red'] + $color4['red']) / 4; $green = ($color1['green'] + $color2['green'] + $color3['green'] + $color4['green']) / 4; $blue = ($color1['blue'] + $color2['blue'] + $color3['blue'] + $color4['blue']) / 4; ImageSetPixel($dst_img, $i + $dst_x - $src_x, $j + $dst_y - $src_y, ImageColorClosest($dst_img, $red, $green, $blue)); } } } /** * @param bool $overwrite * @return bool */ function store_image_data($overwrite = false) { global $prefs; $size = strlen($this->image); $fhash = ""; if ($prefs['gal_use_db'] != 'y') { // Store data in directory switch ($this->type) { case 't': $ext = ".thumb"; break; case 's': $ext = ".scaled_" . $this->xsize . "x" . $this->ysize; break; case 'b': // for future use $ext = ".backup"; break; default: $ext = ''; } $fhash = $this->path . $ext; //Path+extension @$fw = fopen($prefs['gal_use_dir'] . $fhash, "wb"); if (!$fw) { return false; } fwrite($fw, $this->image); fclose($fw); $data = ''; } $this->filename = $this->xsize . "x" . $this->ysize . "_" . $this->name; // rebuild filename for downloading images // insert data $fn = $this->filename; if ($overwrite) { //overwrites all except the colums of the primary key //if there is no oldxsize, we use xsize if (!isset($this->oldxsize)) { $this->oldxsize = $this->xsize; $this->oldysize = $this->ysize; } $query = "update `tiki_images_data` set `filetype`=?, `filename`=?,`data`=?, `filesize`=?,`xsize`=?, `ysize`=? where `imageId`=? and `type`=? and `xsize`=? and `ysize`=?"; $bindvars = array($this->filetype, $this->filename, ($prefs['gal_use_db'] == 'y') ? $this->image : '', (int)$size, (int)$this->xsize, (int)$this->ysize, (int)$this->imageId, $this->type, (int)$this->oldxsize, (int)$this->oldysize); $result = $this->query($query, $bindvars); } else { $table = $this->table('tiki_images_data')->insertOrUpdate( array( 'xsize' => (int)$this->xsize, 'ysize' => (int)$this->ysize, 'type' => $this->type, 'filesize' => (int)$size, 'filetype' => $this->filetype, 'filename' => $this->filename, 'data' => ($prefs['gal_use_db'] == 'y') ? $this->image : '', ), array( 'imageId' => (int) $this->imageId, ) ); } return true; } /** * @param $imageid * @param $itype * @param $xsize * @param int $ysize * @return bool */ function rebuild_image($imageid, $itype, $xsize, $ysize=0) { global $prefs; $galid = $this->get_gallery_from_image($imageid); if (empty($galid)) return false; if ($ysize == 0) { $ysize = $xsize; } //we don't rebuild original images if ($itype == 'o') return false; //if it is a scaled image, test the gallery settings if ($itype == 's') { $hasscale = false; if ($prefs["preset_galleries_info"] == 'y' && $prefs["scaleSizeGalleries"] > 0) { $scaleinfo = $prefs["scaleSizeGalleries"]; if ((($scaleinfo == $xsize) && ($scaleinfo >= $ysize)) || (($scaleinfo == $ysize) && ($scaleinfo >= $xsize))) { $hasscale = true; $newx = $scaleinfo; $newy = $scaleinfo; } } else { $scaleinfo = $this->get_gallery_scale_info($galid); while (list($num, $sci) = each($scaleinfo)) { if ((($sci['scale'] == $xsize) && ($sci['scale'] >= $ysize)) || (($sci['scale'] == $ysize) && ($sci['scale'] >= $xsize))) { $hasscale = true; $newx = $sci['scale']; $newy = $sci['scale']; } } } if (!$hasscale) { return false; } } // now we can start rebuilding the image //if (!function_exists("ImageCreateFromString")) return false; #get image and other infos $this->get_image($imageid); $galinfo = $this->get_gallery_info($galid); // determine new size if ($itype == 't') { $newx = $galinfo["thumbSizeX"]; $newy = $galinfo["thumbSizeY"]; } // do it if ($this->issupported($this->filetype)) { if (!$this->rescaleImage($newx, $newy)) { die; } } else { // filetype is not supported, but we store the data // assiming newx, newy as new size $this->xsize = $newx; $this->ysize = $newy; } // we always rescale to jpegs. $t_type = 'image/jpeg'; // some more infos $filename = $this->filename; // filename of original image $this->type = $itype; // We only reach this point if rebuild_thumbnails() was run, i.e. there is nothing // in the database - so we need overwrite param to be false to insert into database $this->store_image_data(false); //return new size $newsize["xsize"] = $this->xsize; $newsize["ysize"] = $this->ysize; return $newsize; } /** * @param $galleryId * @return bool */ function rebuild_thumbnails($galleryId) { global $prefs; // rewritten by flo $query = "select `imageId`, `path` from `tiki_images` where `galleryId`=?"; $result = $this->query($query, array((int)$galleryId)); while ($res = $result->fetchRow()) { $query2 = "delete from `tiki_images_data` where `imageId`=? and `type`=?"; $result2 = $this->query($query2, array((int)$res["imageId"], 't')); if (strlen($res["path"]) > 0) { $ftn = $prefs['gal_use_dir'] . $res["path"] . ".thumb"; if (file_exists($ftn)) { unlink($ftn); } } } return true; } /** * @param $galleryId * @param $imageId */ function rebuild_scales($galleryId, $imageId = -1) { // doesn't really rebuild, it deletes the scales and thumbs for // automatic rebuild // give either a galleryId for rebuild complete gallery or // a imageId for a image rebuild global $prefs; if ($imageId == -1) { //gallery mode //mysql does'nt have subqueries. Bad. $bindvars = array(); $query1 = "select `imageId`,`path` from `tiki_images`"; if ($galleryId>-1) { // if galleryid == -1 then all galleries $query1 .= ' where `galleryId`=?'; $bindvars = array((int)$galleryId); } $result1 = $this->query($query1, $bindvars); while ($res = $result1->fetchRow()) { $query2 = 'select `xsize`,`ysize`,`type` from `tiki_images_data` where `imageId`=? and not (`type`=?)'; $query3 = "delete from `tiki_images_data` where `imageId`=? and not (`type`=?)"; $bindvars2 = array((int)$res["imageId"], 'o'); $result2 = $this->query($query2, $bindvars2); while ($res2 = $result2->fetchRow()) { if (!empty($res['path'])) { if ($res2['type']=='s') { $ext = ".scaled_" . $res2['xsize'] . "x" . $res2['ysize']; } if ($res2['type']=='t') { $ext = ".thumb"; } if ($res2['type']=='s' || $res2['type'] == 't') { // in case we add other types later @unlink($prefs['gal_use_dir'] . $res['path'] . $ext); } } } // delete images_data entries $result3 = $this->query($query3, $bindvars2); } } else { //image mode $query = "delete from `tiki_images_data` where `ImageId`=? and not `type`=?"; $result = $this->query($query, array((int)$ImageId, 'o')); } } /** * @param $id * @param $name * @param $description * @param null $lat * @param null $lon * @param null $file * @return bool */ function edit_image($id, $name, $description, $lat=NULL, $lon=NULL, $file=NULL) { global $prefs; $name = strip_tags($name); $description = strip_tags($description); $query = "update `tiki_images` set `name`=?, `description`=?, `lat`=?, `lon`=? where `imageId` = ?"; $result = $this->query($query, array($name, $description, (float)$lat, (float)$lon, (int)$id)); if (!empty($file) && !empty($file['name'])) { if (!is_uploaded_file($file['tmp_name']) || !($fp = fopen($file['tmp_name'], "rb"))) return false; $data = fread($fp, $file['size']); $etag = md5($data); fclose($fp); if ($prefs['gal_use_db'] == 'y') { $query = "update `tiki_images_data` set `data`=?, `etag`=?, `filename`=? where `imageId` = ? and `type`=?"; $result = $this->query($query, array($data, $etag, $file['name'], (int)$id, 'o')); } else { $query = "select `path` from `tiki_images` where `imageId`=?"; $path = $this->getOne($query, $id); if (!move_uploaded_file($file['tmp_name'], $prefs['gal_use_dir'].$path)) { return false; } $query = "update `tiki_images_data` set `etag`=?,`filename`=? where `imageId` = ? and `type`=?"; $result = $this->query($query, array($etag, $file['name'], (int)$id, 'o')); } $query = "delete from `tiki_images_data` where `imageId`=? and `type`!=?"; $result = $this->query($query, array((int)$id, 'o')); } require_once('lib/search/refresh-functions.php'); refresh_index('images', $id); return true; } /** * @param $galleryId * @param $name * @param $description * @param $filename * @param $filetype * @param $data * @param $size * @param $xsize * @param $ysize * @param $user * @param $t_data * @param $t_type * @param null $lat * @param null $lon * @param null $gal_info * @return bool */ function insert_image($galleryId, $name, $description, $filename, $filetype, &$data, $size, $xsize, $ysize, $user, $t_data, $t_type, $lat=NULL, $lon=NULL, $gal_info=NULL) { global $prefs; $name = strip_tags($name); $description = strip_tags($description); if ($t_data && is_string($t_data)) { $t_data = array('data' => $t_data, 'xsize' => 0, 'ysize' => 0); } $path = ''; if ($prefs['gal_use_db'] != 'y') { // Store data in directory $fhash = md5(uniqid($filename)); if (!($fw = fopen($prefs['gal_use_dir'] . $fhash, "wb"))) { return false; } fwrite($fw, $data); fclose($fw); $data = ''; if ($t_data) { if (!($fw = fopen($prefs['gal_use_dir'] . $fhash . '.thumb', "wb"))) { return false; } fwrite($fw, $t_data['data']); fclose($fw); $t_data['data'] = ''; } $path = $fhash; } $query = "insert into `tiki_images`(`galleryId`,`name`,`description`,`user`,`created`,`hits`,`path`,`lat`,`lon`) values(?,?,?,?,?,?,?,?,?)"; $result = $this->query($query, array((int)$galleryId, $name, $description, $user, (int)$this->now, 0, $path, $lat, $lon)); $query = "select max(`imageId`) from `tiki_images` where `created`=?"; $imageId = $this->getOne($query, array((int)$this->now)); // insert data //$this->blob_encode($data); $query = "insert into `tiki_images_data`(`imageId`,`xsize`,`ysize`, `type`,`filesize`,`filetype`,`filename`,`data`) values (?,?,?,?,?,?,?,?)"; $result = $this->query($query, array((int)$imageId, (int)$xsize, (int)$ysize, 'o', (int)$size, $filetype, $filename, $data)); // insert thumb if ($t_data) { //$this->blob_encode($t_data['data']); $query = "insert into `tiki_images_data`(`imageId`,`xsize`,`ysize`, `type`,`filesize`,`filetype`,`filename`,`data`) values (?,?,?,?,?,?,?,?)"; $result = $this->query($query, array((int)$imageId, (int)$t_data['xsize'], (int)$t_data['ysize'], 't', (int)$size, $t_type, $filename, $t_data['data'])); } $query = "update `tiki_galleries` set `lastModif`=? where `galleryId`=?"; $result = $this->query($query, array((int)$this->now, (int)$galleryId)); if ($prefs['feature_score'] == 'y') { $this->score_event($user, 'igallery_new_img'); } if ($prefs['feature_actionlog'] == 'y') { $logslib = TikiLib::lib('logs'); $logslib->add_action('Uploaded', $galleryId, 'image gallery', 'imageId=' . $imageId); } require_once('lib/search/refresh-functions.php'); refresh_index('images', $imageId); $this->notify($imageId, $galleryId, $name, $filename, $description, isset($gal_info['name'])?$gal_info['name']: '', 'upload image', $user); return $imageId; } /** * @param $imageId * @param $galleryId * @param $name * @param $filename * @param $description * @param $galleryName * @param $action * @param $user */ function notify($imageId, $galleryId, $name, $filename, $description, $galleryName, $action, $user) { global $prefs; if ($prefs['feature_user_watches'] == 'y') { $event = 'image_gallery_changed'; $nots = $this->get_event_watches($event, $galleryId); if ($prefs['feature_daily_report_watches'] == 'y') { $reportsManager = Reports_Factory::build('Reports_Manager'); $reportsManager->addToCache($nots, array("event"=>$event, "imageId"=>$imageId, "imageName"=>$name, "fileName"=>$filename, "galleryId"=>$galleryId, "galleryName"=>$galleryName, "action"=>$action, "user"=>$user)); } $smarty = TikiLib::lib('smarty'); include_once('lib/notifications/notificationemaillib.php'); $smarty->assign_by_ref('galleryId', $galleryId); $smarty->assign_by_ref('galleryName', $galleryName); $smarty->assign_by_ref('author', $user); $smarty->assign_by_ref('fname', $name); $smarty->assign_by_ref('filename', $filename); $smarty->assign_by_ref('description', $description); $smarty->assign_by_ref('imageId', $imageId); sendEmailNotification($nots, 'watch', 'user_watch_image_gallery_changed_subject.tpl', NULL, 'user_watch_image_gallery_upload.tpl'); } } /** * @param $id * @param $angle */ function rotate_image($id, $angle) { //get image global $prefs; $this->get_image($id); $this->rotateimage($angle); $this->store_image_data(true); // delete all scaled images. Will be rebuild when requested $query = "delete from `tiki_images_data` where `imageId`=? and `type` !=?"; $result = $this->query($query, array((int)$id, 'o')); } /** * @param $id */ function rotate_right_image($id) { $this->rotate_image($id, 270); } /** * @param $id */ function rotate_left_image($id) { $this->rotate_image($id, 90); } /** * @param $id * @param $user * @return bool */ function remove_image($id, $user) { global $prefs; $path = $this->getOne("select `path` from `tiki_images` where `imageId`=?", array($id)); $imageInfo = $this->get_image_info($id); $gal_info = $this->get_gallery($imageInfo['galleryId']); if ($path) { @unlink($prefs['gal_use_dir'] . $path); @unlink($prefs['gal_use_dir'] . $path . '.thumb'); // remove scaled images $query = "select i.`path`, d.`xsize`, d.`ysize` from `tiki_images` i, `tiki_images_data` d where i.`imageId`=d.`imageId` and i.`imageId`=? and d.`type`=?"; $result=$this->query($query, array($id, 's')); while ($res = $result->fetchRow()) { @unlink($prefs['gal_use_dir'] . $path . '.scaled_' . $res['xsize'] . 'x' . $res['ysize']); } } $query = "delete from `tiki_images` where `imageId`=?"; $result = $this->query($query, array((int)$id)); $query = "delete from `tiki_images_data` where `imageId`=?"; $result = $this->query($query, array((int)$id)); $this->remove_object('image', $id); $this->notify($imageInfo['imageId'], $imageInfo['galleryId'], $imageInfo['name'], $imageInfo['filename'], $imageInfo['description'], isset($gal_info['name'])?$gal_info['name']: '', 'remove image', $user); return true; } /** * @param $offset * @param $maxRecords * @param $sort_mode * @param $find * @param $galleryId * @return array */ function get_images($offset, $maxRecords, $sort_mode, $find, $galleryId = -1) { if ($find) { $findesc = '%' . $find . '%'; $mid = " and (`name` like ? or `description` like ?)"; $bindvars=array($findesc, $findesc); } else { $mid = ""; $bindvars=array(); } if ($galleryId != -1 && is_numeric($galleryId)) { $mid .= " and i.`galleryId`=? "; $bindvars[]=(int) $galleryId; } else if ($galleryId == -1) {//don't show system gallery $mid .= 'and i.`galleryId`!=? '; $bindvars[] = 0; } $query_cant = "select count(*) from `tiki_images` i where 1 $mid"; $cant = $this->getOne($query_cant, $bindvars); $query = "select i.`path`, i.`imageId`, i.`name`, i.`description`, i.`created`, d.`filename`, d.`filesize`, d.`xsize`, d.`ysize`, i.`user`, i.`hits` from `tiki_images` i, `tiki_images_data` d where i.`imageId`=d.`imageId` $mid and d.`type`=? order by " . $this->convertSortMode($sort_mode); $bindvars[] = 'o'; $result = $this->query($query, $bindvars, $maxRecords, $offset); $ret = array(); while ($res = $result->fetchRow()) { $ret[] = $res; } $retval = array(); $retval["data"] = $ret; $retval["cant"] = $cant; return $retval; } /** * @param $offset * @param $maxRecords * @param $sort_mode * @param $find * @param $galleryId * @return array */ function get_subgalleries($offset, $maxRecords, $sort_mode, $find, $galleryId = -1) { if ($sort_mode == '') { $sort_mode = 'name_asc'; } else { //filesize is for listing images. equivalent is images $sort_mode = preg_replace('/(filesize_)/', 'images_', $sort_mode); } if ($find) { $findesc = '%' . $find . '%'; $mid = " and (`name` like ? or `description` like ?)"; $bindvars=array($galleryId, $findesc, $findesc); } else { $mid = ""; $bindvars=array($galleryId); } $query = "select g.`galleryId`,g.`name`,g.`description`, g.`created`,g.`lastModif`,g.`visible`,g.`theme`,g.`user`, g.`hits`,g.`maxRows`,g.`rowImages`,g.`thumbSizeX`, g.`thumbSizeY`,g.`public`,g.`sortorder`,g.`sortdirection`, g.`galleryimage`,g.`parentgallery`,count(i.`imageId`) as images from `tiki_galleries` g, `tiki_images` i where i.`galleryId`=g.`galleryId` and `parentgallery`=? $mid group by g.`galleryId`, g.`name`,g.`description`, g.`created`,g.`lastModif`,g.`visible`,g.`theme`,g.`user`, g.`hits`,g.`maxRows`,g.`rowImages`,g.`thumbSizeX`, g.`thumbSizeY`,g.`public`,g.`sortorder`,g.`sortdirection`, g.`galleryimage`,g.`parentgallery` order by ". $this->convertSortMode($sort_mode); $result = $this->query($query, $bindvars, $maxRecords, $offset); $ret = array(); while ($res = $result->fetchRow()) { // get the number of the gallery representation image $res['imageId']=$this->get_gallery_image($res['galleryId'], $res['galleryimage']); $ret[] = $res; } $retval = array(); $retval["data"] = $ret; $query_cant = "select count(*) from `tiki_galleries` where `parentgallery`=? $mid"; $cant = $this->getOne($query_cant, $bindvars); $retval["cant"] = $cant; return $retval; } /** * @param $galleryId * @param string $rule * @param string $sort_mode * @return mixed */ function get_gallery_image($galleryId, $rule='', $sort_mode = '') { $query = 'select i.`imageId` from `tiki_images` i, `tiki_images_data` d where i.`imageId`=d.`imageId` and i.`galleryId`=? and d.`type`=? order by '; /* if sort by filesize while browsing images it needs to be read from tiki_image_data table */ if ($sort_mode == 'filesize_asc' || $sort_mode == 'filesize_desc') { $query .= 'd.'; } else { $query .= 'i.'; } $bindvars = array($galleryId, 'o'); switch($rule) { case 'firstu': // first uploaded $query .= $this->convertSortMode('created_asc'); $imageId = $this->getOne($query, $bindvars); break; case 'lastu': // last uploaded $query .= $this->convertSortMode('created_desc'); $imageId = $this->getOne($query, $bindvars); break; case 'all': case 'first': if (!$sort_mode) { // first image in default gallery sortorder $query2 = 'select `sortorder`,`sortdirection` from `tiki_galleries` where `galleryId`=?'; $result = $this->query($query2, array($galleryId)); $res = $result->fetchRow(); $sort_mode = $res['sortorder'] . '_' . $res['sortdirection']; } $query .= $this->convertSortMode($sort_mode); if ($rule != 'all') { $imageId = $this->getOne($query, $bindvars); break; } $result = $this->query($query, $bindvars); $imageId = array(); while ($res = $result->fetchRow()) { $imageId[] = reset($res); } break; case 'last': if ($sort_mode) { $invsor = explode('_', $sort_mode); $sort_mode = $invsor[0] . '_' . ($invsor[1] == 'asc' ? 'desc' : 'asc'); } else { // last image in default gallery sortorder $query2 = 'select `sortorder`,`sortdirection` from `tiki_galleries` where `galleryId`=?'; $result = $this->query($query2, $bindvars); $res = $result->fetchRow(); if ($res['sortdirection'] == 'asc') { $res['sortdirection']='desc'; } else { $res['sortdirection']='asc'; } $sort_mode = $res['sortorder'] . '_' . $res['sortdirection']; } $query .= $this->convertSortMode($sort_mode); $imageId = $this->getOne($query, $bindvars); break; case 'random': //random image of gallery $ret = $this->get_random_image($galleryId); $imageId = $ret['imageId']; break; case 'default': //check gallery settings and re-run this function $query = 'select `galleryimage` from `tiki_galleries` where `galleryId`=?'; $rule = $this->getOne($query, array($galleryId)); $imageId = $this->get_gallery_image($galleryId, $rule); break; default: // imageId is listed in gallery settings if (is_numeric($rule)) { $imageId = (int) $rule; } else { // unknown. $imageId = -1; } break; } return($imageId); } /** * @param $sort_mode * @param $find * @param $imageId * @param $galleryId * @return array */ function get_prev_and_next_image($sort_mode, $find, $imageId, $galleryId = -1) { if ($find) { $findesc = '%' . $find . '%'; $mid = " and (`name` like ? or `description` like ?)"; $bindvars = array('o', $findesc, $findesc); } else { $mid = ""; $bindvars = array('o'); } $midcant = ""; $cantvars = array(); if ($galleryId != -1 && is_numeric($galleryId)) { $mid .= " and i.`galleryId`=? "; $bindvars[] = (int)$galleryId; $midcant = "where `galleryId`=? "; $cantvars[] = (int)$galleryId; } $query = "select i.`imageId` from `tiki_images` i, `tiki_images_data` d where i.`imageId`=d.`imageId` and d.`type`=? $mid order by "; /* if sort by filesize while browsing images it needs to be read from tiki_image_data table */ if ($sort_mode == 'filesize_asc' || $sort_mode == 'filesize_desc') { $query .= 'd.'; } else { $query .= 'i.'; } $query .= $this->convertSortMode($sort_mode); $result = $this->query($query, $bindvars); $prev = -1; $next = 0; $tmpid = 0; while ($res = $result->fetchRow()) { if ($imageId == $res['imageId']) { $prev = $tmpid; } else if ($prev >= 0) { // $prev is set, so, this one is the next $next = $res['imageId']; break; } $tmpid = $res['imageId']; } return array('prev' => ($prev > 0 ? $prev : 0), 'next' => $next); } /** * @param $sort_mode * @param $find * @param $galleryId * @return mixed */ function get_first_image($sort_mode, $find, $galleryId = -1) { if ($find) { $findesc = '%' . $find . '%'; $mid = " and (`name` like ? or `description` like ?)"; $bindvars=array('o', $findesc, $findesc); } else { $mid = ""; $bindvars = array('o'); } $midcant = ""; $cantvars = array(); if ($galleryId != -1 && is_numeric($galleryId)) { $mid .= " and i.`galleryId`=? "; $bindvars[] = (int)$galleryId; $midcant = "where `galleryId`=? "; $cantvars[] = (int)$galleryId; } $query = "select i.`imageId` from `tiki_images` i, `tiki_images_data` d where i.`imageId`=d.`imageId` and d.`type`=? $mid order by " . $this->convertSortMode($sort_mode); $result = $this->query($query, $bindvars, 1, 0); $res = $result->fetchRow(); return $res['imageId']; } /** * @param $sort_mode * @param $find * @param $galleryId * @return mixed */ function get_last_image($sort_mode, $find, $galleryId = -1) { if (strstr($sort_mode, 'asc')) { $sort_mode = str_replace('asc', 'desc', $sort_mode); } else { $sort_mode = str_replace('desc', 'asc', $sort_mode); } if ($find) { $findesc = '%' . $find . '%'; $mid = " and (`name` like ? or `description` like ?)"; $bindvars = array('o', $findesc, $findesc); } else { $mid = ""; $bindvars = array('o'); } $midcant = ""; $cantvars = array(); if ($galleryId != -1 && is_numeric($galleryId)) { $mid .= " and i.`galleryId`=? "; $bindvars[]=(int)$galleryId; $midcant = "where `galleryId`=? "; $cantvars[] = (int)$galleryId; } $query = "select i.`imageId` from `tiki_images` i, `tiki_images_data` d where i.`imageId`=d.`imageId` and d.`type`=? $mid order by ".$this->convertSortMode($sort_mode); $result = $this->query($query, $bindvars, 1, 0); $res = $result->fetchRow(); return $res['imageId']; } /** * @param $offset * @param $maxRecords * @param $sort_mode * @param $find * @param $galleryId * @return array */ function list_images($offset, $maxRecords, $sort_mode, $find, $galleryId = -1) { return $this->get_images($offset, $maxRecords, $sort_mode, $find, $galleryId); } /** * @param $galleryId * @return array */ function get_random_image($galleryId = -1) { $whgal = ""; $bindvars = array(); if (((int)$galleryId) != -1) { $whgal = " where `galleryId`=? "; $bindvars[] = (int) $galleryId; } $query = "select count(*) from `tiki_images` $whgal"; $cant = $this->getOne($query, $bindvars); $ret = array(); if ($cant) { $pick = rand(0, $cant - 1); $query = "select `imageId`, `description`, `galleryId`, `name` from `tiki_images` $whgal"; $result = $this->query($query, $bindvars, 1, $pick); $res = $result->fetchRow(); $ret["galleryId"] = $res["galleryId"]; $ret["imageId"] = $res["imageId"]; $ret["name"] = $res["name"]; $ret["description"] = $res["description"]; $query = "select `name` from `tiki_galleries` where `galleryId` = ?"; $ret["gallery"] = $this->getOne($query, array((int)$res["galleryId"])); } else { $ret["galleryId"] = 0; $ret["imageId"] = 0; $ret["name"] = tra("No image yet, sorry."); } return ($ret); } /** * @param int $offset * @param $maxRecords * @param string $sort_mode * @param string $user * @param null $find * @return array */ function list_galleries($offset = 0, $maxRecords = -1, $sort_mode = 'name_desc', $user = '', $find = null) { // If $user is admin then get ALL galleries, if not only user galleries are shown global $tiki_p_admin_galleries, $tiki_p_admin; $old_sort_mode = ''; if (in_array($sort_mode, array('images_desc', 'images_asc'))) { $old_offset = $offset; $old_maxRecords = $maxRecords; $old_sort_mode = $sort_mode; $sort_mode = 'name_desc'; $offset = 0; $maxRecords = -1; } // If the user is not admin then select `it` 's own galleries or public galleries if (($tiki_p_admin_galleries == 'y') or ($tiki_p_admin == 'y') or ($user == 'admin')) { $whuser = ""; $bindvars = array(); } else { $whuser = "where g.`user`=? or g.public=?"; $bindvars = array($user, 'y'); } if ($find) { $findesc = '%' . $find . '%'; if (empty($whuser)) { $whuser = "where g.`name` like ? or g.`description` like ?"; $bindvars = array($findesc,$findesc); } else { $whuser .= " and g.`name` like ? or g.`description` like ?"; $bindvars[] = $findesc; $bindvars[] = $findesc; } } // If sort mode is versions then offset is 0, maxRecords is -1 (again) and sort_mode is nil // If sort mode is links then offset is 0, maxRecords is -1 (again) and sort_mode is nil // If sort mode is backlinks then offset is 0, maxRecords is -1 (again) and sort_mode is nil $query = "select g.*, a.`name` as parentgalleryName from `tiki_galleries` g left join `tiki_galleries` a on g.`parentgallery` = a.`galleryId` $whuser order by " . $this->convertSortMode($sort_mode); $query_cant = "select count(*) from `tiki_galleries` g $whuser"; $result = $this->query($query, $bindvars, $maxRecords, $offset); $cant = $this->getOne($query_cant, $bindvars); $ret = array(); global $prefs, $user, $tiki_p_admin; $userlib = TikiLib::lib('user'); while ($res = $result->fetchRow()) { $res['perms'] = $this->get_perm_object($res['galleryId'], 'image gallery', $res, false); if ($res['perms']['tiki_p_view_image_gallery'] == 'y') { $res['images'] = $this->getOne("select count(*) from `tiki_images` where `galleryId`=?", array($res['galleryId'])); $ret[] = $res; } } if ($old_sort_mode == 'images_asc') { usort($ret, 'compare_images'); } if ($old_sort_mode == 'images_desc') { usort($ret, 'r_compare_images'); } if (in_array($old_sort_mode, array('images_desc', 'images_asc'))) { $ret = array_slice($ret, $old_offset, $old_maxRecords); } $retval = array(); $retval["data"] = $ret; $retval["cant"] = $cant; return $retval; } /** * @param int $offset * @param $maxRecords * @param string $sort_mode * @param $user * @param $find * @return array */ function list_visible_galleries($offset = 0, $maxRecords = -1, $sort_mode = 'name_desc', $user, $find) { global $tiki_p_admin_galleries, $tikilib; // If $user is admin then get ALL galleries, if not only user galleries are shown $old_sort_mode = ''; if (in_array($sort_mode, array('images desc', 'images asc'))) { $old_offset = $offset; $old_maxRecords = $maxRecords; $old_sort_mode = $sort_mode; $sort_mode = 'user desc'; $offset = 0; $maxRecords = -1; } $whuser = ""; $bindvars=array('y'); if ($find) { $findesc = '%' . $find . '%'; if (empty($whuser)) { $whuser = " and (`name` like ? or `description` like ?)"; $bindvars = array('y', $findesc, $findesc); } else { $whuser .= " and (`name` like ? or `description` like ?)"; $bindvars[]=$findesc; $bindvars[]=$findesc; } } // If sort mode is versions then offset is 0, maxRecords is -1 (again) and sort_mode is nil // If sort mode is links then offset is 0, maxRecords is -1 (again) and sort_mode is nil // If sort mode is backlinks then offset is 0, maxRecords is -1 (again) and sort_mode is nil $query = "select * from `tiki_galleries` where `visible`=? $whuser order by ".$this->convertSortMode($sort_mode); $query_cant = "select count(*) from `tiki_galleries` where `visible`=? $whuser"; $result = $this->query($query, $bindvars, $maxRecords, $offset); $cant = $this->getOne($query_cant, $bindvars); $ret = array(); while ($res = $result->fetchRow()) { if (!$tikilib->user_has_perm_on_object($user, $res['galleryId'], 'image gallery', 'tiki_p_view_image_gallery')) { continue; } $aux = array(); $aux["name"] = $res["name"]; $gid = $res["galleryId"]; $aux["visible"] = $res["visible"]; $aux["id"] = $gid; $aux["galleryId"] = $res["galleryId"]; $aux["description"] = $res["description"]; $aux["created"] = $res["created"]; $aux["lastModif"] = $res["lastModif"]; $aux["user"] = $res["user"]; $aux["hits"] = $res["hits"]; $aux["public"] = $res["public"]; $aux["theme"] = $res["theme"]; $aux["geographic"] = $res["geographic"]; $aux["images"] = $this->getOne("select count(*) from `tiki_images` where `galleryId`=?", array($gid)); $ret[] = $aux; } if ($old_sort_mode == 'images asc') { usort($ret, 'compare_images'); } if ($old_sort_mode == 'images desc') { usort($ret, 'r_compare_images'); } if (in_array($old_sort_mode, array('images desc', 'images asc'))) { $ret = array_slice($ret, $old_offset, $old_maxRecords); } $retval = array(); $retval["data"] = $ret; $retval["cant"] = $cant; return $retval; } /** * @param $id * @return mixed */ function get_gallery($id) { $query = "select * from `tiki_galleries` where `galleryId`=?"; $result = $this->query($query, array((int) $id)); $res = $result->fetchRow(); return $res; } /** * @param $galleryId * @return mixed */ function get_gallery_owner($galleryId) { $query = "select `user` from `tiki_galleries` where `galleryId`=?"; $user = $this->getOne($query, array((int)$galleryId)); return $user; } /** * @param $imageid * @return mixed */ function get_gallery_from_image($imageid) { $query = "select `galleryId` from `tiki_images` where `imageId`=?"; $galid = $this->getOne($query, array((int)$imageid)); return $galid; } /** * @param $imgId * @param $galId * @return bool */ function move_image($imgId, $galId) { $query = "update `tiki_images` set `galleryId`=? where `imageId`=?"; $result = $this->query($query, array((int)$galId, (int)$imgId)); return true; } /** * @param $id * @param string $itype * @param int $xsize * @param int $ysize * @return mixed */ function get_image_info($id, $itype = 'o', $xsize = 0, $ysize = 0) { // code may be merged with get_image $mid = ""; if ($xsize != 0 && $ysize == 0) { // bounding box $ysize = $xsize; } if ($xsize != 0 && $ysize != 0) { $bindvars = array((int)$id, $itype, (int)$xsize, (int)$ysize); if ($xsize == $ysize) { // we don't know yet. $mid = "and (d.`xsize` = ? or d.`ysize` = ?) order by `xysize` desc"; } else { $mid = 'and d.`xsize` = ? and d.`ysize` = ?'; } } if (!isset($bindvars) || !is_array($bindvars)) { $bindvars = array((int)$id, $itype); } $query = "select i.`imageId`, i.`galleryId`, i.`name`, i.`description`, i.`created`, i.`user`, i.`hits`, i.`path`, i.`lat`, i.`lon`, d.`xsize`,d.`ysize`,d.`type`,d.`filesize`, d.`filetype`,d.`filename`,d.`xsize` * d.`ysize` as `xysize` from `tiki_images` i, `tiki_images_data` d where i.`imageId`=? and d.`imageId`=i.`imageId` and d.`type`=? $mid"; $result = $this->query($query, $bindvars, 1); $res = $result->fetchRow(); return $res; } // Add an option to establish Image size (x, y) /** * @param $id * @param string $itype * @param int $xsize * @param int $ysize * @return mixed */ function get_image($id, $itype = 'o', $xsize = 0, $ysize = 0) { global $prefs; $mid = ""; if ($itype == 't') { $galid = $this->get_gallery_from_image($id); $galinfo = $this->get_gallery_info($galid); $xsize = $galinfo["thumbSizeX"]; $ysize = $galinfo["thumbSizeY"]; } if ($xsize != 0 && $ysize == 0) { // first parameter (xsize) represents a scale // so we select a bounding box $ysize = $xsize; } if ($xsize != 0 && $ysize != 0) { if ($ysize == $xsize) { // we don't know yet. $mid = "and (d.`xsize`=? or d.`ysize`=?) order by `xysize` desc "; $bindvars = array((int)$id, $itype, (int)$xsize, (int)$ysize); } else { //exact match $mid = "and d.`xsize`=? and d.`ysize`=? "; $bindvars = array((int)$id, $itype, (int)$xsize, (int)$ysize); } } if (!isset($bindvars) || !is_array($bindvars)) { $bindvars = array((int)$id, $itype); } $query = "select i.`imageId`, i.`galleryId`, i.`name`, i.`description`, i.`created`, i.`user`, i.`hits`, i.`path`,i.`lat`, i.`lon`, d.`xsize`,d.`ysize`,d.`type`,d.`filesize`, d.`filetype`,d.`filename`,d.`data`, d.`xsize` * d.`ysize` as `xysize`, d.`etag` from `tiki_images` i, `tiki_images_data` d where i.`imageId`=? and d.`imageId`=i.`imageId` and d.`type`=? $mid"; $result = $this->query($query, $bindvars, 1); if ($result===false || $result===null) { die; } $res = $result->fetchRow(); $this->imageId = $res["imageId"]; $this->galleryId = $res["galleryId"]; $this->name = $res["name"]; $this->description = $res["description"]; $this->lat = $res["lat"]; $this->lon = $res["lon"]; $this->created = $res["created"]; $this->user = $res["user"]; $this->hits = $res["hits"]; $this->path = $res["path"]; $this->xsize = $res["xsize"]; $this->ysize = $res["ysize"]; $this->type = $res["type"]; $this->filesize = $res["filesize"]; $this->filetype = $res["filetype"]; $this->filename = $res["filename"]; $this->etag= $res["etag"]; # build scaled images or thumb if not available if ($itype != 'o' && !isset($this->imageId)) { if ($newsize = $this->rebuild_image($id, $itype, $xsize, $ysize)) { // removed because this causes endless recursion //return $this->get_image($id, $itype, $newsize["xsize"], $newsize["ysize"]); // Since the rescaled image is the one we want, we have to switch to its path and data $res['path'] = $this->path; $res['data'] = $this->image; } } // get image data from fs if (strlen($res["data"]) < 3) { // this is needed by postgres, because it inserts '' in the data field switch ($itype) { case 't': $ext = ".thumb"; break; case 's': $ext = ".scaled_" . $res["xsize"] . "x" . $res["ysize"]; break; case 'b': // for future use $ext = ".backup"; break; default: $ext = ''; } // If the image was a .gif then the thumbnail has 0 bytes if the thumbnail // is empty then use the full image as thumbnail // if ($ext==".thumb" && filesize($prefs['gal_use_dir'].$res["path"].$ext)==0 ) { // $ext=''; //} $this->readimagefromfile($prefs['gal_use_dir'] . $res["path"] . $ext); } else { $this->image = $res["data"]; } if (!isset($this->imagehandle)) $this->readimagefromstring(); // etag checks if ($this->etag=='') { $this->add_etag(); } return $res; } function add_etag() { // stores md5 based etag in the tables // this function assumes that the $this->imageId and other // are loaded before (through $this->get_image() or similar) if (isset($this->image)) {//avoid broken images through warning $etag = md5($this->image); $query = 'update `tiki_images_data` set `etag`=? where `imageId`=? and `xsize`=? and `ysize`=? and `type`=?'; $bindvars = array($etag, (int) $this->imageId, (int) $this->xsize, (int) $this->ysize, $this->type); $this->query($query, $bindvars); } } /** * @param $id * @param string $itype * @param int $xsize * @param int $ysize * @return bool */ function get_etag($id, $itype = 'o', $xsize = 0, $ysize = 0) { // used to get the etag of a image. This function can be called // before we load the image into memory to check if the browser // has the image cached. $mid = ""; if ($itype == 't') { $galid = $this->get_gallery_from_image($id); $galinfo = $this->get_gallery_info($galid); $xsize = $galinfo["thumbSizeX"]; $ysize = $galinfo["thumbSizeY"]; } if ($xsize != 0 && $ysize == 0) { // first parameter (xsize) represents a scale // so we select a bounding box $ysize=$xsize; } if ($xsize != 0 && $ysize != 0) { if ($ysize == $xsize) { // we don't know yet. $mid = "and (d.`xsize`=? or d.`ysize`=?) order by `xysize` desc "; $bindvars = array((int)$id, $itype, (int)$xsize, (int)$ysize); } else { //exact match $mid = "and d.`xsize`=? and d.`ysize`=? "; $bindvars = array((int)$id, $itype, (int)$xsize, (int)$ysize); } } if (!@is_array($bindvars)) { $bindvars = array((int)$id, $itype); } $query = "select d.`xsize` * d.`ysize` as `xysize`, d.`etag` from `tiki_images_data` d where d.`imageId`=? and d.`type`=? $mid"; $result = $this->query($query, $bindvars, 1); if ($result===false || $result===null) { return(false); } $res = $result->fetchRow(); $this->etag = $res["etag"]; return($res["etag"]); } /** * @param $name * @param int $galleryId * @return mixed */ function get_imageid_byname($name, $galleryId=0) { $bindvars=array($name); $query = "select `imageId` from `tiki_images` where `name` like ?"; if (!empty($galleryId)) { $query .= ' and galleryId=?'; $bindvars[] = $galleryId; } $result = $this->query($query, $bindvars, 1); $res = $result->fetchRow(); return($res["imageId"]); } /** * @param $id * @return mixed */ function get_image_thumb($id) { return $this->get_image($id, 't'); } /** * @param $galleryId * @param $name * @param $description * @param $theme * @param $user * @param $maxRows * @param $rowImages * @param $thumbSizeX * @param $thumbSizeY * @param $public * @param string $visible * @param string $sortorder * @param string $sortdirection * @param string $galleryimage * @param $parentgallery * @param string $showname * @param string $showimageid * @param string $showdescription * @param string $showcreated * @param string $showuser * @param string $showhits * @param string $showxysize * @param string $showfilesize * @param string $showfilename * @param string $defaultscale * @param string $geographic * @param string $showcategories * @return mixed */ function replace_gallery( $galleryId, $name, $description, $theme, $user, $maxRows, $rowImages, $thumbSizeX, $thumbSizeY, $public, $visible = 'y', $sortorder = 'created', $sortdirection = 'desc', $galleryimage = 'first', $parentgallery = -1, $showname = 'y', $showimageid = 'n', $showdescription = 'n', $showcreated = 'n', $showuser = 'n', $showhits = 'y', $showxysize = 'y', $showfilesize = 'n', $showfilename = 'n', $defaultscale = 'o', $geographic = 'n', $showcategories = 'n' ) { global $prefs; // if the user is admin or the user is the same user and the gallery exists then replace if not then // create the gallary if the name is unused. $name = strip_tags($name); $description = strip_tags($description); // check if the gallery already exists. if yes: do update, if no: update it if ($galleryId < 1) $galleryId = $this->getOne("select `galleryId` from `tiki_galleries` where `name`=? and `parentgallery`=?", array($name, $parentgallery)); if ($galleryId > 0) { $query = "update `tiki_galleries` set `name`=?,`visible`=?, `geographic`=?,`maxRows`=? , `rowImages`=?, `thumbSizeX`=?, `thumbSizeY`=?, `description`=?, `theme`=?, `lastModif`=?, `public`=?, `sortorder`=?, `sortdirection`=?, `galleryimage`=?, `parentgallery`=?,`showname`=?,`showimageid`=?,`showdescription`=?,`showcategories`=?, `showcreated`=?,`showuser`=?,`showhits`=?,`showxysize`=?,`showfilesize`=?, `showfilename`=?,`defaultscale`=?, `user`=? where `galleryId`=?"; $result = $this->query( $query, array( $name, $visible, $geographic, (int)$maxRows, (int)$rowImages, (int)$thumbSizeX, (int)$thumbSizeY, $description, $theme, (int)$this->now, $public, $sortorder, $sortdirection, $galleryimage, (int)$parentgallery, $showname, $showimageid, $showdescription, $showcategories, $showcreated, $showuser, $showhits, $showxysize, $showfilesize, $showfilename, $defaultscale, $user, (int)$galleryId ) ); } else { // Create a new record $query = "insert into `tiki_galleries`(`name`,`description`,`theme`,`created`,`user`,`lastModif`,`maxRows`,`rowImages`,`thumbSizeX`,`thumbSizeY`,`public`,`hits`,`visible`,`sortorder`,`sortdirection`,`galleryimage`,`parentgallery`,`showname`,`showimageid`,`showdescription`,`showcategories`,`showcreated`,`showuser`,`showhits`,`showxysize`,`showfilesize`,`showfilename`,`defaultscale`,`geographic`) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; $bindvars = array( $name, $description, $theme, (int) $this->now, $user, (int) $this->now, (int) $maxRows, (int) $rowImages, (int) $thumbSizeX, (int) $thumbSizeY, $public, 0, $visible, $sortorder, $sortdirection, $galleryimage, (int) $parentgallery, $showname, $showimageid, $showdescription, $showcategories, $showcreated, $showuser, $showhits, $showxysize, $showfilesize, $showfilename, $defaultscale, $geographic ); $result = $this->query($query, $bindvars); $galleryId = $this->getOne("select max(`galleryId`) from `tiki_galleries` where `name`=? and `created`=?", array($name, (int) $this->now)); if ($prefs['feature_score'] == 'y') { $this->score_event($user, 'igallery_new'); } } require_once('lib/search/refresh-functions.php'); refresh_index('galleries', $galleryId); return $galleryId; } /** * @param $galleryId * @param $scale */ function add_gallery_scale($galleryId, $scale) { $old_scale = $this->getOne("select scale from tiki_galleries_scales where galleryId = ? AND scale = ?", array((int)$galleryId, (int)$scale)); if ($scale != $old_scale) { $query = "insert into `tiki_galleries_scales`(`galleryId`,`scale`) values(?,?)"; $result = $this->query($query, array((int)$galleryId, (int)$scale)); } } /** * @param $galleryId * @param int $scale */ function remove_gallery_scale($galleryId, $scale= 0) { $mid = ""; $bindvars = array((int) $galleryId); if ($scale != 0) { $mid = " and `scale`=? "; $bindvars[]=(int) $scale; } $query = "delete from `tiki_galleries_scales` where `galleryId`=? $mid"; $result = $this->query($query, $bindvars); } /** * @param $id * @return bool */ function remove_gallery($id) { global $prefs; $query = "select `imageId`, path from `tiki_images` where `galleryId`=?"; $result = $this->query($query, array((int) $id)); while ($res = $result->fetchRow()) { $path = $res["path"]; $query2 = "select `xsize`,`ysize`,`type` from `tiki_images_data` where `imageId`=?"; $result2 = $this->query($query2, array((int)$res["imageId"])); while ($res2 = $result2->fetchRow()) { switch ($res2["type"]) { case 't': $ext = ".thumb"; break; case 's': $ext = ".scaled_" . $res2["xsize"] . "x" . $res2["ysize"]; break; case 'b': // for future use $ext = ".backup"; break; default: $ext = ''; } if ($path) { @unlink($prefs['gal_use_dir'] . $path . $ext); } } $query3 = "delete from `tiki_images_data` where `imageId`=?"; $result3 = $this->query($query3, array((int)$res["imageId"])); $this->remove_object('image', $res["imageId"]); } $query = "delete from `tiki_galleries` where `galleryId`=?"; $result = $this->query($query, array((int) $id)); $query = "delete from `tiki_images` where `galleryId`=?"; $result = $this->query($query, array((int) $id)); $this->remove_gallery_scale($id); $this->remove_object('image gallery', $id); return true; } /** * @param $id * @return mixed */ function get_gallery_info($id) { // alias for get_gallery return $this->get_gallery($id); } /** * @param $id * @return array */ function get_gallery_scale_info($id) { $query = "select * from `tiki_galleries_scales` where `galleryId`=? order by `scale` asc"; $result = $this->query($query, array((int) $id)); $resa = array(); while ($res = $result->fetchRow()) { $resa[] = $res; } return $resa; } /** * @param $id * @param int $scale * @return mixed */ function get_gallery_next_scale($id, $scale= 0) { $query = "select * from `tiki_galleries_scales` where `galleryId`=? and `scale` > ? order by `scale` asc"; $result = $this->query($query, array((int) $id, (int) $scale)); $res = $result->fetchRow(); return $res; } /** * @param $id * @return mixed */ function get_gallery_default_scale($id) { $query = "select `defaultscale` from `tiki_galleries` where `galleryId`=?"; $ret=$this->getOne($query, array((int) $id)); return $ret; } /** * @param $id * @param $currentscale * @return array */ function get_gallery_prevnext_scale($id, $currentscale) { $ret=array(); $bindvars=array((int) $id, (int) $currentscale); $query = 'select `scale` from `tiki_galleries_scales` where `galleryId`=? '; $query2 =$query.'and `scale`>? order by `scale` asc'; $ret['nextscale']=$this->getOne($query2, $bindvars); $query2 =$query.'and `scale`<? order by `scale` desc'; $ret['prevscale']=$this->getOne($query2, $bindvars); if ($ret['nextscale']) { $ret['nexttype']='s'; } else { $ret['nexttype']='o'; } if ($ret['prevscale']) { $ret['prevtype']='s'; } else { $ret['prevtype']='o'; } return($ret); } //Capture Images from wiki, blogs, .... /** * @param $data * @return mixed */ function capture_images($data) { global $prefs, $tikilib; if ($prefs['cacheimages'] != 'y') return $data; preg_match_all("/src=\"([^\"]+)\"/", $data, $reqs1); preg_match_all("/src=\'([^\']+)\'/", $data, $reqs2); preg_match_all("/src=([A-Za-z0-9\:\?\=\/\\\.\-\_]+)\}/", $data, $reqs3); preg_match_all("/src=([A-Za-z0-9\:\?\=\/\\\.\-\_]+) /", $data, $reqs4); $merge = array_merge($reqs1[1], $reqs2[1], $reqs3[1], $reqs4[1]); $merge = array_unique($merge); //print_r($merge); // Now for each element in the array capture the image and // if the capture was successful then change the reference to the // internal image $page_data = $data; foreach ($merge as $img) { // This prevents caching images if (!strstr($img, "img/wiki_up") && !strstr($img, "show_image.php") && !strstr($img, "nocache") && @getimagesize($img)) { //print("Procesando: $img<br />"); @$fp = fopen($img, "r"); if ($fp) { $data = ''; while (!feof($fp)) { $data .= fread($fp, 4096); } //print("Imagen leida:".strlen($data)." bytes<br />"); fclose($fp); if (strlen($data) > 0) { $url_info = parse_url($img); $pinfo = pathinfo($url_info["path"]); $type = "image/" . $pinfo["extension"]; $name = $pinfo["basename"]; $size = strlen($data); $url = $img; if (function_exists("ImageCreateFromString") && (!strstr($type, "gif"))) { $img = imagecreatefromstring($data); $size_x = imagesx($img); $size_y = imagesy($img); // Fix the ratio values for system gallery $gal_info["thumbSizeX"] = 90; $gal_info["thumbSizeY"] = 90; if ($size_x > $size_y) $tscale = ((int)$size_x / $gal_info["thumbSizeX"]); else $tscale = ((int)$size_y / $gal_info["thumbSizeY"]); $tw = ((int)($size_x / $tscale)); $ty = ((int)($size_y / $tscale)); if (chkgd2()) { $t = imagecreatetruecolor($tw, $ty); imagecopyresampled($t, $img, 0, 0, 0, 0, $tw, $ty, $size_x, $size_y); } else { $t = imagecreate($tw, $ty); $this->ImageCopyResampleBicubic($t, $img, 0, 0, 0, 0, $tw, $ty, $size_x, $size_y); } // CHECK IF THIS TEMP IS WRITEABLE OR CHANGE THE PATH TO A WRITEABLE DIRECTORY //$tmpfname = 'temp.jpg'; //$tmpfname = tempnam("/tmp", "img"); $tmpfname = tempnam($prefs['tmpDir'], "img"); imagejpeg($t, $tmpfname); // Now read the information $fp = fopen($tmpfname, "rb"); $t_data = fread($fp, filesize($tmpfname)); fclose($fp); unlink($tmpfname); $t_pinfo = pathinfo($tmpfname); $t_type = $t_pinfo["extension"]; $t_type = 'image/' . $t_type; $imageId = $this->insert_image(0, '', '', $name, $type, $data, $size, $size_x, $size_y, 'admin', $t_data, $t_type, NULL, NULL, $gal_info); //print("Imagen generada en $imageId<br />"); } else { //print("No GD detected generating image without thumbnail<br />"); $imageId = $this->insert_image(0, '', '', $name, $type, $data, $size, 100, 100, 'admin', '', '', NULL, NULL, $gal_info); //print("Imagen en $imageId<br />"); } // Now change it! //print("Changing $url to imageId: $imageId"); $uri = parse_url($_SERVER["REQUEST_URI"]); $path = str_replace("tiki-editpage", "show_image", $uri["path"]); $path = str_replace("tiki-edit_article", "show_image", $path); $page_data = str_replace($url, $tikilib->httpPrefix(true). $path . '?id=' . $imageId, $page_data); } // if strlen } // if $fp } } // foreach return $page_data; } /** * @param $userfile * @param int $galleryId * @param string $name * @param string $description * @param string $gal_info * @return array */ function get_one_image_from_disk($userfile, $galleryId=0, $name='', $description='', $gal_info='') { global $prefs, $user; $ret = array(); if (is_uploaded_file($_FILES[$userfile]['tmp_name'])) { $file_name = $_FILES[$userfile]['name']; $ret['filename'] = $file_name; if (!empty($prefs['gal_match_regex']) && !preg_match('/'.$prefs['gal_match_regex'].'/', $file_name, $reqs)) { $ret['msg'] = tra('Invalid imagename (using filters for filenames)'); return $ret; } if (!empty($prefs['gal_nmatch_regex']) && preg_match('/'.$prefs['gal_nmatch_regex'].'/', $file_name, $reqs)) { $ret['msg'] = tra('Invalid imagename (using filters for filenames)'); return $ret; } $type = $_FILES[$userfile]['type']; $size = $_FILES[$userfile]['size']; $file_tmp_name = $_FILES[$userfile]['tmp_name']; $tmp_dest = $prefs['tmpDir'] . '/' . $file_name.'.tmp'; // add .tmp to not overwrite existing files (like index.php) if (!move_uploaded_file($file_tmp_name, $tmp_dest)) { $ret['msg'] = tra('Errors detected'); @unlink($tmp_dest); return $ret; } $fp = fopen($tmp_dest, "rb"); $ret['data'] = fread($fp, filesize($tmp_dest)); fclose($fp); $imginfo = @getimagesize($tmp_dest); unlink($tmp_dest); if (!$ret['data'] || !$imginfo) { $ret['msg'] = tra('Errors detected'); return $ret; } if (!$galleryId) { // was called just to get and check the file $ret['xsize'] = $imginfo[0]; $ret['ysize'] = $imginfo[1]; $ret['filetype'] = $type; $ret['filesize'] = $size; return $ret; } if ($name == '') $name = $file_name; if (($imageId = $this->insert_image($galleryId, $name, $description, $file_name, $type, $ret['data'], $size, 0, 0, $user, '', '', NULL, NULL, $gal_info))===false) { $ret['msg'] = tra('Upload was not successful'); } else { $ret['imageId'] = $imageId; } } else { $ret['msg'] = tra('Upload was not successful'); $ret['filename'] = $_FILES[$userfile]['tmp_name']; } unset($ret['data']); return $ret; } // function to move images from one store to another (fs to db or db to fs) /** * @param $imageId * @param string $direction * @return bool|int */ function move_image_store($imageId, $direction = 'to_fs') { global $prefs; global $errstr; $this->clear_class_vars(); //cleanup if ($direction!='to_fs' && $direction!='to_db') { return(false); } if ($direction == 'to_fs' and !is_dir($prefs['gal_use_dir'])) { $errstr = tra("unknown destination directory. Please set it up in <a href='tiki-admin.php?page=galleries'>tiki-admin.php?page=galleries</a>"); return(0); } // get the storage location $query='select `path` from `tiki_images` where `imageId`=?'; $path=$this->getOne($query, array($imageId), false); if ($path===false) { // imageId not found return(false); } if ((empty($path) && $direction=='to_fs') || (!empty($path) && $direction=='to_db')) { // move image // load image $this->get_image($imageId); $query='update `tiki_images` set `path`=? where `imageId`=?'; if ($direction=='to_fs') { $this->path=md5(uniqid($this->filename)); // store_image data did already overwrite the "data" field in tiki_images_data $this->query($query, array($this->path, $imageId)); } // write image $this->store_image_data(true); if ($direction=='to_db') { // remove image in fs if (!@unlink($prefs['gal_use_dir'].$this->path)) { $errstr = tra("unlink failed"); } $this->query($query, array('', $imageId)); } return(1); } return(0); } /** * @param $galId * @param string $direction * @return array|bool */ function move_gallery_store($galId, $direction='to_fs') { $met = ini_get('max_execution_time'); $st = time(); $n = 0; $errors = 0; $timeout = false; if ($direction != 'to_fs' && $direction != 'to_db') { return(false); } // remove all scales. They will be rebuild on access $this->rebuild_scales($galId); // move images store if ($galId == -1) { $query = 'select `imageId` from `tiki_images`'; $result = $this->query($query, array()); } else { $query = 'select `imageId` from `tiki_images` where `galleryId`=?'; $result = $this->query($query, array($galId)); } while ($res = $result->fetchRow()) { $r = $this->move_image_store($res['imageId'], $direction); if ($r !== false) { $n += $r; } else { $errors++; } if ($met-time()+$st < 3) { // avoid timeouts so that we dont end with broken images $timeout = true; break; } } $resultarray = array('moved_images'=>$n, 'timeout'=>$timeout, 'errors'=>$errors); return($resultarray); } function clear_class_vars() { // function to clear loaded data. Usable for mass changes unset($this->imageId); unset($this->galleryId); unset($this->name); unset($this->description); unset($this->lat); unset($this->lon); unset($this->created); unset($this->user); unset($this->hits); unset($this->path); unset($this->xsize); unset($this->oldxsize); unset($this->ysize); unset($this->oldysize); unset($this->type); unset($this->filesize); unset($this->filetype); unset($this->filename); unset($this->etag); unset($this->image); } /* compute the ratio the image $xsize,$size must have to go in the box */ /** * @param $xsize * @param $ysize * @param int $xbox * @param int $ybox * @return float|int|mixed */ function ratio($xsize, $ysize, $xbox=0, $ybox=0) { if (empty($xbox) && empty($ybox)) return 1; if ($xsize <= $xbox && $ysize <= $ybox) return 1; if (empty($xbox)) { return $ybox/xsize; } else { $t = $xbox/$xsize; if (!empty($ybox)) { return $t; } else { return min($t, $ybox/$ysize); } } } }