/photogallery/includes/admin.class.php
0,0 → 1,1532
<?php
 
/**
* Class providing admin functions.
*
* @package singapore
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003-2006 Tamlyn Rhodes
* @version $Id: admin.class.php,v 1.65 2006/09/08 15:29:22 tamlyn Exp $
*/
 
define("SG_ADMIN", 1024);
define("SG_SUSPENDED", 2048);
 
//include the base IO class
require_once dirname(__FILE__)."/singapore.class.php";
 
/**
* Provides gallery, image and user administration functions.
*
* @uses Singapore
* @package singapore
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
*/
class sgAdmin extends Singapore
{
/**
* Array of error messages raised by the script
* @var array
*/
var $errors = array();
/**
* Array of informational messages raised by the script
* @var array
*/
var $messages = array();
/**
* Base name of admin template file to include
* @var string
*/
var $includeFile = "login";
/**
* Admin constructor. Doesn't call {@link Singapore} constructor.
* @param string the path to the base singapore directory
*/
function sgAdmin($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);
//as if magic_quotes_gpc wasn't insane enough, php doesn't add slashes
//to the tmp_name variable so I have to add them manually. Grrrr.
foreach($_FILES as $key => $nothing)
$_FILES[$key]["tmp_name"] = addslashes($_FILES[$key]["tmp_name"]);
$_FILES = array_map(array("Singapore","arraystripslashes"), $_FILES);
}
$galleryId = isset($_REQUEST["gallery"]) ? $_REQUEST["gallery"] : ".";
//load config from singapore root directory
$this->config =& sgConfig::getInstance();
$this->config->loadConfig($basePath."singapore.ini");
$this->config->loadConfig($basePath."secret.ini.php");
//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_current_template = $this->config->pathto_templates.$this->config->default_template."/";
$this->config->pathto_admin_template = $this->config->pathto_templates.$this->config->admin_template_name."/";
//load config from admin template ini file (admin.ini) if present
$this->config->loadConfig($basePath.$this->config->pathto_admin_template."admin.ini");
$this->template = $this->config->default_template;
//do not load gallery-specific ini files
 
//set current language from request vars or config
$this->language = isset($_REQUEST["lang"]) ? $_REQUEST["lang"] : $this->config->default_language;
//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");
$this->translator->readLanguageFile($this->config->base_path.$this->config->pathto_locale."singapore.admin.".$this->language.".pmo");
//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);
//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 = "menu";
else $this->action = $_REQUEST["action"];
//set page title
$this->pageTitle = $this->config->gallery_name;
//set root node of crumb line
$holder = new sgGallery("", new stdClass);
$holder->name = $this->config->gallery_name;
$this->ancestors = array($holder);
}
/**
* Push an error message onto the error stack
* @param string Error message
* @param string true if error is fatal; false otherwise (optional)
* @return false
*/
function pushError($error, $fatal = false)
{
if($fatal) die($error);
$this->errors[] = $error;
return false;
}
/**
* Push a message onto the message stack
* @return true
*/
function pushMessage($message)
{
$this->messages[] = $message;
return true;
}
function showMessages()
{
if(empty($this->errors) && empty($this->messages)) return '';
$errorText = $this->translator->_g("ERROR");
$ret = '<ul id="sgAdminMessages">';
foreach($this->errors as $error)
$ret .= '<li class="adminError">'.$errorText.': '.$error.'</li>'."\n";
foreach($this->messages as $message)
$ret .= '<li class="adminMessage">'.$message.'</li>'."\n";
$ret .= '</ul>';
return $ret;
}
/**
* Returns a link to the image or gallery with the correct formatting and path
* NOTE: This takes its arguments in a different order to {@link Singapore::formatURL()}
*
* @author Adam Sissman <adam at bluebinary dot com>
*/
function formatAdminURL($action, $gallery = null, $image = null, $startat = null, $extra = null)
{
$ret = $this->config->base_url."admin.php?";
$ret .= "action=".$action;
if($gallery != null) $ret .= "&amp;gallery=".$gallery;
if($image != null) $ret .= "&amp;image=".$image;
if($startat != null) $ret .= "&amp;startat=".$startat;
if($extra != null) $ret .= $extra;
if($this->language != $this->config->default_language) $ret .= '&amp;'.$this->config->url_lang.'='.$this->language;
if($this->template != $this->config->default_template) $ret .= '&amp;'.$this->config->url_template.'='.$this->template;
return $ret;
}
 
