0,0 → 1,976 |
<?php |
|
/** |
* Main class. |
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License |
* @copyright (c)2003-2006 Tamlyn Rhodes |
* @version $Id: singapore.class.php,v 1.75 2006/09/12 11:56:11 thepavian Exp $ |
*/ |
|
//define constants for regular expressions |
define('SG_REGEXP_PROTOCOLURL', '(?:http://|https://|ftp://|mailto:)(?:[a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,4}(?::[0-9]+)?(?:/[^ \n\r\"\'<]+)?'); |
define('SG_REGEXP_WWWURL', 'www\.(?:[a-zA-Z0-9\-]+\.)*[a-zA-Z]{2,4}(?:/[^ \n\r\"\'<]+)?'); |
define('SG_REGEXP_EMAILURL', '(?:[\w][\w\.\-]+)+@(?:[\w\-]+\.)+[a-zA-Z]{2,4}'); |
|
/** |
* Provides functions for handling galleries and images |
* @package singapore |
* @author Tamlyn Rhodes <tam at zenology dot co dot uk> |
*/ |
class Singapore |
{ |
/** |
* current script version |
* @var string |
*/ |
var $version = "0.10.1"; |
|
/** |
* instance of a {@link sgConfig} object representing the current |
* script configuration |
* @var sgConfig |
*/ |
var $config; |
|
/** |
* instance of the currently selected IO handler object |
* @var sgIO_csv |
*/ |
var $io; |
|
/** |
* instance of a {@link Translator} |
* @var Translator |
*/ |
var $translator; |
|
/** |
* instance of a {@link sgGallery} representing the current gallery |
* @var sgGallery |
*/ |
var $gallery; |
|
/** |
* reference to the currently selected {@link sgImage} object in the |
* $images array of {@link $gallery} |
* @var sgImage |
*/ |
var $image; |
|
/** |
* two character code of language currently in use |
* @var string |
*/ |
var $language = null; |
|
/** |
* name of template currently in use |
* @var string |
*/ |
var $template = null; |
|
/** |
* details of current user |
* @var sgUser |
*/ |
var $user = null; |
|
/** |
* name of action requested |
* @var string |
*/ |
var $action = null; |
|
/** |
* Constructor, does all init type stuff. This code is a total mess. |
* @param string the path to the base singapore directory |
*/ |
function Singapore($basePath = "") |
{ |
//import class definitions |
//io handler class included once config is loaded |
require_once $basePath."includes/translator.class.php"; |
require_once $basePath."includes/thumbnail.class.php"; |
require_once $basePath."includes/gallery.class.php"; |
require_once $basePath."includes/config.class.php"; |
require_once $basePath."includes/image.class.php"; |
require_once $basePath."includes/user.class.php"; |
|
//start execution timer |
$this->scriptStartTime = microtime(); |
|
//remove slashes |
if(get_magic_quotes_gpc()) |
$_REQUEST = array_map(array("Singapore","arraystripslashes"), $_REQUEST); |
|
//desanitize request |
$_REQUEST = array_map("htmlentities", $_REQUEST); |
|
//load config from singapore root directory |
$this->config =& sgConfig::getInstance(); |
$this->config->loadConfig($basePath."singapore.ini"); |
$this->config->loadConfig($basePath."secret.ini.php"); |
|
//if instantiated remotely... |
if(!empty($basePath)) { |
//...try to guess base path and relative url |
if(empty($this->config->base_path)) |
$this->config->base_path = $basePath; |
if(empty($this->config->base_url)) |
$this->config->base_url = $basePath; |
//...load local config if present |
//may over-ride guessed values above |
$this->config->loadConfig("singapore.local.ini"); |
} |
|
//set current gallery to root if not specified in url |
$galleryId = isset($_REQUEST[$this->config->url_gallery]) ? $_REQUEST[$this->config->url_gallery] : "."; |
|
//load config from gallery ini file (gallery.ini) if present |
$this->config->loadConfig($basePath.$this->config->pathto_galleries.$galleryId."/gallery.ini"); |
|
//set current template from request vars or config |
//first, preset template to default one |
$this->template = $this->config->default_template; |
//then check if requested template exists |
if(!empty($_REQUEST[$this->config->url_template])) { |
$templates = Singapore::getListing($this->config->base_path.$this->config->pathto_templates); |
foreach($templates->dirs as $single) { |
if($single == $_REQUEST[$this->config->url_template]) { |
$this->template = $single; |
break; |
} |
} |
} |
|
$this->config->pathto_current_template = $this->config->pathto_templates.$this->template.'/'; |
//load config from template ini file (template.ini) if present |
$this->config->loadConfig($basePath.$this->config->pathto_current_template."template.ini"); |
|
//set runtime values |
$this->config->pathto_logs = $this->config->pathto_data_dir."logs/"; |
$this->config->pathto_cache = $this->config->pathto_data_dir."cache/"; |
$this->config->pathto_admin_template = $this->config->pathto_templates.$this->config->admin_template_name."/"; |
|
//set current language from request vars or config |
if(!empty($_REQUEST[$this->config->url_lang])) |
$this->language = $_REQUEST[$this->config->url_lang]; |
else { |
$this->language = $this->config->default_language; |
if($this->config->detect_language) |
foreach($this->getBrowserLanguages() as $lang) |
if($lang=="en" || file_exists($basePath.$this->config->pathto_locale."singapore.".$lang.".pmo")) { |
$this->language = $lang; |
break; |
} |
} |
|
//read the language file |
$this->translator =& Translator::getInstance($this->language); |
$this->translator->readLanguageFile($this->config->base_path.$this->config->pathto_locale."singapore.".$this->language.".pmo"); |
|
//clear the UMASK |
umask(0); |
|
//include IO handler class and create instance |
require_once $basePath."includes/io_".$this->config->io_handler.".class.php"; |
$ioClassName = "sgIO_".$this->config->io_handler; |
$this->io = new $ioClassName($this->config); |
|
//load gallery and image info |
$this->selectGallery($galleryId); |
|
//set character set |
if(!empty($this->translator->languageStrings[0]["charset"])) |
$this->character_set = $this->translator->languageStrings[0]["charset"]; |
else |
$this->character_set = $this->config->default_charset; |
|
//set action to perform |
if(empty($_REQUEST["action"])) $this->action = "view"; |
else $this->action = $_REQUEST["action"]; |
|
|
} |
|
/** |
* Load gallery and image info |
* @param string the id of the gallery to load (optional) |
*/ |
function selectGallery($galleryId = "") |
{ |
if(empty($galleryId)) $galleryId = isset($_REQUEST[$this->config->url_gallery]) ? $_REQUEST[$this->config->url_gallery] : "."; |
|
//try to validate gallery id |
if(strlen($galleryId)>1 && $galleryId{1} != '/') $galleryId = './'.$galleryId; |
|
//detect back-references to avoid file-system walking |
if(strpos($galleryId,"../")!==false) $galleryId = "."; |
|
//find all ancestors to current gallery |
$this->ancestors = array(); |
$ancestorNames = explode("/", $galleryId); |
$numberOfAncestors = count($ancestorNames); |
|
//construct fully qualified gallery ids |
$ancestorIds[0] = "."; |
for($i=1; $i<$numberOfAncestors; $i++) |
$ancestorIds[$i] = $ancestorIds[$i-1]."/".$ancestorNames[$i]; |
|
//fetch galleries passing previous gallery as parent pointer |
for($i=0; $i<$numberOfAncestors; $i++) |
if(!$this->ancestors[$i] =& $this->io->getGallery( |
$ancestorIds[$i], $this->ancestors[$i-1], |
//only fetch children of bottom level gallery |
($i==$numberOfAncestors-1) ? 1 : 0 |
) |
) |
break; |
|
//need to remove bogus parent of root gallery created by previous step |
unset($this->ancestors[-1]); |
|
//set reference to current gallery |
$this->gallery = &$this->ancestors[count($this->ancestors)-1]; |
|
//check if gallery was successfully fetched |
if($this->gallery == null) { |
$this->gallery = new sgGallery($galleryId, $this->ancestors[0]); |
$this->gallery->name = $this->translator->_g("Gallery not found '%s'",htmlspecialchars($galleryId)); |
} |
|
//sort galleries and images |
$GLOBALS["sgSortOrder"] = $this->config->gallery_sort_order; |
if($this->config->gallery_sort_order!="x") usort($this->gallery->galleries, array("Singapore","multiSort")); |
$GLOBALS["sgSortOrder"] = $this->config->image_sort_order; |
if($this->config->image_sort_order!="x") usort($this->gallery->images, array("Singapore","multiSort")); |
unset($GLOBALS["sgSortOrder"]); |
|
//if startat is set then cast to int otherwise startat 0 |
$this->gallery->startat = isset($_REQUEST[$this->config->url_startat]) ? (int)$_REQUEST[$this->config->url_startat] : 0; |
$this->startat = $this->gallery->startat; //depreciated |
|
//select the image (if any) |
if(!empty($_REQUEST[$this->config->url_image])) |
$this->selectImage($_REQUEST[$this->config->url_image]); |
|
//load hit data |
if($this->config->track_views || $this->config->show_views) |
$this->io->getHits($this->gallery); |
|
//update and save hit data |
if($this->config->track_views) { |
if($this->isImagePage()) { |
$this->image->hits++; |
$this->image->lasthit = time(); |
} elseif($this->gallery->startat == 0) { |
$this->gallery->hits++; |
$this->gallery->lasthit = time(); |
} |
$this->io->putHits($this->gallery); |
} |
} |
|
/** |
* Selects an image from the current gallery |
* @param mixed either the filename of the image to select or the integer |
* index of its position in the images array |
* @return boolean true on success; false otherwise |
*/ |
function selectImage($image) |
{ |
if(is_string($image)) { |
foreach($this->gallery->images as $index => $img) |
if($img->id == $image) { |
$this->image =& $this->gallery->images[$index]; |
return true; |
} |
} elseif(is_int($image) && $image >= 0 && $image < count($this->gallery->images)) { |
$this->image =& $this->gallery->images[$image]; |
return true; |
} |
$this->image =& new sgImage("", $this->gallery); |
$this->image->name = $this->translator->_g("Image not found '%s'",htmlspecialchars($image)); |
return false; |
} |
|
|
/** |
* Obfuscates the given email address by replacing "." with "dot" and "@" with "at" |
* @param string email address to obfuscate |
* @param boolean override the obfuscate_email config setting (optional) |
* @return string obfuscated email address or HTML mailto link |
*/ |
function formatEmail($email, $forceObfuscate = false) |
{ |
if($this->config->obfuscate_email || $forceObfuscate) |
return strtr($email,array("@" => ' <b>'.$this->translator->_g("email|at").'</b> ', "." => ' <b>'.$this->translator->_g("email|dot").'</b> ')); |
else |
return "<a href=\"mailto:".$email."\">".$email."</a>"; |
} |
|
|
/** |
* Returns image name for image pages and gallery name for gallery pages. |
* If either of these is empty, returns gallery_name config option. |
* |
* @return string Title of current page |
*/ |
function pageTitle() |
{ |
$crumbArray = $this->crumbLineArray(); |
|
$ret = ""; |
for($i=count($crumbArray)-1;$i>0;$i--) |
$ret .= $crumbArray[$i]->nameForce()." < "; |
$ret .= $crumbArray[$i]->nameForce(); |
|
return $ret; |
} |
|
/** |
* @return bool true if this is an image page; false otherwise |
*/ |
function isImagePage() |
{ |
return !empty($this->image); |
} |
|
/** |
* @return bool true if this is a non-album gallery page; false otherwise |
*/ |
function isGalleryPage() |
{ |
return !empty($this->gallery) && $this->gallery->galleryCount()>0;; |
} |
|
/** |
* @return bool true if this is an album page; false otherwise |
*/ |
function isAlbumPage() |
{ |
return !$this->isGalleryPage() && !$this->isImagePage() && !empty($this->gallery); |
} |
|
|
/** |
* @return int the script execution time in seconds rounded to two decimal places |
*/ |
function scriptExecTime() |
{ |
$scriptStartTime = $this->scriptStartTime; |
$scriptEndTime = microtime(); |
|
list($usec, $sec) = explode(" ",$scriptStartTime); |
$scriptStartTime = (float)$usec + (float)$sec; |
list($usec, $sec) = explode(" ",$scriptEndTime); |
$scriptEndTime = (float)$usec + (float)$sec; |
|
$scriptExecTime = floor(($scriptEndTime - $scriptStartTime)*100)/100; |
return $scriptExecTime; |
} |
|
/** |
* Displays the script execution time if configured to do so |
* @returns string the script execution time |
*/ |
function scriptExecTimeText() |
{ |
if($this->config->show_execution_time) |
return $this->translator->_g("Page created in %s seconds",$this->scriptExecTime()); |
else |
return ""; |
} |
|
function poweredByText() |
{ |
return $this->translator->_g("Powered by").' <a href="http://www.sgal.org/">singapore</a>'; |
} |
|
function allRightsReserved() |
{ |
return $this->translator->_g("All rights reserved."); |
} |
|
function licenseText() |
{ |
return $this->translator->_g("Images may not be reproduced in any form without the express written permission of the copyright holder."); |
} |
|
function adminURL() |
{ |
return '<a href="'.$this->config->base_url.'admin.php">'; |
} |
|
function adminLink() |
{ |
return $this->adminURL().$this->translator->_g("Log in")."</a>"; |
} |
|
|
/** |
* Checks to see if the user is currently logged in to admin mode. Also resets |
* the login timeout to the current time. |
* @returns boolean true if the user is logged in; false otherwise |
* @static |
*/ |
function isLoggedIn() |
{ |
if( |
isset($this->user) && |
$_SESSION["sgUser"]["ip"] == $_SERVER["REMOTE_ADDR"] && |
(time() - $_SESSION["sgUser"]["loginTime"] < 600) |
) { |
//reset loginTime to current time |
$_SESSION["sgUser"]["loginTime"] = time(); |
return true; |
} |
return false; |
} |
|
function loadUser($username = null) |
{ |
if($username == null) |
if(isset($_SESSION["sgUser"])) |
$username = $_SESSION["sgUser"]["username"]; |
else |
return false; |
|
$users = $this->io->getUsers(); |
foreach($users as $user) |
if($user->username == $username) { |
$this->user = $user; |
return $user; |
} |
return false; |
} |
|
/** |
* Creates an array of objects each representing an item in the crumb line. |
* @return array the items of the crumb line |
*/ |
function crumbLineArray() |
{ |
$crumb = $this->ancestors; |
|
if($this->isImagePage()) $crumb[] = $this->image; |
|
return $crumb; |
} |
|
/** |
* @return string the complete crumb line with links |
*/ |
function crumbLineText() |
{ |
$crumbArray = $this->crumbLineArray(); |
|
$ret = ""; |
for($i=0;$i<count($crumbArray)-1;$i++) |
$ret .= $crumbArray[$i]->nameLink()." >\n"; |
$ret .= $crumbArray[$i]->nameForce(); |
|
return $ret; |
} |
|
function crumbLine() |
{ |
return $this->translator->_g("crumb line|You are here:")." ".$this->crumbLineText(); |
} |
|
/** |
* Generates the HTML code for imagemap_navigation |
* @return string imagemap HTML code |
*/ |
function imageMap() |
{ |
if(!$this->config->imagemap_navigation) return ""; |
|
$imageWidth = $this->image->width(); |
$imageHeight = $this->image->height(); |
$middleX = round($imageWidth/2); |
$middleY = round($imageHeight/2); |
|
$ret = "<map name=\"sgNavMap\" id=\"sgNavMap\">\n"; |
if($this->image->hasNext()) $ret .= '<area href="'.$this->image->nextURL().'" alt="'.$this->image->nextText().'" title="'.$this->image->nextText().'" shape="poly" '; |
else $ret .= '<area href="'.$this->image->parentURL().'" alt="'.$this->image->parentText().'" title="'.$this->image->parentText().'" shape="poly" '; |
$ret .= "coords=\"$middleX,$middleY,$imageWidth,$imageHeight,$imageWidth,0,$middleX,$middleY\" />\n"; |
if($this->image->hasPrev()) $ret .= '<area href="'.$this->image->prevURL().'" alt="'.$this->image->prevText().'" title="'.$this->image->prevText().'" shape="poly" '; |
else $ret .= '<area href="'.$this->image->parentURL().'" alt="'.$this->image->parentText().'" title="'.$this->image->parentText().'" shape="poly" '; |
$ret .= "coords=\"$middleX,$middleY,0,0,0,$imageHeight,$middleX,$middleY\" />\n"; |
$ret .= '<area href="'.$this->image->parentURL().'" alt="'.$this->image->parentText().'" title="'.$this->image->parentText().'" shape="poly" '; |
$ret .= "coords=\"$middleX,$middleY,0,0,$imageWidth,0,$middleX,$middleY\" />\n"; |
$ret .= '</map>'; |
|
return $ret; |
} |
|
/** |
* Generates the HTML code for the language select box |
* @return string select box HTML code |
*/ |
function languageFlipper() |
{ |
if(!$this->config->language_flipper) return ""; |
|
$languageCache = $this->config->base_path.$this->config->pathto_data_dir."languages.cache"; |
// Look for the language file |
if(!file_exists($languageCache)) |
return ""; |
|
// Open the file |
$fp = @fopen($languageCache, "r"); |
if (!$fp) return ""; |
|
// Read contents |
$str = ''; |
while (!feof($fp)) $str .= fread($fp, 1024); |
// Unserialize |
$availableLanguages = @unserialize($str); |
|
$ret = '<div class="sgLanguageFlipper">'; |
$ret .= '<form method="get" action="'.$_SERVER["PHP_SELF"]."\">\n"; |
//carry over current get vars |
foreach($_GET as $var => $val) |
$ret .= '<input type="hidden" name="'.$var.'" value="'.htmlspecialchars($val)."\" />\n"; |
$ret .= '<select name="'.$this->config->url_lang."\">\n"; |
$ret .= ' <option value="'.$this->config->default_language.'">'.$this->translator->_g("Select language...")."</option>\n"; |
foreach($availableLanguages as $code => $name) { |
$ret .= ' <option value="'.$code.'"'; |
if($code == $this->language && $this->language != $this->config->default_language) |
$ret .= 'selected="true" '; |
$ret .= '>'.htmlentities($name)."</option>\n"; |
} |
$ret .= "</select>\n"; |
$ret .= '<input type="submit" class="button" value="'.$this->translator->_g("Go")."\" />\n"; |
$ret .= "</form></div>\n"; |
return $ret; |
} |
|
/** |
* Generates the HTML code for the template select box |
* @return string select box HTML code |
*/ |
function templateFlipper() |
{ |
if(!$this->config->template_flipper) return ""; |
|
//get list of installed templates |
$templates = Singapore::getListing($this->config->base_path.$this->config->pathto_templates, "dirs"); |
|
$ret = '<div class="sgTemplateFlipper">'; |
$ret .= '<form method="get" action="'.$_SERVER["PHP_SELF"]."\">\n"; |
//carry over current get vars |
foreach($_GET as $var => $val) |
$ret .= '<input type="hidden" name="'.$var.'" value="'.htmlspecialchars($val)."\" />\n"; |
$ret .= '<select name="'.$this->config->url_template."\">\n"; |
$ret .= ' <option value="'.$this->config->default_template.'">'.$this->translator->_g("Select template...")."</option>\n"; |
foreach($templates->dirs as $name) |
//do not list admin template(s) |
if(strpos($name, "admin_")===false) { |
$ret .= ' <option value="'.$name.'"'; |
if($name == $this->template && $this->template != $this->config->default_template) |
$ret .= 'selected="true" '; |
$ret .= '>'.$name."</option>\n"; |
} |
$ret .= "</select>\n"; |
$ret .= '<input type="submit" class="button" value="'.$this->translator->_g("Go")."\" />\n"; |
$ret .= "</form></div>\n"; |
return $ret; |
} |
|
|
/** |
* @param string $seperator optional string to seperate the Gallery Tab Links |
* @return string |
*/ |
function galleryTab($seperator = " | ") |
{ |
$showing = $this->galleryTabShowing(); |
return Singapore::conditional($this->galleryTabLinks(), $showing.$seperator."%s", $showing); |
} |
|
/** |
* @return string |
*/ |
function galleryTabShowing() |
{ |
if($this->isAlbumPage()) { |
$total = $this->gallery->imageCount(); |
$perPage = $this->config->thumb_number_album; |
} else { |
$total = $this->gallery->galleryCount(); |
$perPage = $this->config->thumb_number_gallery; |
} |
|
if($this->gallery->startat+$perPage > $total) |
$last = $total; |
else |
$last = $this->gallery->startat+$perPage; |
|
return $this->translator->_g("Showing %s-%s of %s",($this->gallery->startat+1),$last,$total); |
} |
|
/** |
* @return string |
*/ |
function galleryTabLinks() |
{ |
$ret = ""; |
if($this->hasPrevPage()) |
$ret .= $this->prevPageLink()." "; |
|
//This is for compatibility with old templates |
//it detects if compatibility mode is on using method_exists() |
if(!$this->gallery->isRoot() && method_exists($this, 'galleryName')) |
$ret .= $this->gallery->parentLink(); |
|
if($this->hasNextPage()) |
$ret .= " ".$this->nextPageLink(); |
|
return $ret; |
} |
|
function navigationLinks() { |
$ret = "<link rel=\"Top\" title=\"".$this->config->gallery_name."\" href=\"".$this->ancestors[0]->URL()."\" />\n"; |
|
if($this->isImagePage()) { |
$ret .= "<link rel=\"Up\" title=\"".$this->image->parent->name()."\" href=\"".$this->image->parent->URL()."\" />\n"; |
if ($this->image->hasPrev()) { |
$first= $this->image->firstImage(); |
$prev = $this->image->prevImage(); |
$ret .= "<link rel=\"First\" title=\"".$first->name()."\" href=\"".$first->URL()."\" />\n"; |
$ret .= "<link rel=\"Prev\" title=\"".$prev->name()."\" href=\"".$prev->URL()."\" />\n"; |
} |
if ($this->image->hasNext()) { |
$next = $this->image->nextImage(); |
$last = $this->image->lastImage(); |
$ret .= "<link rel=\"Next\" title=\"".$next->name()."\" href=\"".$next->URL()."\" />\n"; |
$ret .= "<link rel=\"Last\" title=\"".$last->name()."\" href=\"".$last->URL()."\" />\n"; |
//prefetch next image |
$ret .= "<link rel=\"Prefetch\" href=\"".$next->imageURL()."\" />\n"; |
} |
} else { |
if(!$this->gallery->isRoot()) |
$ret .= "<link rel=\"Up\" title=\"".$this->gallery->parent->name()."\" href=\"".$this->gallery->parent->URL()."\" />\n"; |
if($this->hasPrevPage()) { |
$ret .= "<link rel=\"Prev\" title=\"".$this->translator->_g("gallery|Previous")."\" href=\"".$this->prevPageURL()."\" />\n"; |
$ret .= "<link rel=\"First\" title=\"".$this->translator->_g("gallery|First")."\" href=\"".$this->firstPageURL()."\" />\n"; |
} |
if($this->hasNextPage()) { |
$ret .= "<link rel=\"Next\" title=\"".$this->translator->_g("gallery|Next")."\" href=\"".$this->nextPageURL()."\" />\n"; |
$ret .= "<link rel=\"Last\" title=\"".$this->translator->_g("gallery|Last")."\" href=\"".$this->lastPageURL()."\" />\n"; |
} |
} |
return $ret; |
} |
|
|
/** |
* @return int the number of 'pages' or 'screen-fulls' |
*/ |
function galleryPageCount() { |
if($this->isAlbumPage()) |
return intval($this->gallery->imageCount()/$this->config->thumb_number_album)+1; |
else |
return intval($this->gallery->galleryCount()/$this->config->thumb_number_gallery)+1; |
} |
|
/** |
* @return int |
*/ |
function lastPageIndex() { |
if($this->isAlbumPage()) |
return ($this->galleryPageCount()-1)* |
($this->isAlbumPage()?$this->config->thumb_number_album:$this->config->thumb_number_gallery); |
} |
|
/** |
* @return bool true if there is at least one more page |
*/ |
function hasNextPage() { |
if($this->isAlbumPage()) |
return count($this->gallery->images)>$this->startat+$this->config->thumb_number_album; |
elseif($this->isGalleryPage()) |
return count($this->gallery->galleries)>$this->startat+$this->config->thumb_number_gallery; |
elseif($this->isImagePage()) |
return isset($this->gallery->images[$this->image->index+1]); |
} |
|
/** |
* @return bool true if there is at least one previous page |
*/ |
function hasPrevPage() { |
if($this->isAlbumPage() || $this->isGalleryPage()) |
return $this->startat > 0; |
elseif($this->isImagePage()) |
return isset($this->gallery->images[$this->image->index-1]); |
} |
|
function firstPageURL() { |
return $this->gallery->URL(0); |
} |
|
function firstPageLink() { |
return "<a href=\"".$this->firstPageURL()."\">".$this->translator->_g("First %s", $this->itemsPerPage())."</a>"; |
} |
|
/** |
* @return string the URL of the previous page |
*/ |
function prevPageURL() { |
return $this->gallery->URL($this->startat - $this->itemsPerPage()); |
} |
|
function prevPageLink() { |
return "<a href=\"".$this->prevPageURL()."\">".$this->translator->_g("Previous %s", $this->itemsPerPage())."</a>"; |
} |
|
/** |
* @return string the URL of the next page |
*/ |
function nextPageURL() { |
return $this->gallery->URL($this->startat + $this->itemsPerPage()); |
} |
|
function nextPageLink() { |
return "<a href=\"".$this->nextPageURL()."\">".$this->translator->_g("Next %s", $this->itemsPerPage())."</a>"; |
} |
|
function lastPageURL() { |
$perpage = $this->isAlbumPage() ? $this->config->thumb_number_album : $this->config->thumb_number_gallery; |
return $this->gallery->URL(floor($this->gallery->itemCount() / $perpage) * $perpage); |
} |
|
function lastPageLink() { |
return "<a href=\"".$this->lastPageURL()."\">".$this->translator->_g("Last %s", $this->itemsPerPage())."</a>"; |
} |
|
function itemsPerPage() |
{ |
return $this->isAlbumPage() ? $this->config->thumb_number_album : $this->config->thumb_number_gallery; |
} |
|
/** |
* @return string link for adding a comment to image |
*/ |
function imageCommentLink() |
{ |
return "<a href=\"". |
$this->formatURL($this->gallery->idEncoded(), $this->image->id, null, "addcomment"). |
"\">".$this->translator->_g("Add a comment")."</a>"; |
} |
|
/** |
* @return array array of sgImage objects |
*/ |
function &previewThumbnailsArray() |
{ |
$ret = array(); |
$index = $this->image->index(); |
$start = ceil($index - $this->config->thumb_number_preview/2); |
|
for($i = $start; $i < $start + $this->config->thumb_number_preview; $i++) |
if(isset($this->image->parent->images[$i])) |
$ret[$i] =& $this->image->parent->images[$i]; |
|
return $ret; |
} |
|
function previewThumbnails() |
{ |
$thumbs =& $this->previewThumbnailsArray(); |
$index = $this->image->index(); |
$ret = ""; |
foreach($thumbs as $key => $thumb) { |
$thumbClass = "sgThumbnailPreview"; |
if($key==$index-1) $thumbClass .= " sgThumbnailPreviewPrev"; |
elseif($key==$index) $thumbClass .= " sgThumbnailPreviewCurrent"; |
elseif($key==$index+1) $thumbClass .= " sgThumbnailPreviewNext"; |
$ret .= $thumb->thumbnailLink($thumbClass, "preview")."\n"; |
} |
|
return $ret; |
} |
|
////////////////////////////// |
//////ex-sgUtils methods////// |
////////////////////////////// |
|
/** |
* Callback function for sorting things |
* @static |
*/ |
function multiSort($a, $b) { |
switch($GLOBALS["sgSortOrder"]) { |
case "f" : |
case "p" : return strcmp($a->id, $b->id); //path |
case "F" : |
case "P" : return strcmp($b->id, $a->id); //path (reverse) |
case "n" : return strcmp($a->name, $b->name); //name |
case "N" : return strcmp($b->name, $a->name); //name (reverse) |
case "i" : return strcasecmp($a->name, $b->name); //case-insensitive name |
case "I" : return strcasecmp($b->name, $a->name); //case-insensitive name (reverse) |
case "a" : return strcmp($a->artist, $b->artist); //artist |
case "A" : return strcmp($b->artist, $a->artist); //artist (reverse) |
case "d" : return strcmp($a->date, $b->date); //date |
case "D" : return strcmp($b->date, $a->date); //date (reverse) |
case "l" : return strcmp($a->location, $b->location); //location |
case "L" : return strcmp($b->location, $a->location); //location (reverse) |
} |
} |
|
/** |
* Slightly pointless method |
*/ |
function conditional($conditional, $iftrue, $iffalse = null) |
{ |
if($conditional) return sprintf($iftrue, $conditional); |
elseif($iffalse != null) return sprintf($iffalse, $conditional); |
else return ""; |
} |
|
/** |
* Callback function for recursively stripping slashes |
* @static |
*/ |
function arraystripslashes($toStrip) |
{ |
if(is_array($toStrip)) |
return array_map(array("Singapore","arraystripslashes"), $toStrip); |
else |
return stripslashes($toStrip); |
} |
|
function thumbnailPath($gallery, $image, $width, $height, $forceSize, $mode = 1) |
{ |
$config =& sgConfig::getInstance(); |
switch($mode) { |
case 0 : |
return $config->pathto_data_dir."cache/".$width."x".$height.($forceSize?"f":"").strtr("-$gallery-$image",":/?\\","----"); |
case 1 : |
return $config->pathto_galleries.$gallery."/_thumbs/".$width."x".$height.($forceSize?"f":"").strtr("-$image",":/?\\","----"); |
} |
} |
|
/** |
* @param string relative or absolute path to directory |
* @param string regular expression of files to return (optional) |
* @param bool true to get hidden directories too |
* @returns stdClass|false a data object representing the directory and its contents |
* @static |
*/ |
function getListing($wd, $mask = null, $getHidden = false) |
{ |
$dir = new stdClass; |
$dir->path = realpath($wd)."/"; |
$dir->files = array(); |
$dir->dirs = array(); |
|
$dp = opendir($dir->path); |
if(!$dp) return false; |
|
while(false !== ($entry = readdir($dp))) |
if(is_dir($dir->path.$entry)) { |
if(($entry{0} != '.' && $entry{0} != '_') || $getHidden) |
$dir->dirs[] = $entry; |
} else { |
if($mask == null || preg_match("/\.($mask)$/i",$entry)) |
$dir->files[] = $entry; |
} |
|
sort($dir->files); |
sort($dir->dirs); |
closedir($dp); |
return $dir; |
} |
|
/** |
* Recursively deletes all directories and files in the specified directory. |
* USE WITH EXTREME CAUTION!! |
* @returns boolean true on success; false otherwise |
* @static |
*/ |
function rmdir_all($wd) |
{ |
if(!$dp = opendir($wd)) return false; |
$success = true; |
while(false !== ($entry = readdir($dp))) { |
if($entry == "." || $entry == "..") continue; |
if(is_dir("$wd/$entry")) $success &= Singapore::rmdir_all("$wd/$entry"); |
else $success &= unlink("$wd/$entry"); |
} |
closedir($dp); |
$success &= rmdir($wd); |
return $success; |
} |
|
/** |
* Returns an array of language codes specified in the Accept-Language HHTP |
* header field of the user's browser. q= components are ignored and removed. |
* hyphens (-) are converted to underscores (_). |
* @return array accepted language codes |
* @static |
*/ |
function getBrowserLanguages() |
{ |
$langs = array(); |
foreach(explode(",",$_SERVER["HTTP_ACCEPT_LANGUAGE"]) as $bit) |
if($pos = strpos($bit,";")) |
$langs[] = strtr(substr($bit,0,$pos),"-","_"); |
else |
$langs[] = strtr($bit,"-","_"); |
return $langs; |
} |
|
/** |
* Wrapper for mkdir() implementing the safe-mode hack |
*/ |
function mkdir($path) |
{ |
$config =& sgConfig::getInstance(); |
if($config->safe_mode_hack) { |
$connection = ftp_connect($config->ftp_server); |
// login to ftp server |
$result = ftp_login($connection, $config->ftp_user, $config->ftp_pass); |
|
// check if connection was made |
if ((!$connection) || (!$result)) |
return false; |
|
ftp_chdir($connection, $config->ftp_base_path); // go to destination dir |
if(!ftp_mkdir($connection, $path)) // create directory |
return false; |
|
ftp_site($connection, "CHMOD ".$config->directory_mode." ".$path); |
ftp_close($connection); // close connection |
return true; |
} else |
return mkdir($path, octdec($config->directory_mode)); |
} |
|
/** |
* Tests if $child is within or is the same path as $parent. |
* |
* @param string path to parent directory |
* @param string path to child directory or file |
* @param bool set false to prevent canonicalisation of paths (optional) |
* @return bool true if $child is contained within or is $parent |
*/ |
function isSubPath($parent, $child, $canonicalise = true) |
{ |
$parentPath = $canonicalise ? realpath($parent) : $parent; |
$childPath = $canonicalise ? realpath($child) : $child; |
return $parentPath && $childPath && substr($childPath,0,strlen($parentPath)) == $parentPath; |
} |
|
|
function isInGroup($groups1,$groups2) |
{ |
return (bool) array_intersect(explode(" ",$groups1),explode(" ",$groups2)); |
} |
|
} |
|
|
?> |