/**
* Tries to find temporary storage space
*/
function findTempDirectory()
{
if(isset($_ENV["TMP"]) && is_writable($_ENV["TMP"])) return $_ENV["TMP"];
elseif(isset($_ENV["TEMP"]) && is_writable($_ENV["TEMP"])) return $_ENV["TEMP"];
elseif(is_writable("/tmp")) return "/tmp";
elseif(is_writable("/windows/temp")) return "/windows/temp";
elseif(is_writable("/winnt/temp")) return "/winnt/temp";
else return null;
}
function getMaxHits($array)
{
$max = 0;
foreach($array as $obj)
if($obj->hits > $max)
$max = $obj->hits;
return $max;
}
/**
* Returns true if the current admin action has been confirmed (i.e. by clicking OK)
*/
function actionConfirmed()
{
return isset($_REQUEST["confirmed"]) && $_REQUEST["confirmed"] == $this->translator->_g("confirm|OK");
}
/**
* Returns true if the current admin action has been cancelled (i.e. by clicking Cancel)
*/
function actionCancelled()
{
return isset($_REQUEST["confirmed"]) && $_REQUEST["confirmed"] == $this->translator->_g("confirm|Cancel");
}
/**
* Checks request variables for action to perform, checks user permissions,
* performs action and sets file to include.
*/
function doAction()
{
//check if user is logged in
if(!$this->isLoggedIn() && $this->action != "login")
return;
//choose which file to include and/or perform admin actions
switch($this->action) {
case "addgallery" :
$this->selectGallery();
if(!$this->checkPermissions($this->gallery,"add")) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "view";
} elseif($this->addGallery()) {
$this->selectGallery($this->gallery->id."/".$_REQUEST["newgallery"]);
$this->pushMessage($this->translator->_g("Gallery added"));
$this->includeFile = "editgallery";
} else {
$this->includeFile = "newgallery";
}
break;
case "addimage" :
$this->selectGallery();
if(!$this->checkPermissions($this->gallery,"add")) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "view";
break;
}
switch($_REQUEST["sgLocationChoice"]) {
case "remote" :
case "single" :
if($this->addImage())
$this->includeFile = "editimage";
else
$this->includeFile = "newimage";
break;
case "multi" :
if($this->addMultipleImages())
$this->includeFile = "view";
else
$this->includeFile = "newimage";
break;
default :
$this->includeFile = "newimage";
break;
}
break;
case "changethumbnail" :
$this->selectGallery();
if(!$this->checkPermissions($this->gallery,"edit")) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "view";
} elseif($this->actionConfirmed()) {
$this->saveGalleryThumbnail();
$this->includeFile = "editgallery";
} elseif($this->actionCancelled()) {
$this->includeFile = "editgallery";
} else {
$this->includeFile = "changethumbnail";
}
break;
case "deletegallery" :
$this->selectGallery();
if(!$this->checkPermissions($this->gallery,"delete")) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "view";
} elseif($this->actionConfirmed() || ($this->gallery->galleryCount()==0 && $this->gallery->imageCount()==0)) {
if($this->deleteGallery())
$this->selectGallery($this->gallery->parent->id);
$this->includeFile = "view";
} elseif($this->actionCancelled()) {
$this->includeFile = "view";
} else {
$GLOBALS["confirmTitle"] = $this->translator->_g("Delete Gallery");
$GLOBALS["confirmMessage"] = $this->translator->_g("Gallery %s is not empty.\nAre you sure you want to irretrievably delete it and all subgalleries and images it contains?", "<em>".$this->gallery->name."</em>");
$this->includeFile = "confirm";
}
break;
case "deleteimage" :
$this->selectGallery();
if(!$this->checkPermissions($this->gallery,"delete")) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "view";
} elseif($this->actionConfirmed()) {
$this->deleteImage();
$this->includeFile = "view";
} elseif($this->actionCancelled()) {
$this->includeFile = "view";
} else {
$GLOBALS["confirmTitle"] = $this->translator->_g("delete image");
$GLOBALS["confirmMessage"] = $this->translator->_g("Are you sure you want to irretrievably delete image %s from gallery %s?","<em>".$this->image->name().$this->image->byArtistText()."</em>","<em>".$this->gallery->name()."</em>");
$this->includeFile = "confirm";
}
break;
case "deleteuser" :
if(!$this->user->isAdmin()) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "menu";
} elseif($this->actionConfirmed()) {
if($this->deleteUser())
$this->pushMessage($this->translator->_g("User deleted"));
$this->includeFile = "manageusers";
} elseif($this->actionCancelled()) {
$this->includeFile = "manageusers";
} else {
$GLOBALS["confirmTitle"] = $this->translator->_g("delete user");
$GLOBALS["confirmMessage"] = $this->translator->_g("Are you sure you want to permanently delete user %s?","<em>".$_REQUEST["user"]."</em>");
$this->includeFile = "confirm";
}
break;
case "editgallery" :
$this->selectGallery();
if(!$this->checkPermissions($this->gallery,"edit")) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "view";
} else
$this->includeFile = "editgallery";
break;
case "editimage" :
$this->selectGallery();
if(!$this->checkPermissions($this->gallery,"edit")) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "view";
} else
$this->includeFile = "editimage";
break;
case "editpass" :
if($this->user->isGuest()) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "menu";
} else
$this->includeFile = "editpass";
break;
case "editpermissions" :
$this->selectGallery();
if(!$this->user->isAdmin() && !$this->user->isOwner($this->gallery)) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "view";
} else
$this->includeFile = "editpermissions";
break;
case "editprofile" :
if($this->user->isGuest()) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "menu";
} else
$this->includeFile = "editprofile";
break;
case "edituser" :
if(!$this->user->isAdmin() && $_REQUEST["user"] != $this->user->username || $this->user->isGuest()) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "menu";
} else
$this->includeFile = "edituser";
break;
case "login" :
if($this->doLogin())
$this->includeFile = "menu";
else
$this->includeFile = "login";
break;
case "logout" :
$this->logout();
$this->includeFile = "login";
break;
case "manageusers" :
if(!$this->user->isAdmin()) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "menu";
} else
$this->includeFile = "manageusers";
break;
case "multi" :
$this->selectGallery();
if(!isset($_REQUEST["sgGalleries"]) && !isset($_REQUEST["sgImages"])) {
$this->pushMessage($this->translator->_g("Please select one or more items."));
$this->includeFile = "view";
} elseif($_REQUEST["subaction"]==$this->translator->_g("Copy or move")) {
$this->includeFile = "multimove";
} elseif($_REQUEST["subaction"]==$this->translator->_g("Delete")) {
if(!$this->checkPermissions($this->gallery,"delete")) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "view";
} elseif($this->actionConfirmed()) {
if(isset($_REQUEST["sgImages"])) {
$success = $this->deleteMultipleImages();
$this->pushMessage($this->translator->_g("%s images deleted.", $success));
} else {
$success = $this->deleteMultipleGalleries();
$this->pushMessage($this->translator->_g("%s galleries deleted.", $success));
}
$this->includeFile = "view";
} elseif($this->actionCancelled()) {
$this->includeFile = "view";
} else {
if(isset($_REQUEST["sgImages"])) {
$GLOBALS["confirmTitle"] = $this->translator->_g("Delete Images");
$GLOBALS["confirmMessage"] = $this->translator->_g("Are you sure you want to permanently delete %s images?",count($_REQUEST["sgImages"]));
} else{
$GLOBALS["confirmTitle"] = $this->translator->_g("Delete Galleries");
$GLOBALS["confirmMessage"] = $this->translator->_g("Are you sure you want to permanently delete %s galleries?",count($_REQUEST["sgGalleries"]));
}
$this->includeFile = "confirm";
}
} elseif($_REQUEST["subaction"]==$this->translator->_g("Re-index")) {
if(is_int($success = $this->reindexMultipleGalleries()))
$this->pushMessage($this->translator->_g("Galleries re-indexed. %s total images added.", $success));
$this->includeFile = "view";
}
break;
case "multimove" :
$this->selectGallery();
if($this->actionConfirmed()) {
if(isset($_REQUEST["sgImages"])) {
//$success = $this->moveMultipleImages();
//$this->adminMessage = $this->translator->_g("%s images moved.", $success);
$success=true;
$this->pushMessage("not yet implemented");
} else {
$success = $this->moveMultipleGalleries();
$this->pushMessage($this->translator->_g("%s galleries moved.", $success));
}
}
$this->includeFile = "view";
break;
case "newgallery" :
$this->selectGallery();
if(!$this->checkPermissions($this->gallery,"add")) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "view";
} else
$this->includeFile = "newgallery";
break;
case "newimage" :
$this->selectGallery();
if(!$this->checkPermissions($this->gallery,"add")) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "view";
} else
$this->includeFile = "newimage";
break;
case "newuser" :
if(!$this->user->isAdmin()) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "menu";
} elseif($this->addUser())
$this->includeFile = "edituser";
else
$this->includeFile = "manageusers";
break;
case "purgecache" :
if(!$this->user->isAdmin()) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "menu";
} elseif($this->actionConfirmed()) {
if($this->purgeCache())
$this->pushMessage($this->translator->_g("Thumbnail cache purged"));
$this->includeFile = "menu";
} elseif($this->actionCancelled()) {
$this->includeFile = "menu";
} else {
$dir = $this->getListing($this->config->pathto_cache,$this->config->recognised_extensions);
$GLOBALS["confirmTitle"] = $this->translator->_g("purge cached thumbnails");
$GLOBALS["confirmMessage"] = $this->translator->_g("Are you sure you want to delete all %s cached thumbnails?",count($dir->files));
$this->includeFile = "confirm";
}
break;
case "reindex" :
$this->selectGallery();
if(!$this->checkPermissions($this->gallery,"edit"))
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
else {
$imagesAdded = $this->reindexGallery();
if(is_int($imagesAdded))
$this->pushMessage($this->translator->_g("Gallery re-indexed. %s images added.",$imagesAdded));
}
$this->includeFile = "view";
break;
case "savegallery" :
$this->selectGallery();
if(!$this->checkPermissions($this->gallery,"edit")) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "view";
} elseif($this->saveGallery()) {
$this->includeFile = "view";
} else {
$this->includeFile = "editgallery";
}
break;
case "saveimage" :
$this->selectGallery();
if(!$this->checkPermissions($this->gallery,"edit")) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "view";
} elseif($this->saveImage()) {
$this->pushMessage($this->translator->_g("Image info saved"));
$this->includeFile = "view";
} else {
$this->includeFile = "view";
}
break;
case "savepass" :
if($this->user->isGuest()) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "menu";
} elseif($this->savePass()) {
$this->pushMessage($this->translator->_g("Password saved"));
$this->includeFile = "menu";
} else {
$this->includeFile = "editpass";
}
break;
case "savepermissions" :
$this->selectGallery();
if(!$this->user->isAdmin() && !$this->user->isOwner($this->gallery)) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "view";
} elseif($this->savePermissions()) {
$this->pushMessage($this->translator->_g("Permissions saved"));
$this->includeFile = "view";
} else {
$this->includeFile = "editpermissions";
}
break;
case "saveprofile" :
if($_REQUEST["user"] != $this->user->username || $this->user->isGuest()) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "menu";
} elseif($this->saveUser()) {
$this->pushMessage($this->translator->_g("User info saved"));
$this->includeFile = "menu";
} else {
$this->includeFile = "editprofile";
}
break;
case "saveuser" :
if(!$this->user->isAdmin()) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "menu";
} elseif($this->saveUser())
$this->includeFile = "manageusers";
else
$this->includeFile = "edituser";
break;
case "showgalleryhits" :
$this->selectGallery();
//load hit data for child galleries
foreach(array_keys($this->gallery->galleries) as $index)
$this->io->getHits($this->gallery->galleries[$index]);
/*if(!$this->checkPermissions($this->gallery,"read")) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "menu";
} else {*/
$this->includeFile = "galleryhits";
//}
break;
case "showimagehits" :
$this->selectGallery();
/*if(!$this->checkPermissions($this->gallery,"read")) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "menu";
} else {*/
$this->includeFile = "imagehits";
//}
break;
case "suspenduser" :
if(!$this->user->isAdmin()) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "menu";
} elseif($this->suspendUser())
$this->pushMessage($this->translator->_g("User info saved"));
$this->includeFile = "manageusers";
break;
case "view" :
$this->selectGallery();
/*if(!$this->checkPermissions($this->gallery,"read")) {
$this->pushMessage($this->translator->_g("You do not have permission to perform this operation."));
$this->includeFile = "menu";
} else*/
$this->includeFile = "view";
break;
case "menu" :
default :
$this->includeFile = "menu";
}
}
function &allGalleriesArray()
{
$root =& $this->io->getGallery(".", new stdClass, 100);
return $this->allGalleriesRecurse($root);
}
function &allGalleriesRecurse(&$gal)
{
if($gal->hasChildGalleries()) {
$galArray = array();
foreach($gal->galleries as $child)
$galArray = array_merge($galArray, $this->allGalleriesRecurse($child));
array_unshift($galArray, $gal);
return $galArray;
} else
return array($gal);
}
/**
* Returns a two-dimensional array of links for the admin bar.
*
* @returns string
*/
function adminLinksArray()
{
if(!$this->isLoggedIn()) return array(0 => array($this->translator->_g("admin bar|Back to galleries") => "."));
$ret[0][$this->translator->_g("admin bar|Admin")] = $this->formatAdminURL("menu");
$ret[0][$this->translator->_g("admin bar|Galleries")] = $this->formatAdminURL("view", isset($this->gallery) ? $this->gallery->idEncoded() : null);
$ret[0][$this->translator->_g("admin bar|Log out")] = $this->formatAdminURL("logout");
if($this->isGalleryPage() || $this->isAlbumPage() || $this->isImagePage()) {
$ret[1][$this->translator->_g("admin bar|Edit gallery")] = $this->formatAdminURL("editgallery",$this->gallery->idEncoded());
$ret[1][$this->translator->_g("admin bar|Access control")] = $this->formatAdminURL("editpermissions",$this->gallery->idEncoded());
$ret[1][$this->translator->_g("admin bar|Delete gallery")] = $this->formatAdminURL("deletegallery",$this->gallery->idEncoded());
$ret[1][$this->translator->_g("admin bar|New subgallery")] = $this->formatAdminURL("newgallery",$this->gallery->idEncoded());
$ret[1][$this->translator->_g("admin bar|Re-index gallery")] = $this->formatAdminURL("reindex",$this->gallery->idEncoded());
if($this->isImagePage()) {
$ret[2][$this->translator->_g("admin bar|Edit image")] = $this->formatAdminURL("editimage",$this->gallery->idEncoded(),$this->image->id);
$ret[2][$this->translator->_g("admin bar|Delete image")] = $this->formatAdminURL("deleteimage",$this->gallery->idEncoded(),$this->image->id);
}
$ret[2][$this->translator->_g("admin bar|New image")] = $this->formatAdminURL("newimage",$this->gallery->idEncoded());
}
return $ret;
}
/**
* Saves the new password if it is correctly specified.
*
* @return boolean true on success; false otherwise
*/
function savePass()
{
$users = $this->io->getUsers();
$found = false;
for($i=0;$i < count($users);$i++)
if($_POST["sgUsername"] == $users[$i]->username) {
$found = true;
if(md5($_POST["sgOldPass"]) == $users[$i]->userpass)
if($_POST["sgNewPass1"]==$_POST["sgNewPass2"])
if(strlen($_POST["sgNewPass1"]) >= 6 && strlen($_POST["sgNewPass1"]) <= 16) {
$users[$i]->userpass = md5($_POST["sgNewPass1"]);
if($this->io->putUsers($users)) return true;
else $this->pushError($this->translator->_g("Could not save user info"));
}
else
$this->pushError($this->translator->_g("New password must be between 6 and 16 characters long."));
else
$this->pushError($this->translator->_g("The new passwords you entered do not match."));
else
$this->pushError($this->translator->_g("The current password you entered does not match the one in the database."));
}
if(!$found) $this->pushError($this->translator->_g("The username specified was not found in the database."));
//some sort of error occurred so:
return false;
}
/**
* Attempts to log a registered user into admin.
*
* @return boolean true on success; false otherwise
*/
function doLogin()
{
if(!empty($_POST["sgUsername"]) && !empty($_POST["sgPassword"])) {
if($this->loadUser($_POST["sgUsername"]) && md5($_POST["sgPassword"]) == $this->user->userpass){
if($this->user->permissions & SG_SUSPENDED) {
$this->logout();
return $this->pushError($this->translator->_g("Your account has been suspended"));
} else {
$_SESSION["sgUser"]["username"] = $this->user->username;
$_SESSION["sgUser"]["ip"] = $_SERVER["REMOTE_ADDR"];
$_SESSION["sgUser"]["loginTime"] = time();
return $this->pushMessage($this->translator->_g("Welcome to singapore admin!"));
}
}
$this->logout();
return $this->pushError($this->translator->_g("Username and/or password incorrect"));
}
return $this->pushError($this->translator->_g("You must enter a username and password"));
}
/**
* Cancels a user's admin session.
*
* @return true
*/
function logout()
{
$_SESSION["sgUser"] = null;
return $this->pushMessage($this->translator->_g("Thank you and goodbye!"));
}
/**
* Checks if the specified operation is permitted on the specified object
*
* @param sgImage|sgGallery the object to be operated on
* @param string the action to perform (either 'read', 'edit', 'add' or 'delete')
* @return bool true if permissions are satisfied; false otherwise
*/
function checkPermissions($obj, $action, $gallery = null, $image = null)
{
//admins and object owners automatically have full permissions
if($this->user->isAdmin() || $this->user->isOwner($obj))// || (!$this->user->isGuest() && $obj->owner == "__nobody__"))
return true;
//get the appropriate permission bitmask depending on action
switch($action) {
case "read" :
$inheritPerm = SG_IHR_READ;
$worldPerm = SG_WLD_READ;
$groupPerm = SG_GRP_READ;
break;
case "edit" :
$inheritPerm = SG_IHR_EDIT;
$worldPerm = SG_WLD_EDIT;
$groupPerm = SG_GRP_EDIT;
break;
case "add" :
$inheritPerm = SG_IHR_ADD;
$worldPerm = SG_WLD_ADD;
$groupPerm = SG_GRP_ADD;
break;
case "delete" :
$inheritPerm = SG_IHR_DELETE;
$worldPerm = SG_WLD_DELETE;
$groupPerm = SG_GRP_DELETE;
break;
default :
//unrecognised action so disallow it
return false;
}
//check if the permission is inherited
if(($obj->permissions & $inheritPerm) == $inheritPerm)
if($obj->isRoot())
//shouldn't happen, but just in case
return false;
else
//check permissions of parent
return $this->checkPermissions($obj->parent, $action, $gallery, $image);
else
//not inherited so check world and group permissions of current object
return $obj->permissions & $worldPerm
|| ($this->isInGroup($this->user->groups, $obj->groups) && $obj->permissions & $groupPerm);
}
function savePermissions()
{
$obj =& $this->gallery;
$perms = 0;
switch($_POST["sgRead"]) {
case "inherit" : $perms |= SG_IHR_READ; break;
case "group" : $perms |= SG_GRP_READ; break;
case "world" : $perms |= SG_WLD_READ; break;
case "owner" : break;
}
switch($_POST["sgEdit"]) {
case "inherit" : $perms |= SG_IHR_EDIT; break;
case "group" : $perms |= SG_GRP_EDIT; break;
case "world" : $perms |= SG_WLD_EDIT; break;
case "owner" : break;
}
switch($_POST["sgAdd"]) {
case "inherit" : $perms |= SG_IHR_ADD; break;
case "group" : $perms |= SG_GRP_ADD; break;
case "world" : $perms |= SG_WLD_ADD; break;
case "owner" : break;
}
switch($_POST["sgDelete"]) {
case "inherit" : $perms |= SG_IHR_DELETE; break;
case "group" : $perms |= SG_GRP_DELETE; break;
case "world" : $perms |= SG_WLD_DELETE; break;
case "owner" : break;
}
$obj->permissions |= $perms; // isn't this equivalent
$obj->permissions &= $perms; // to == assignment?
//only the owner or admin can change groups
if($this->user->isAdmin() || $this->user->isOwner($obj));
$obj->groups = $_POST["sgGroups"];
//only the admin can change the owner
if($this->user->isAdmin())
$obj->owner = $_POST["sgOwner"];
if($this->io->putGallery($this->gallery))
return $this->pushMessage($this->translator->_g("Gallery info saved"));
return $this->pushError($this->translator->_g("Could not save gallery info"));
}
/**
* Creates a new user.
*
* @return bool true on success; false otherwise
*/
function addUser()
{
$users = $this->io->getUsers();
foreach($users as $usr)
if($usr->username == $_REQUEST["user"])
return $this->pushError($this->translator->_g("Username already exists"));
if(!preg_match("/^[a-zA-Z0-9_]{3,}$/",$_REQUEST["user"]))
return $this->pushError($this->translator->_g("Username must be at least 3 characters long and contain only alphanumeric characters"));
$users[count($users)] = new sgUser($_REQUEST["user"], md5("password"));
if($this->io->putUsers($users))
return $this->pushMessage($this->translator->_g("User info saved"));
return $this->pushError($this->translator->_g("Could not save user info"));
}
/**
* Deletes a user.
*
* @return bool true on success; false otherwise
*/
function deleteUser($username = null)
{
if($username == null)
$username = $_REQUEST["user"];
if($username == "admin" || $username == "guest")
return $this->pushError($this->translator->_g("Cannot delete built in accounts"));
$users = $this->io->getUsers();
foreach($users as $i => $usr)
if($usr->username == $username) {
//delete user at offset $i from $users
array_splice($users,$i,1);
if($this->io->putUsers($users))
return true;
return $this->pushError($this->translator->_g("Could not save user info"));
}
return $this->pushError($this->translator->_g("Username not recognised"));
}
/**
* Saves a user's info.
*
* @return bool true on success; false otherwise
*/
function saveUser() {
$users = $this->io->getUsers();
for($i=0; $i<count($users); $i++)
if($users[$i]->username == $_REQUEST["user"]) {
$users[$i]->email = $this->prepareText($_REQUEST["sgEmail"]);
$users[$i]->fullname = $this->prepareText($_REQUEST["sgFullname"]);
$users[$i]->description = $this->prepareText($_REQUEST["sgDescription"]);
if($this->user->isAdmin() && $_REQUEST["action"] == "saveuser") {
$users[$i]->groups = $this->prepareText($_REQUEST["sgGroups"]);
$users[$i]->permissions = ($_REQUEST["sgType"] == "admin") ? $users[$i]->permissions | SG_ADMIN : $users[$i]->permissions & ~SG_ADMIN;
if(isset($_REQUEST["sgPassword"]) && $_REQUEST["sgPassword"] != "**********")
$users[$i]->userpass = md5($_REQUEST["sgPassword"]);
}
if($this->io->putUsers($users))
return true;
return $this->pushError($this->translator->_g("Could not save user info"));
}
return $this->pushError($this->translator->_g("Username not recognised"));
}
/**
* Suspend or unsuspend a user's account.
*
* @return bool true on success; false otherwise
*/
function suspendUser() {
$users = $this->io->getUsers();
for($i=0; $i<count($users); $i++)
if($users[$i]->username == $_REQUEST["user"]) {
$users[$i]->permissions = ($users[$i]->permissions & SG_SUSPENDED) ? $users[$i]->permissions & ~SG_SUSPENDED : $users[$i]->permissions | SG_SUSPENDED;
if($this->io->putUsers($users))
return true;
return $this->pushError($this->translator->_g("Could not save user info"));
}
return $this->pushError($this->translator->_g("Username not recognised"));
}
/**
* Check for images in specified gallery directory which are
* not in the metadata and add them. If no gallery is specified,
* the current gallery is used.
* @param string id of gallery to reindex (optional)
* @return int|false the number of images added or false on error
*/
function reindexGallery($galleryId = null)
{
if($galleryId == null)
$gal =& $this->gallery;
else
$gal =& $this->io->getGallery($galleryId, new stdClass);
$imagesAdded = 0;
//get list of images
$dir = Singapore::getListing($this->config->pathto_galleries.$gal->id, $this->config->recognised_extensions);
//cycle through the image files
for($i=0; $i<count($dir->files); $i++) {
//search for the image file in the database images
for($j=0; $j<count($gal->images); $j++)
//if we find it
if($dir->files[$i] == $gal->images[$j]->id)
//skip the rest of this loop
continue 2;
//otherwise add the image to the database
$gal->images[$j] = new sgImage($dir->files[$i], $gal, $this->config);
$gal->images[$j]->name = $dir->files[$i];
list(
$gal->images[$j]->width,
$gal->images[$j]->height,
$gal->images[$j]->type
) = GetImageSize($this->config->pathto_galleries.$gal->id."/".$gal->images[$j]->id);
$imagesAdded++;
}
if($this->io->putGallery($gal))
return $imagesAdded;
return $this->pushError($this->translator->_g("Could not save gallery info"));
}
/**
* Reindexes several galleries from the current gallery.
*
* @return int|false number of images added on success; false otherwise
*/
function reindexMultipleGalleries()
{
$totalImagesAdded = 0;
foreach($_REQUEST["sgGalleries"] as $galleryId) {
$current = $this->reindexGallery($galleryId);
if($current === false) $this->pushError($this->translator->_g("Gallery '%s' could not be reindexed", $galleryId));
else $this->pushMessage($this->translator->_g("Gallery '%s' reindexed: %s images added", $galleryId, $current));
$totalImagesAdded += $current;
}
//reload gallery data if we changed any
if($totalImagesAdded)
$this->selectGallery();
return $totalImagesAdded;
}
/**
* Moves or copies galleries.
*
* @return int|false number of galleries moved; false otherwise
*/
function moveMultipleGalleries()
{
$totalGalleriesMoved = 0;
foreach($_REQUEST["sgGalleries"] as $galleryId) {
$source = $this->config->base_path.$this->config->pathto_galleries.$galleryId;
$target = $this->config->base_path.$this->config->pathto_galleries.$_REQUEST['sgMoveTarget'].'/'.basename($galleryId);
if(file_exists($target)) {
$this->pushError($this->translator->_g("Unable to copy/move gallery '%s' because the target gallery already exists.", $galleryId));
} elseif($this->isSubPath($source, $target, false)) {
$this->pushError($this->translator->_g("Unable to copy/move gallery '%s' because the target is a child of the source.", $galleryId));
//} elseif(!is_writable($target)) {
// $this->pushError($this->translator->_g("Unable to copy/move gallery '%s': the target is not writable", $galleryId));
} else {
if($_REQUEST["sgMoveType"] == 'move') { //Move
$current = rename($source, $target);
} else { //Copy
$current = $this->copyDir($source, $target);
}
if($current === false) $this->pushError($this->translator->_g("Unable to copy/move gallery '%s' because the operation failed.", $galleryId));
else $totalGalleriesMoved++;
}
}
//load target gallery
if($totalGalleriesMoved)
$this->selectGallery($_REQUEST['sgMoveTarget']);
return $totalGalleriesMoved;
}
/**
* Copies everything from directory $fromDir to directory $toDir
* and sets up files mode $chmod
* @author Anton Makarenko <makarenkoa at ukrpost dot net>
*/
function copyDir($fromDir, $toDir)
{
$success = true;
$handle = opendir($fromDir);
//ensure target directory exists
if(!file_exists($toDir))
if(mkdir($toDir))
chmod($toDir, octdec($this->config->directory_mode));
else
return false;
while(false !== ($item = readdir($handle)))
if($item != '.' && $item != '..') {
$from = $fromDir.'/'.$item;
$to = $toDir.'/'.$item;
if(is_dir($from)) {
if($success &= mkdir($to))
chmod($to, octdec($this->config->directory_mode));
//recurse
$this->copyDir($from, $to);
} else {
if($success &= copy($from, $to))
chmod($to, octdec($this->config->file_mode));
}
}
closedir($handle);
return $success;
}
/**
* Creates a gallery.
*
* @return boolean true on success; false otherwise
*/
function addGallery()
{
$newGalleryId = $this->gallery->id."/".$_REQUEST["newgallery"];
$path = $this->config->base_path.$this->config->pathto_galleries.$newGalleryId;
//fail if directory already exists
if(file_exists($path))
return $this->pushError($this->translator->_g("Gallery already exists."));
//create directory or fail
if(!Singapore::mkdir($path))
return $this->pushError($this->translator->_g("Unable to create directory '%s'", $path));
//explicitly set permissions on gallery directory
@chmod($path, octdec($this->config->directory_mode));
$gal =& new sgGallery($newGalleryId, $this->gallery);
$gal->name = $_REQUEST["newgallery"];
//set object owner
if(!$this->user->isGuest())
$gal->owner = $this->user->username;
//save gallery metadata
if($this->io->putGallery($gal))
return true;
else
return $this->pushError($this->translator->_g("Unable to save metadata."));
}
function prepareText($text, $multiline = false)
{
if($multiline) {
$text = strip_tags($text, $this->config->allowed_tags);
$text = str_replace(array("\n","\r"), array("<br />",""), $text);
} else {
$text = htmlspecialchars($text);
}
return $text;
}
/**
* Saves gallery info to the database.
*
* @return boolean true on success; false otherwise
*/
function saveGallery()
{
$this->gallery->categories = $_REQUEST["sgCategories"];
$this->gallery->name = $this->prepareText($_REQUEST["sgGalleryName"]);
$this->gallery->artist = $this->prepareText($_REQUEST["sgArtistName"]);
$this->gallery->email = $this->prepareText($_REQUEST["sgArtistEmail"]);
$this->gallery->date = $this->prepareText($_REQUEST["sgDate"]);
$this->gallery->copyright = $this->prepareText($_REQUEST["sgCopyright"]);
$this->gallery->summary = $this->prepareText($_REQUEST["sgSummary"],true);
$this->gallery->desc = $this->prepareText($_REQUEST["sgGalleryDesc"],true);
if($this->config->enable_clickable_urls) {
//recognise URLs and htmlise them
$this->gallery->desc = preg_replace('{(?<!href="|href=)\b('.SG_REGEXP_PROTOCOLURL.')\b(?!</a>)}', '<a href="$1">$1</a>', $this->gallery->desc); //general protocol match
$this->gallery->desc = preg_replace('{(?<!://)\b('.SG_REGEXP_WWWURL.')\b(?!</a>)}', '<a href="http://$1">$1</a>', $this->gallery->desc); //web addresses starting www. without path info
$this->gallery->desc = preg_replace('{(?<!mailto:|\.)\b('.SG_REGEXP_EMAILURL.')\b(?!</a>)}', '<a href="mailto:$1">$1</a>', $this->gallery->desc); //email addresses *@*.*
}
if($this->io->putGallery($this->gallery))
return true;
else
return $this->pushError($this->translator->_g("Could not save gallery info"));
}
/**
* Deletes a gallery and everything contained within it.
*
* @return boolean true on success; false otherwise
*/
function deleteGallery($galleryId = null)
{
if($galleryId === null)
$galleryId = $_REQUEST['gallery'];
//calculate the path where the folder actually resides.
$path = $this->config->base_path.$this->config->pathto_galleries.$galleryId;
//security check: make sure requested file is in galleries directory
if(!$this->isSubPath($this->config->base_path.$this->config->pathto_galleries,$path))
return $this->pushError($this->translator->_g("Requested item '%s' appears to be outside the galleries directory", $galleryId));
//check that the gallery to delete is not the top level directory
if(realpath($path) == realpath($this->config->base_path.$this->config->pathto_galleries))
return $this->pushError($this->translator->_g("Cannot delete the root gallery."));
//attempt to remove the offending directory and all contained therein
if($this->rmdir_all($path))
return $this->pushMessage($this->translator->_g("Gallery '%s' deleted.", $galleryId));
else
return $this->pushError($this->translator->_g("Unable to delete gallery '%s'.", $galleryId));
}
/**
* Deletes several galleries from the current gallery.
*
* @return int number of galleries deleted
*/
function deleteMultipleGalleries() {
$totalGalleriesDeleted = 0;
foreach($_REQUEST["sgGalleries"] as $galleryId) {
$this->deleteGallery($galleryId);
$totalGalleriesDeleted++;
}
//reload gallery data if we deleted any
if($totalGalleriesDeleted)
$this->selectGallery();
return $totalGalleriesDeleted;
}
/**
* Saves changes to the gallery thumbnail to the database.
*
* @return boolean true on success; false otherwise
*/
function saveGalleryThumbnail()
{
$this->gallery->filename = $_REQUEST['sgThumbName'];
if($this->io->putGallery($this->gallery))
$this->pushMessage($this->translator->_g("Thumbnail changed."));
else
$this->pushError($this->translator->_g("Unable to save metadata."));
}
/**
* Adds an image to the database.
*
* @return boolean true on success; false otherwise
*/
function addImage()
{
if($_REQUEST["sgLocationChoice"] == "remote") {
$image = $_REQUEST["sgImageURL"];
$path = $image;
} elseif($_REQUEST["sgLocationChoice"] == "single") {
//set filename as requested and strip off any clandestine path info
if($_REQUEST["sgNameChoice"] == "same") $image = basename($_FILES["sgImageFile"]["name"]);
else $image = basename($_REQUEST["sgFileName"]);
//make sure image is valid
if(!preg_match("/\.(".$this->config->recognised_extensions.")$/i", $image)) {
$imgInfo = GetImageSize($_FILES["sgImageFile"]["tmp_name"]);
switch($imgInfo[2]) {
case 1 : $image .= '.gif'; break;
case 2 : $image .= '.jpg'; break;
case 3 : $image .= '.png'; break;
case 6 : $image .= '.bmp'; break;
case 7 :
case 8 : $image .= '.tif'; break;
default :
return $this->pushError($this->translator->_g("Uploaded image '%s' has unrecognised extension and image type could not be determined from file contents.", $image));
}
}
$path = $this->config->base_path.$this->config->pathto_galleries.$this->gallery->id."/".$image;
$srcImage = $image;
if(file_exists($path))
switch($this->config->upload_overwrite) {
case 1 : //overwrite
$this->deleteImage($image);
break;
case 2 : //generate unique
for($i=0;file_exists($path);$i++) {
$pivot = strrpos($srcImage,".");
$image = substr($srcImage, 0, $pivot).'-'.$i.substr($srcImage, $pivot,strlen($srcImage)-$pivot);
$path = $this->config->base_path.$this->config->pathto_galleries.$this->gallery->id."/".$image;
}
break;
case 0 : //raise error
default :
return $this->pushError($this->translator->_g("File already exists."));
}
if(!move_uploaded_file($_FILES["sgImageFile"]["tmp_name"],$path))
return $this->pushError($this->translator->_g("Could not upload file."));
// try to change file-permissions
@chmod($path, octdec($this->config->file_mode));
}
$img =& new sgImage($image, $this->gallery);
$img->name = strtr(substr($image, strrpos($image,"/"), strrpos($image,".")-strlen($image)), "_", " ");
list($img->width, $img->height, $img->type) = GetImageSize($path);
//leave owner of guest-uploaded files as default '__nobody__'
if(!$this->user->isGuest())
$img->owner = $this->user->username;
$this->gallery->images[] =& $img;
//set as gallery thumbnail?
if($this->gallery->imageCount()==1)
$this->gallery->filename = $img->id;
if($this->io->putGallery($this->gallery)) {
$this->selectImage($image);
return $this->pushMessage($this->translator->_g("Image added", $image));
} else {
@unlink($path);
return $this->pushError($this->translator->_g("Unable to save metadata."));
}
}
/**
* Adds the contents of an uploaded archive to the database.
*
* @return boolean true on success; false otherwise
*/
function addMultipleImages()
{
//find system temp directory
if(!($systmpdir = $this->findTempDirectory()))
return $this->pushError($this->translator->_g("Unable to find temporary storage space."));
//create new temp directory in system temp dir but stop after 100 attempts
while(!Singapore::mkdir($tmpdir = $systmpdir."/".uniqid("sg")) && $tries++<100);
$archive = $_FILES["sgArchiveFile"]["tmp_name"];
if(!is_uploaded_file($archive))
return $this->pushError($this->translator->_g("Could not upload file."));
//decompress archive to temp
$cmd = escapeshellcmd($this->config->pathto_unzip);
$cmd .= ' -d "'.escapeshellcmd(realpath($tmpdir));
$cmd .= '" "'.escapeshellcmd(realpath($archive)).'"';
if(!exec($cmd))
return $this->pushError($this->translator->_g("Could not decompress archive."));
//start processing archive contents
$wd = $tmpdir;
$contents = $this->getListing($wd,$this->config->recognised_extensions);
//cope with archives contained within a directory
if(empty($contents->files) && count($contents->dirs) == 1)
$contents = $this->getListing($wd .= '/'.$contents->dirs[0],$this->config->recognised_extensions);
$success = true;
 
//add any images to current gallery
foreach($contents->files as $image) {
//check image is valid and ignore it if it isn't
if(!preg_match("/\.(".$this->config->recognised_extensions.")$/i", $image)) {
$imgInfo = GetImageSize($wd.'/'.$image);
switch($imgInfo[2]) {
case 1 : $image .= '.gif'; break;
case 2 : $image .= '.jpg'; break;
case 3 : $image .= '.png'; break;
case 6 : $image .= '.bmp'; break;
case 7 :
case 8 : $image .= '.tif'; break;
default :
$this->pushMessage($this->translator->_g("Uploaded image '%s' has unrecognised extension and image type could not be determined from file contents.", $image));
continue;
}
}
$path = $this->config->pathto_galleries.$this->gallery->id."/".$image;
$srcImage = $image;
if(file_exists($path))
switch($this->config->upload_overwrite) {
case 1 : //overwrite
$this->deleteImage($image);
break;
case 2 : //generate unique
for($i=0;file_exists($path);$i++) {
$pivot = strrpos($srcImage,".");
$image = substr($srcImage, 0, $pivot).'-'.$i.substr($srcImage, $pivot,strlen($srcImage)-$pivot);
$path = $this->config->base_path.$this->config->pathto_galleries.$this->gallery->id."/".$image;
}
break;
case 0 : //raise error
default :
$this->pushError($this->translator->_g("File '%s' already exists."));
$success = false;
continue;
}
copy($wd.'/'.$srcImage,$path);
// try to change file-permissions
@chmod($path, octdec($this->config->file_mode));
$img =& new sgImage($image, $this->gallery);
$img->name = strtr(substr($image, strrpos($image,"/"), strrpos($image,".")-strlen($image)), "_", " ");
list($img->width, $img->height, $img->type) = GetImageSize($path);
 
//leave owner of guest-uploaded files as default '__nobody__'
if(!$this->user->isGuest())
$img->owner = $this->user->username;
$this->gallery->images[] = $img;
}
//add any directories as subgalleries, if allowed
if($this->config->allow_dir_upload == 1 && !$this->user->isGuest()
|| $this->config->allow_dir_upload == 2 && $this->user->isAdmin())
foreach($contents->dirs as $gallery) {
$path = $this->config->pathto_galleries.$this->gallery->id."/".$gallery;
if(file_exists($path))
switch($this->config->upload_overwrite) {
case 1 : //overwrite
$this->deleteGallery($this->gallery->id.'/'.$gallery);
break;
case 2 : //generate unique
for($i=0;file_exists($path);$i++)
$path = $this->config->pathto_galleries.$this->gallery->id."/".$gallery.'-'.$i;
break;
case 0 : //raise error
default :
$this->pushError($this->translator->_g("File '%s' already exists."));
$success = false;
continue;
}
//move from temp dir to gallery
rename($wd.'/'.$gallery, $path);
//change directory permissions (but not contents)
@chmod($path, octdec($this->config->directory_mode));
}
//if images were added save metadata
if(!empty($contents->files))
$this->io->putGallery($this->gallery)
or $this->pushError($this->translator->_g("Unable to save metadata."));
//if subgalleries were added reload gallery data
if(!empty($contents->dirs))
$this->selectGallery();
//remove temporary directory
$this->rmdir_all($tmpdir);
if($success)
return $this->pushMessage($this->translator->_g("Archive contents added."));
else
return $this->pushError($this->translator->_g("Some archive contents could not be added."));
}
/**
* Saves image info to the database.
*
* @return boolean true on success; false otherwise
*/
function saveImage()
{
$this->image->id = $this->prepareText($_REQUEST['image']);
$this->image->thumbnail = $this->prepareText($_REQUEST["sgThumbnail"]);
$this->image->categories = $this->prepareText($_REQUEST["sgCategories"]);
$this->image->name = $this->prepareText($_REQUEST["sgImageName"]);
$this->image->artist = $this->prepareText($_REQUEST["sgArtistName"]);
$this->image->email = $this->prepareText($_REQUEST["sgArtistEmail"]);
$this->image->location = $this->prepareText($_REQUEST["sgLocation"]);
$this->image->date = $this->prepareText($_REQUEST["sgDate"]);
$this->image->copyright = $this->prepareText($_REQUEST["sgCopyright"]);
$this->image->desc = $this->prepareText($_REQUEST["sgImageDesc"],true);
$this->image->camera = $this->prepareText($_REQUEST["sgField01"]);
$this->image->lens = $this->prepareText($_REQUEST["sgField02"]);
$this->image->film = $this->prepareText($_REQUEST["sgField03"]);
$this->image->darkroom = $this->prepareText($_REQUEST["sgField04"]);
$this->image->digital = $this->prepareText($_REQUEST["sgField05"]);
if($this->io->putGallery($this->gallery))
return true;
else
return $this->pushError($this->translator->_g("Unable to save metadata."));
}
/**
* Deletes an image from the current gallery.
*
* @param string the filename of the image to delete (optional)
* @return boolean true on success; false otherwise
*/
function deleteImage($image = null)
{
if($image === null)
$image = $this->image->id;
//if file is remote or doesn't exist then there's no point trying to delete it
if(!sgImage::isRemote($image) && file_exists($this->config->pathto_galleries.$this->gallery->id."/".$image))
//check that we're not being fooled into deleting something we shouldn't
if(!$this->isSubPath($this->config->pathto_galleries, $this->config->pathto_galleries.$this->gallery->id."/".$image))
return $this->pushError($this->translator->_g("Requested item '%s' appears to be outside the galleries directory.", htmlspecialchars($image)));
else
unlink($this->config->pathto_galleries.$this->gallery->id."/".$image);
//remove the image from the images array
foreach($this->gallery->images as $i => $img)
if($img->id == $image) {
array_splice($this->gallery->images,$i,1);
//image removed from array so save metadata
if($this->io->putGallery($this->gallery)) {
//nulling image reference will select parent gallery
$this->image = null;
return $this->pushMessage($this->translator->_g("Image '%s' deleted", htmlspecialchars($image)));
} else {
return $this->pushError($this->translator->_g("Unable to save metadata."));
}
}
//image not found in array
return $this->pushError($this->translator->_g("Image not found '%s'", htmlspecialchars($image)));
}
/**
* Deletes several images from the current gallery.
*
* @return int|false number of images deleted on success; false otherwise
*/
function deleteMultipleImages() {
$deleted = 0;
foreach($_REQUEST["sgImages"] as $image)
if($this->deleteImage($image))
$deleted++;
 
return $deleted;
}
/**
* Deletes the contents of the cache directory.
*
* @return boolean true on success; false otherwise
*/
function purgeCache()
{
$dir = $this->getListing($this->config->pathto_cache, $this->config->recognised_extensions);
$success = true;
for($i=0;$i<count($dir->files);$i++) {
$success &= unlink($dir->path.$dir->files[$i]);
}
return $success;
}
 
}
 
 
?>