No changes between revisions
/Web/JS/MLAB_Menu.js
125,6 → 125,7
Content+=' <li> <a href="Web/Designs.cs.html" title="Samostatné konstrukce">Konstrukce</a> </li>';
Content+=' <li> <a href="Web/News.cs.html" title="Novinky">Novinky</a> </li>';
Content+=' <li> <a href="Web/FAQ.cs.html" title="Nejčastější dotazy">FAQ</a> </li>';
Content+=' <li> <a href= "http://www.mlab.cz/photogallery/" title="Galerie fotografií">Fotogalerie</a> </li>';
Content+=' <li> <a href="Web/Downloads.cs.html" title="Ke stažení">Downloads</a> </li>';
Content+=' <li> <a href= "http://www.mlab.cz/WebSVN/listing.php?repname=MLAB&amp;path=%2F&amp;sc=0&amp;langchoice=Česky" title="Webový přístup do databáze SVN">WebSVN</a> </li>';
Content+=' <li> <a href="Web/Maintenance.cs.html" title="Stránka údržby webu">Údržba</a> </li>';
141,6 → 142,7
Content+=' <li> <a href="Web/Designs.en.html" title="Independed Designs">Designs</a> </li>';
Content+=' <li> <a href="Web/News.en.html" title="News">News</a> </li>';
Content+=' <li> <a href="Web/FAQ.en.html" title="Frequently Asked Questions">FAQ</a> </li>';
Content+=' <li> <a href= "http://www.mlab.cz/photogallery/" title="Photo Gallery">Photogallery</a> </li>';
Content+=' <li> <a href="Web/Downloads.en.html" title="For download">Downloads</a> </li>';
Content+=' <li> <a href= "http://www.mlab.cz/WebSVN/listing.php?repname=MLAB&amp;path=%2F&amp;sc=0&amp;langchoice=English" title="Web interface to SVN database">WebSVN</a> </li>';
Content+=' <li> <a href="Web/Maintenance.en.html" title="Maintenance page">Maintenance</a> </li>';
/photogallery/templates/MLAB/header.tpl.php
0,0 → 1,60
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="keywords" content="stavebnice MLAB univerzální moduly">
<meta name="description" content="Projekt MLAB, Prázdná stránka">
<!-- AUTOINCLUDE START "Page/Head.cs.ihtml" DO NOT REMOVE -->
<link rel="StyleSheet" href="../../Web/CSS/MLAB.css" type="text/css" title="MLAB základní­ styl">
<link rel="StyleSheet" href="../../Web/CSS/MLAB_Print.css" type="text/css" media="print">
<link rel="shortcut icon" type="image/x-icon" href="../../Web/PIC/MLAB.ico">
<script type="text/javascript" src="../../Web/JS/MLAB_Menu.js"></script>
<!-- AUTOINCLUDE END -->
<title><?php echo $sg->pageTitle(); ?></title>
<?php echo $sg->navigationLinks(); ?>
<!--
This page was generated by singapore <http://singapore.sourceforge.net>
singapore is free software licensed under the terms of the GNU GPL.
-->
</head>
 
<body lang="cs">
 
<!-- AUTOINCLUDE START "Page/Header.cs.ihtml" DO NOT REMOVE -->
<!-- ============== HLAVICKA ============== -->
<div class="Header">
<script type="text/javascript">
<!--
SetRelativePath("../../");
DrawHeader();
// -->
</script>
<noscript>
<p><b> Pro zobrazení (vložení) hlavièky je potøeba JavaScript </b></p>
</noscript>
</div>
<!-- AUTOINCLUDE END -->
 
<!-- AUTOINCLUDE START "Page/Menu.cs.ihtml" DO NOT REMOVE -->
<!-- ============== MENU ============== -->
<div class="Menu">
<script type="text/javascript">
<!--
SetRelativePath("../../");
DrawMenu();
// -->
</script>
<noscript>
<p><b> Pro zobrazení (vložení) menu je potøeba JavaScript </b></p>
</noscript>
</div>
<!-- AUTOINCLUDE END -->
 
<!-- ============== TEXT ============== -->
<div class="Text">
<div id="crumb"><?php echo $sg->crumbLine(); ?></div>
 
<!-- start of generated content -->
 
/photogallery/templates/MLAB/images/Thumbs.db
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/MLAB/images/blank.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/MLAB/images/shadow-bl.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/MLAB/images/shadow-bm.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/MLAB/images/shadow-br.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/MLAB/images/shadow-ml.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/MLAB/images/shadow-mr.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/MLAB/images/shadow-tabl.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/MLAB/images/shadow-tabm.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/MLAB/images/shadow-tabr.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/MLAB/images/shadow-tl.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/MLAB/images/shadow-tm.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/MLAB/images/shadow-tr.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/MLAB/images/slide-bl.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/MLAB/images/slide-br.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/MLAB/images/slide-tl.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/MLAB/images/slide-tr.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/MLAB/footer.tpl.php
0,0 → 1,27
 
<div id="footer"><p>
<?php echo $sg->allRightsReserved(); ?>
<?php echo $sg->licenseText(); ?>
<br />
<?php echo $sg->poweredByText(); ?>
<?php echo $sg->scriptExecTimeText(); ?> |
<?php echo $sg->adminLink(); ?>
</p></div>
</div>
<!-- AUTOINCLUDE START "Page/Footer.cs.ihtml" DO NOT REMOVE -->
<!-- ============== PATIÈKA ============== -->
<div class="Footer">
<script type="text/javascript">
<!--
SetRelativePath("../../");
DrawFooter();
// -->
</script>
<noscript>
<p><b> Pro zobrazení (vložení) hlavièky je potøeba JavaScript </b></p>
</noscript>
</div>
<!-- AUTOINCLUDE END -->
 
</body>
</html>
/photogallery/templates/MLAB/album.tpl.php
0,0 → 1,60
<p class="sgNavBar sgTopNavBar">
<?php if($sg->gallery->hasPrev()) echo $sg->gallery->prevLink()." | "; ?>
<?php if(!$sg->gallery->isRoot()) echo $sg->gallery->parentLink(); ?>
<?php if($sg->gallery->hasNext()) echo " | ".$sg->gallery->nextLink(); ?>
</p>
 
<h2 class="sgTitle"><?php echo $sg->gallery->name(); ?></h2>
<h4 class="sgSubTitle"><?php echo $sg->gallery->byArtistText(); ?></h4>
 
<div class="sgShadow"><table class="sgShadow" cellspacing="0">
<tr>
<td class="tabl"></td>
<td class="tabm">
<div><?php echo $sg->galleryTab(); ?></div>
</td>
<td class="tabr"></td>
</tr>
<tr>
<td class="tl"></td>
<td class="tm"></td>
<td class="tr"></td>
</tr>
<tr>
<td class="ml"></td>
<td class="mm">
<?php for($index = $sg->gallery->startat; $index < $sg->gallery->imageCountSelected()+$sg->gallery->startat; $index++): ?>
<div class="sgThumbnail">
<div class="sgThumbnailContent">
<img class="borderTL" src="<?php echo $sg->config->base_url.$sg->config->pathto_current_template ?>images/slide-tl.gif" alt="" />
<img class="borderTR" src="<?php echo $sg->config->base_url.$sg->config->pathto_current_template ?>images/slide-tr.gif" alt="" />
<table><tr><td>
<?php echo $sg->gallery->images[$index]->thumbnailLink(); ?>
</td></tr></table>
<div class="roundedCornerSpacer">&nbsp;</div>
</div>
<div class="bottomCorners">
<img class="borderBL" src="<?php echo $sg->config->base_url.$sg->config->pathto_current_template ?>images/slide-bl.gif" alt="" />
<img class="borderBR" src="<?php echo $sg->config->base_url.$sg->config->pathto_current_template ?>images/slide-br.gif" alt="" />
</div>
</div>
<?php endfor; ?>
</td>
<td class="mr"></td>
</tr>
<tr>
<td class="bl"></td>
<td class="bm"></td>
<td class="br"></td>
</tr>
</table></div>
<p class="sgDetailsList">
<?php foreach($sg->gallery->detailsArray() as $key => $value): ?>
<strong><?php echo $key; ?>:</strong> <?php echo $value; ?><br />
<?php endforeach; ?>
</p>
/photogallery/templates/MLAB/gallery.tpl.php
0,0 → 1,56
<p class="sgNavBar sgTopNavBar">
<?php if($sg->gallery->hasPrev()) echo $sg->gallery->prevLink()." | "; ?>
<?php if(!$sg->gallery->isRoot()) echo $sg->gallery->parentLink(); ?>
<?php if($sg->gallery->hasNext()) echo " | ".$sg->gallery->nextLink(); ?>
</p>
 
<h2 class="sgTitle"><?php echo $sg->gallery->name(); ?></h2>
<h4 class="sgSubTitle"><?php echo $sg->gallery->byArtistText(); ?></h4>
 
<div class="sgShadow"><table class="sgShadow" cellspacing="0">
<tr>
<td class="tabl"></td>
<td class="tabm">
<div><?php echo $sg->galleryTab(); ?></div>
</td>
<td class="tabr"></td>
</tr>
<tr>
<td class="tl"></td>
<td class="tm"></td>
<td class="tr"></td>
</tr>
<tr>
<td class="ml"></td>
<td class="mm">
<?php for($index = $sg->gallery->startat; $index < $sg->gallery->galleryCountSelected()+$sg->gallery->startat; $index++): ?>
<div class="sgGallery"><table class="sgGallery"><tr valign="top">
<td class="sgGalleryThumb">
<?php echo $sg->gallery->galleries[$index]->thumbnailLink(); ?>
</td>
<td>
<p><strong><?php echo $sg->gallery->galleries[$index]->nameLink(); ?></strong></p>
<p><?php echo $sg->gallery->galleries[$index]->summary(); ?></p>
<p>[<?php echo $sg->gallery->galleries[$index]->itemCountText(); ?>]</p>
</td>
</tr></table></div>
<?php endfor; ?>
 
</td>
<td class="mr"></td>
</tr>
<tr>
<td class="bl"></td>
<td class="bm"></td>
<td class="br"></td>
</tr>
</table></div>
 
<p class="sgDetailsList">
<?php foreach($sg->gallery->detailsArray() as $key => $value): ?>
<strong><?php echo $key; ?>:</strong> <?php echo $value; ?><br />
<?php endforeach; ?>
</p>
/photogallery/templates/MLAB/image.tpl.php
0,0 → 1,45
<p class="sgNavBar sgTopNavBar">
<?php echo $sg->previewThumbnails(); ?>
<br />
<?php if($sg->image->hasPrev()) echo $sg->image->prevLink()." | "; ?>
<?php echo $sg->image->parentLink(); ?>
<?php if($sg->image->hasNext()) echo " | ".$sg->image->nextLink(); ?>
</p>
<h2 class="sgTitle"><?php echo $sg->image->name(); ?></h2>
<h4 class="sgSubTitle"><?php echo $sg->image->byArtistText(); ?></h4>
<div class="sgShadow"><table class="sgShadow" cellspacing="0">
<tr>
<td class="tl"></td>
<td class="tm"></td>
<td class="tr"></td>
</tr>
<tr>
<td class="ml"></td>
<td class="mm">
<?php echo $sg->image->imageHTML() ?>
</td>
<td class="mr"></td>
</tr>
<tr>
<td class="bl"></td>
<td class="bm"></td>
<td class="br"></td>
</tr>
</table></div>
<p class="sgNavBar sgBottomNavBar">
<?php if($sg->image->hasPrev()) echo $sg->image->prevLink()." | "; ?>
<?php echo $sg->image->parentLink(); ?>
<?php if($sg->image->hasNext()) echo " | ".$sg->image->nextLink(); ?>
</p>
 
<h4 class="sgNameByArtist"><em><?php echo $sg->image->name() ?></em><?php echo $sg->image->byArtistText() ?></h4>
<p class="sgDetailsList">
<?php foreach($sg->image->detailsArray() as $key => $value): ?>
<strong><?php echo $key ?>:</strong> <?php echo $value ?><br />
<?php endforeach; ?>
</p>
 
<?php echo $sg->imageMap() ?>
/photogallery/templates/MLAB/index.tpl.php
0,0 → 1,32
<?php
 
/**
* Default singapore template.
*
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @copyright (c)2003, 2004 Tamlyn Rhodes
* @version 1.0
*/
 
//include header file
include $sg->config->base_path.$sg->config->pathto_current_template."header.tpl.php";
 
switch($sg->action) {
case "addcomment" :
include $sg->config->base_path.$sg->config->pathto_current_template."addcomment.tpl.php";
default :
if($sg->isImagePage()) {
//this is an 'image' page so include the 'image' template file
include $sg->config->base_path.$sg->config->pathto_current_template."image.tpl.php";
} elseif($sg->isAlbumPage()) {
//this is an 'album' page so include the 'album' template file
include $sg->config->base_path.$sg->config->pathto_current_template."album.tpl.php";
} else {
//this is a 'gallery' page so include the 'gallery' template file
include $sg->config->base_path.$sg->config->pathto_current_template."gallery.tpl.php";
}
}
//include footer file
include $sg->config->base_path.$sg->config->pathto_current_template."footer.tpl.php";
 
?>
/photogallery/templates/MLAB/template.ini
0,0 → 1,50
;Option descriptions have been grouped together here.
;Do not uncomment the following lines, they are for illustration only.
;
;thumb_width_*
; Width in pixels of thumbnails generated by the script.
; This option is affected by the thumb_crop_* option (see below).
;
;thumb_height_*
; Height in pixels of thumbnails generated by the script.
; This option is affected by the thumb_crop_* option (see below).
;
;thumb_crop_*
; By default, width and height are maximum dimensions and images will be
; resized, maintaining the same aspect ratio, to fit within these limits.
; Turn force_size on to make the script crop images to the specified size.
;
;*_gallery
; These options affect gallery pages (those that contain sub-galleries).
;
;*_album
; These options affect album pages (those that contain only images).
;
;*_preview
; These options affect the preview thumbnails displayed on image pages.
;
;*_image
; These options affect full size display images and are only used if
; full_image_resize is on in singapore.ini
 
thumb_width_gallery = 80
thumb_height_gallery = 80
thumb_crop_gallery = off
thumb_number_gallery = 10
;Maximum number of galleries to show on one gallery page.
 
thumb_width_album = 100
thumb_height_album = 100
thumb_crop_album = off
thumb_number_album = 20
;Maximum number of image thumbnails to show on one album page.
 
thumb_width_preview = 50
thumb_height_preview = 50
thumb_crop_preview = off
thumb_number_preview = 5
;Maximum number of preview thumbnails to display (including
;current image). An odd number is usually preferred.
thumb_width_image = 700
thumb_height_image = 500
/photogallery/templates/admin_default/admin.ini
0,0 → 1,88
; singapore admin configuration file <http://singapore.sourceforge.net>
;
; This is a special case of a template.ini file
;
 
[Functionality]
;
; these settings should not be changed
;
 
track_views = false
show_views = true
use_mod_rewrite = off
;mod rewrite doesn't work in admin mode
 
 
[Advanced]
;
; these settings must not be changed
;
 
index_file_url = "admin.php?action=view&amp;"
 
[GET variable names]
;
; these settings must not be changed
;
 
url_gallery = "gallery"
url_image = "image"
url_startat = "startat"
url_action = "action"
url_lang = "lang"
url_template = "template"
 
[Template]
 
;Option descriptions have been grouped together here.
;Do not uncomment the following lines, they are for illustration only.
;
;thumb_width_*
; Width in pixels of thumbnails generated by the script.
; This option is affected by the thumb_crop_* option (see below).
;
;thumb_height_*
; Height in pixels of thumbnails generated by the script.
; This option is affected by the thumb_crop_* option (see below).
;
;thumb_crop_*
; By default, width and height are maximum dimensions and images will be
; resized, maintaining the same aspect ratio, to fit within these limits.
; Turn force_size on to make the script crop images to the specified size.
;
;*_gallery
; These options affect gallery pages (those that contain sub-galleries).
;
;*_album
; These options affect album pages (those that contain only images).
;
;*_preview
; These options affect the preview thumbnails displayed on image pages.
;
;*_image
; These options affect full size display images and are only used if
; full_image_resize is on in singapore.ini
 
thumb_width_gallery = 50
thumb_height_gallery = 50
thumb_crop_gallery = off
thumb_number_gallery = 10
;Maximum number of galleries to show on one gallery page.
 
thumb_width_album = 100
thumb_height_album = 100
thumb_crop_album = off
thumb_number_album = 20
;Maximum number of image thumbnails to show on one album page.
 
thumb_width_preview = 50
thumb_height_preview = 50
thumb_crop_preview = off
thumb_number_preview = 5
;Maximum number of preview thumbnails to display before and
;after current image in image view (eg a value of 2 here
;will result in 5 thumbnails (2 before + current + 2 after)
thumb_width_image = 700
thumb_height_image = 500
/photogallery/templates/admin_default/changethumbnail.tpl.php
0,0 → 1,32
<h1><?php echo $sg->translator->_g("Choose Thumbnail") ?></h1>
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
<input type="hidden" name="action" value="changethumbnail" />
<input type="hidden" name="gallery" value="<?php echo $sg->gallery->idEntities() ?>" />
<p><?php echo $sg->translator->_g("Choose the filename of the image used to represent this gallery.") ?></p>
 
<?php /*<p><select name="sgThumbName">
<option value="__none__"<?php if($sg->gallery->filename == "__none__") echo ' selected="true"'; ?>><?php echo $sg->translator->_g("thumbnail|None") ?></option>
<option value="__random__"<?php if($sg->gallery->filename == "__random__") echo ' selected="true"'; ?>><?php echo $sg->translator->_g("thumbnail|Random") ?></option>
<?php
foreach($sg->gallery->images as $img) {
echo '<option value="'.$img->idEntities().'"';
if($sg->gallery->filename == $img->id) echo ' selected="true"';
echo '>'.$img->name().' ('.$img->idEntities().")</option>\n ";
}
?>
</select></p> */ ?>
<p>
<label><input type="radio" name="sgThumbName" value="__none__"<?php if($sg->gallery->filename == "__none__") echo ' checked="true"'; ?>><?php echo $sg->translator->_g("thumbnail|None") ?></label>
<label><input type="radio" name="sgThumbName" value="__random__"<?php if($sg->gallery->filename == "__random__") echo ' checked="true"'; ?>><?php echo $sg->translator->_g("thumbnail|Random") ?></label>
<?php
foreach($sg->gallery->images as $img) {
echo '<label><input type="radio" name="sgThumbName" value="'.$img->idEntities().'"';
if($sg->gallery->filename == $img->id) echo ' checked="true"';
echo '>'.$img->thumbnailHTML("", "preview")."</label>\n ";
}
?>
</p>
<p><input type="submit" class="button" name="confirmed" value="<?php /*"*/ echo $sg->translator->_g("confirm|OK") ?>">
<input type="submit" class="button" name="confirmed" value="<?php /*"*/ echo $sg->translator->_g("confirm|Cancel") ?>"></p>
</form>
/photogallery/templates/admin_default/confirm.tpl.php
0,0 → 1,15
<h1><?php echo $confirmTitle ?></h1>
 
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
<?php
foreach($_REQUEST as $name => $value)
if(is_array($value))
foreach($value as $subname => $subvalue)
echo "<input type=\"hidden\" name=\"{$name}[{$subname}]\" value=\"$subvalue\" />\n";
else
echo "<input type=\"hidden\" name=\"$name\" value=\"$value\" />\n";
?>
<p><?php echo $confirmMessage ?></p>
<p><input type="submit" class="button" name="confirmed" value="<?php /*"*/ echo $sg->translator->_g("confirm|OK") ?>">
<input type="submit" class="button" name="confirmed" value="<?php /*"*/ echo $sg->translator->_g("confirm|Cancel") ?>"></p>
</form>
/photogallery/templates/admin_default/editgallery.tpl.php
0,0 → 1,57
<h1><?php echo $sg->translator->_g("Edit Gallery") ?></h1>
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
<input type="hidden" name="action" value="savegallery" />
<input type="hidden" name="gallery" value="<?php echo $sg->gallery->idEntities() ?>" />
<input type="hidden" name="sgCategories" value="<?php echo $sg->gallery->categories ?>" />
 
<table class="formTable">
<tr>
<td><?php echo $sg->translator->_g("Thumbnail") ?></td>
<td><div class="inputbox sgImageInput">
<?php
if($sg->gallery->filename == "__random__")
echo nl2br($sg->translator->_g("Random\nthumbnail"));
else
echo $sg->gallery->thumbnailHTML();
?>
<br />
<a href="<?php echo $sg->formatAdminURL("changethumbnail",$sg->gallery->idEncoded()) ?>"><?php echo $sg->translator->_g("thumbnail|Change...") ?></a>
</div></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Gallery name") ?></td>
<td><input type="text" name="sgGalleryName" value="<?php echo $sg->gallery->name ?>" size="40" /></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Artist name") ?></td>
<td><input type="text" name="sgArtistName" value="<?php echo $sg->gallery->artist ?>" size="40" /></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Email") ?></td>
<td><input type="text" name="sgArtistEmail" value="<?php echo $sg->gallery->email ?>" size="40" /></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Date") ?></td>
<td><input type="text" name="sgDate" value="<?php echo $sg->gallery->date ?>" size="40" /></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Copyright") ?></td>
<td><input type="text" name="sgCopyright" value="<?php echo $sg->gallery->copyright ?>" size="40" /></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Summary") ?></td>
<td><textarea name="sgSummary" cols="70" rows="3"><?php echo $sg->gallery->summaryStripped() ?></textarea></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Description") ?></td>
<td><textarea name="sgGalleryDesc" cols="70" rows="8"><?php echo $sg->gallery->descriptionStripped() ?></textarea></td>
</tr>
<tr>
<td></td>
<td><input type="submit" class="button" value="<?php /*"*/ echo $sg->translator->_g("Save Changes") ?>" /></td>
</tr>
</table>
</form>
/photogallery/templates/admin_default/editimage.tpl.php
0,0 → 1,67
<h1><?php echo $sg->translator->_g("Edit Image") ?></h1>
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
<input type="hidden" name="action" value="saveimage" />
<input type="hidden" name="gallery" value="<?php echo $sg->gallery->idEntities() ?>" />
<input type="hidden" name="image" value="<?php echo $sg->image->idEntities() ?>" />
<input type="hidden" name="sgThumbnail" value="<?php echo $sg->image->thumbnail ?>" />
<input type="hidden" name="sgCategories" value="<?php echo $sg->image->categories ?>" />
<table class="formTable">
<tr>
<td><?php echo $sg->translator->_g("Image") ?></td>
<td><div class="inputbox sgImageInput"><?php echo $sg->image->thumbnailHTML() ?></div></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Image name") ?></td>
<td><input type="text" name="sgImageName" value="<?php echo $sg->image->name ?>" size="40" /></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Artist name") ?></td>
<td><input type="text" name="sgArtistName" value="<?php echo $sg->image->artist ?>" size="40" /></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Email") ?></td>
<td><input type="text" name="sgArtistEmail" value="<?php echo $sg->image->email ?>" size="40" /></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Location") ?></td>
<td><input type="text" name="sgLocation" value="<?php echo $sg->image->location ?>" size="40" /></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Date") ?></td>
<td><input type="text" name="sgDate" value="<?php echo $sg->image->date ?>" size="40" /></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Copyright") ?></td>
<td><input type="text" name="sgCopyright" value="<?php echo $sg->image->copyright ?>" size="40" /></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Description") ?></td>
<td><textarea name="sgImageDesc" cols="70" rows="8"><?php echo $sg->image->descriptionStripped() ?></textarea></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Camera") ?></td>
<td><input type="text" name="sgField01" value="<?php echo $sg->image->camera ?>" size="40" /></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Lens") ?></td>
<td><input type="text" name="sgField02" value="<?php echo $sg->image->lens ?>" size="40" /></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Film") ?></td>
<td><input type="text" name="sgField03" value="<?php echo $sg->image->film ?>" size="40" /></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Darkroom manipulation") ?></td>
<td><input type="text" name="sgField04" value="<?php echo $sg->image->darkroom ?>" size="40" /></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Digital manipulation") ?></td>
<td><input type="text" name="sgField05" value="<?php echo $sg->image->digital ?>" size="40" /></td>
</tr>
<tr>
<td></td>
<td><input type="submit" class="button" value="<?php /*"*/ echo $sg->translator->_g("Save Changes") ?>" /></td>
</tr>
</table>
</form>
/photogallery/templates/admin_default/editpass.tpl.php
0,0 → 1,25
<h1><?php echo $sg->translator->_g("Change Password") ?></h1>
<p><?php echo $sg->translator->_g("Please choose a new password between 6 and 16 characters in length.") ?></p>
 
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
<input type="hidden" name="action" value="savepass" />
<input type="hidden" name="sgUsername" value="<?php echo $sg->user->username ?>" />
<table>
<tr>
<td><?php echo $sg->translator->_g("Current password:") ?></td>
<td><input type="password" name="sgOldPass" size="23" /></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("New password:") ?></td>
<td><input type="password" name="sgNewPass1" size="23" /></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Confirm password:") ?></td>
<td><input type="password" name="sgNewPass2" size="23" /></td>
</tr>
<tr>
<td></td>
<td><input type="submit" class="button" value="<?php /*"*/ echo $sg->translator->_g("Save Changes") ?>" /></td>
</tr>
</table>
</form>
/photogallery/templates/admin_default/editpermissions.tpl.php
0,0 → 1,95
<h1><?php echo $sg->translator->_g("Access Control") ?></h1>
 
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
<input type="hidden" name="action" value="savepermissions" />
<input type="hidden" name="gallery" value="<?php echo $sg->gallery->idEntities() ?>" />
 
<table class="formTable">
<tr>
<td><?php echo $sg->translator->_g("Owner") ?></td>
<td><?php
if($sg->user->isAdmin())
echo '<input type="text" name="sgOwner" value="'.$sg->gallery->owner.'" />';
else
echo '<strong>'.$sg->gallery->owner.'</strong>';
?></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Groups") ?></td>
<td><input type="text" name="sgGroups" value="<?php echo $sg->gallery->groups ?>" /></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("access control|Read") ?></td>
<td><div class="inputbox">
<?php
if(($sg->gallery->permissions & SG_IHR_READ) == SG_IHR_READ) $checked = 0;
elseif($sg->gallery->permissions & SG_GRP_READ) $checked = 1;
elseif($sg->gallery->permissions & SG_WLD_READ) $checked = 2;
else $checked = 3;
?>
<label for="sgOwnRead"><input type="radio" class="radio" id="sgOwnRead" name="sgRead" value="owner" <?php if($checked == 3) echo 'checked="true" '; ?>/> <?php echo $sg->translator->_g("permissions|Owner") ?></label>
<label for="sgGrpRead"><input type="radio" class="radio" id="sgGrpRead" name="sgRead" value="group" <?php if($checked == 1) echo 'checked="true" '; ?>/> <?php echo $sg->translator->_g("permissions|Group") ?></label>
<label for="sgWldRead"><input type="radio" class="radio" id="sgWldRead" name="sgRead" value="world" <?php if($checked == 2) echo 'checked="true" '; ?>/> <?php echo $sg->translator->_g("permissions|World") ?></label>
<?php if(!$sg->gallery->isRoot()): ?>
<label for="sgIhrRead"><input type="radio" class="radio" id="sgIhrRead" name="sgRead" value="inherit" <?php if($checked == 0) echo 'checked="true" '; ?>/> <?php echo $sg->translator->_g("permissions|Inherit") ?></label>
<?php endif; ?>
</div></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("access control|Edit") ?></td>
<td><div class="inputbox">
<?php
if(($sg->gallery->permissions & SG_IHR_EDIT) == SG_IHR_EDIT) $checked = 0;
elseif($sg->gallery->permissions & SG_GRP_EDIT) $checked = 1;
elseif($sg->gallery->permissions & SG_WLD_EDIT) $checked = 2;
else $checked = 3;
?>
<label for="sgOwnEdit"><input type="radio" class="radio" id="sgOwnEdit" name="sgEdit" value="owner" <?php if($checked == 3) echo 'checked="true" '; ?>/> <?php echo $sg->translator->_g("permissions|Owner") ?></label>
<label for="sgGrpEdit"><input type="radio" class="radio" id="sgGrpEdit" name="sgEdit" value="group" <?php if($checked == 1) echo 'checked="true" '; ?>/> <?php echo $sg->translator->_g("permissions|Group") ?></label>
<label for="sgWldEdit"><input type="radio" class="radio" id="sgWldEdit" name="sgEdit" value="world" <?php if($checked == 2) echo 'checked="true" '; ?>/> <?php echo $sg->translator->_g("permissions|World") ?></label>
<?php if(!$sg->gallery->isRoot()): ?>
<label for="sgIhrEdit"><input type="radio" class="radio" id="sgIhrEdit" name="sgEdit" value="inherit" <?php if($checked == 0) echo 'checked="true" '; ?>/> <?php echo $sg->translator->_g("permissions|Inherit") ?></label>
<?php endif; ?>
</div></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("access control|Add") ?></td>
<td><div class="inputbox">
<?php
if(($sg->gallery->permissions & SG_IHR_ADD) == SG_IHR_ADD) $checked = 0;
elseif($sg->gallery->permissions & SG_GRP_ADD) $checked = 1;
elseif($sg->gallery->permissions & SG_WLD_ADD) $checked = 2;
else $checked = 3;
?>
<label for="sgOwnAdd"><input type="radio" class="radio" id="sgOwnAdd" name="sgAdd" value="owner" <?php if($checked == 3) echo 'checked="true" '; ?>/> <?php echo $sg->translator->_g("permissions|Owner") ?></label>
<label for="sgGrpAdd"><input type="radio" class="radio" id="sgGrpAdd" name="sgAdd" value="group" <?php if($checked == 1) echo 'checked="true" '; ?>/> <?php echo $sg->translator->_g("permissions|Group") ?></label>
<label for="sgWldAdd"><input type="radio" class="radio" id="sgWldAdd" name="sgAdd" value="world" <?php if($checked == 2) echo 'checked="true" '; ?>/> <?php echo $sg->translator->_g("permissions|World") ?></label>
<?php if(!$sg->gallery->isRoot()): ?>
<label for="sgIhrAdd"><input type="radio" class="radio" id="sgIhrAdd" name="sgAdd" value="inherit" <?php if($checked == 0) echo 'checked="true" '; ?>/> <?php echo $sg->translator->_g("permissions|Inherit") ?></label>
<?php endif; ?>
</div></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("access control|Delete") ?></td>
<td><div class="inputbox">
<?php
if(($sg->gallery->permissions & SG_IHR_DELETE) == SG_IHR_DELETE) $checked = 0;
elseif($sg->gallery->permissions & SG_GRP_DELETE) $checked = 1;
elseif($sg->gallery->permissions & SG_WLD_DELETE) $checked = 2;
else $checked = 3;
?>
<label for="sgOwnDelete"><input type="radio" class="radio" id="sgOwnDelete" name="sgDelete" value="owner" <?php if($checked == 3) echo 'checked="true" '; ?>/> <?php echo $sg->translator->_g("permissions|Owner") ?></label>
<label for="sgGrpDelete"><input type="radio" class="radio" id="sgGrpDelete" name="sgDelete" value="group" <?php if($checked == 1) echo 'checked="true" '; ?>/> <?php echo $sg->translator->_g("permissions|Group") ?></label>
<label for="sgWldDelete"><input type="radio" class="radio" id="sgWldDelete" name="sgDelete" value="world" <?php if($checked == 2) echo 'checked="true" '; ?>/> <?php echo $sg->translator->_g("permissions|World") ?></label>
<?php if(!$sg->gallery->isRoot()): ?>
<label for="sgIhrDelete"><input type="radio" class="radio" id="sgIhrDelete" name="sgDelete" value="inherit" <?php if($checked == 0) echo 'checked="true" '; ?>/> <?php echo $sg->translator->_g("permissions|Inherit") ?></label>
<?php endif; ?>
</div></td>
</tr>
<tr>
<td></td>
<td><input type="submit" class="button" value="<?php /*"*/ echo $sg->translator->_g("Save Changes") ?>" /></td>
</tr>
</table>
</form>
/photogallery/templates/admin_default/editprofile.tpl.php
0,0 → 1,27
<h1><?php echo $sg->translator->_g("Edit Profile"); ?></h1>
 
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
<table class="formTable">
<input type="hidden" name="action" value="saveprofile" />
<input type="hidden" name="user" value="<?php echo $sg->user->username; ?>" />
<tr>
<td><?php echo $sg->translator->_g("Username"); ?></td>
<td><strong><?php echo $sg->user->username; ?></strong></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Email"); ?></td>
<td><input type="input" name="sgEmail" value="<?php echo $sg->user->email; ?>" /></td>
</tr>
<tr>
<td><?php echo $sg->translator->_g("Full name"); ?></td>
<td><input type="input" name="sgFullname" value="<?php echo $sg->user->fullname; ?>" /></td>
</tr>
<tr><td><?php echo $sg->translator->_g("Description"); ?></td>
<td><input type="input" name="sgDescription" value="<?php echo $sg->user->description; ?>" /></td>
</tr>
<tr>
<td></td>
<td><input type="submit" class="button" value="<?php /*"*/ echo $sg->translator->_g("Save Changes") ?>" /></td>
</tr>
</table>
</form>
/photogallery/templates/admin_default/edituser.tpl.php
0,0 → 1,34
<h1><?php echo $sg->translator->_g("User Management"); ?></h1>
 
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
<table class="formTable">
<input type="hidden" name="action" value="saveuser" />
<input type="hidden" name="user" value="<?php echo $_REQUEST["user"]; ?>" />
<?php
$users = $sg->io->getUsers();
for($i=0; $i<count($users); $i++)
if($users[$i]->username == $_REQUEST["user"]) {
$usr = $users[$i];
break;
}
echo "<tr><td>".$sg->translator->_g("Username")."</td><td><strong>".$usr->username."</strong></td></tr>\n";
if($sg->user->isAdmin())
echo "<tr><td>".$sg->translator->_g("Type").'</td><td>'.
'<label for="sgTypeAdmin"><input type="radio" class="radio" id="sgTypeAdmin" name="sgType" value="admin"'.($usr->permissions & SG_ADMIN ? ' checked="true"' : "").' />'.$sg->translator->_g("Administrator")."</label><br />\n".
'<label for="sgTypeUser"><input type="radio" class="radio" id="sgTypeUser" name="sgType" value="user"'. ($usr->permissions & SG_ADMIN ? "" : ' checked="true"').' />'.$sg->translator->_g("User")."</label></td></tr>\n";
if($sg->user->isAdmin())
echo "<tr><td>".$sg->translator->_g("Groups").'</td><td><input type="input" name="sgGroups" value="'.$usr->groups."\" /></td></tr>\n";
echo "<tr><td>".$sg->translator->_g("Email").'</td><td><input type="input" name="sgEmail" value="'.$usr->email."\" /></td></tr>\n";
echo "<tr><td>".$sg->translator->_g("Full name").'</td><td><input type="input" name="sgFullname" value="'.$usr->fullname."\" /></td></tr>\n";
echo "<tr><td>".$sg->translator->_g("Description").'</td><td><input type="input" name="sgDescription" value="'.$usr->description."\" /></td></tr>\n";
if($sg->user->isAdmin() && !$usr->isGuest())
echo "<tr><td>".$sg->translator->_g("Password").'</td><td><input type="input" name="sgPassword" value="**********" /></td></tr>'."\n";
?>
<tr>
<td></td>
<td><input type="submit" class="button" value="<?php /*"*/ echo $sg->translator->_g("Save Changes") ?>" /></td>
</tr>
</table>
</form>
/photogallery/templates/admin_default/footer.tpl.php
0,0 → 1,10
 
<div id="footer"><p>
<?php echo $sg->allRightsReserved() ?>
<br />
<?php echo $sg->poweredByText() ?>
<?php echo $sg->scriptExecTimeText() ?>
</p></div>
 
</body>
</html>
/photogallery/templates/admin_default/galleryhits.tpl.php
0,0 → 1,25
<p class="sgNavBar sgTopNavBar">
<?php if($sg->gallery->hasPrev()) echo $sg->gallery->prevLink("showgalleryhits")." | "; ?>
<?php if(!$sg->gallery->isRoot()) echo $sg->gallery->parentLink("showgalleryhits"); ?>
<?php if($sg->gallery->hasNext()) echo " | ".$sg->gallery->nextLink("showgalleryhits"); ?>
</p>
 
<h1><?php echo $sg->gallery->name(); ?></h1>
 
<div class="sgContainer">
<div class="sgContent">
<table class="sgList">
<tr><th><?php echo $sg->translator->_g("Gallery name") ?></th><th><?php echo $sg->translator->_g("hits table|Hits") ?></th><th><?php echo $sg->translator->_g("hits table|Last hit") ?></th><th><?php echo $sg->translator->_g("hits table|Graph") ?></th></tr>
<?php $maxhits = $sg->getMaxHits($sg->gallery->galleries); ?>
<?php foreach($sg->gallery->galleries as $index => $gal): ?>
<tr class="sgRow<?php echo $index%2 ?>">
<td><?php echo $gal->nameLink($gal->isGallery()?"showgalleryhits":"showimagehits"); ?> (<?php echo $gal->idEntities() ?>)</td>
<td align="right"><?php echo $gal->hits; ?></td>
<td align="right" title="<?php echo $gal->lasthit==0 ? "n/a" : date("Y-m-d H:i:s",$gal->lasthit) ?>"><?php echo $gal->lasthit==0 ? "n/a" : date("D j H:i",$gal->lasthit) ?></td>
<td><img src="<?php echo $sg->config->base_url.$sg->config->pathto_admin_template ?>images/graph.gif" height="8" width="<?php echo $maxhits==0 ? "0" : floor(($gal->hits/$maxhits)*300) ?>" alt="" /></td>
</tr>
<?php endforeach; ?>
</table>
</div>
</div>
/photogallery/templates/admin_default/header.tpl.php
0,0 → 1,39
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title><?php echo $sg->pageTitle() ?></title>
<link rel="stylesheet" type="text/css" href="<?php echo $sg->config->base_url.$sg->config->pathto_admin_template ?>main.css" />
<!--
This page was generated by singapore <http://singapore.sourceforge.net>
singapore is free software licensed under the terms of the GNU GPL.
-->
</head>
 
<body>
 
<div id="crumb">
<?php echo $sg->crumbLine() ?>
</div>
 
<div id="header"><img src="<?php echo $sg->config->base_url.$sg->config->pathto_admin_template ?>images/header.gif" alt="<?php echo $sg->config->gallery_name ?>" /></div>
 
<div id="sgAdminBar">
<?php
$sections = $sg->adminLinksArray();
foreach($sections[0] as $text => $url): ?>
<a href="<?php echo $url ?>"><?php echo $text ?></a>
<?php endforeach; ?>
<?php for($i=1;$i<count($sections);$i++): ?>
<span class="sgAdminBarSeparator"></span>
<?php foreach($sections[$i] as $text => $url): ?>
<a href="<?php echo $url ?>"><?php echo $text ?></a>
<?php endforeach; ?>
<?php endfor; ?>
</div>
 
<?php echo $sg->showMessages(); ?>
 
<!-- start of generated content -->
 
/photogallery/templates/admin_default/imagehits.tpl.php
0,0 → 1,24
<p class="sgNavBar sgTopNavBar">
<?php if($sg->gallery->hasPrev()) echo $sg->gallery->prevLink("showimagehits")." | "; ?>
<?php if(!$sg->gallery->isRoot()) echo $sg->gallery->parentLink("showimagehits"); ?>
<?php if($sg->gallery->hasNext()) echo " | ".$sg->gallery->nextLink("showimagehits"); ?>
</p>
 
<h1><?php echo $sg->gallery->name(); ?></h1>
 
<div class="sgContainer">
<div class="sgContent">
<table class="sgList">
<tr><th><?php echo $sg->translator->_g("Image name") ?></th><th><?php echo $sg->translator->_g("hits table|Hits") ?></th><th><?php echo $sg->translator->_g("hits table|Last hit") ?></th><th><?php echo $sg->translator->_g("hits table|Graph") ?></th></tr>
<?php $maxhits = $sg->getMaxHits($sg->gallery->images); ?>
<?php foreach($sg->gallery->images as $index => $img): ?>
<tr class="sgRow<?php echo $index%2 ?>">
<td><?php echo $img->nameLink(); ?> (<?php echo $img->id ?>)</td>
<td align="right"><?php echo empty($img->hits) ? "0" : $img->hits ?></td>
<td align="right" title="<?php echo empty($img->lasthit) ? "n/a" : date("Y-m-d H:i:s",$img->lasthit) ?>"><?php echo empty($img->lasthit) ? "n/a" : date("D j H:i",$img->lasthit) ?></td>
<td><img src="<?php echo $sg->config->base_url.$sg->config->pathto_admin_template ?>images/graph.gif" height="8" width="<?php echo $maxhits==0 ? "0" : floor(($img->hits/$maxhits)*300) ?>" /></td>
</tr>
<?php endforeach; ?>
</table>
</div>
</div>
/photogallery/templates/admin_default/images/blank.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/admin_default/images/graph.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/admin_default/images/header.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/admin_default/index.tpl.php
0,0 → 1,21
<?php
 
/**
* Default singapore admin template.
*
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @copyright (c)2003, 2004 Tamlyn Rhodes
* @version 1.0
*/
 
 
//include header file
include $sg->config->base_path.$sg->config->pathto_admin_template."header.tpl.php";
 
//include selected file
include $sg->config->base_path.$sg->config->pathto_admin_template.$sg->includeFile.".tpl.php";
 
//include footer file
include $sg->config->base_path.$sg->config->pathto_admin_template."footer.tpl.php";
 
?>
/photogallery/templates/admin_default/login.tpl.php
0,0 → 1,22
<h1><?php echo $sg->translator->_g("Log In") ?></h1>
 
<p><?php echo $sg->translator->_g("Please enter your admin username and password below.") ?></p>
 
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
<input type="hidden" name="action" value="login" />
<p>
<?php echo $sg->translator->_g("Username:") ?> <input type="text" name="sgUsername" />
<?php echo $sg->translator->_g("Password:") ?> <input type="password" name="sgPassword" />
<input type="submit" class="button" value="<?php /*"*/ echo $sg->translator->_g("Go") ?>" />
</p>
</form>
 
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
<input type="hidden" name="action" value="login" />
<input type="hidden" name="sgUsername" value="guest" />
<input type="hidden" name="sgPassword" value="password" />
<p>
<?php echo $sg->translator->_g("If you do not have a username then you may log in as a guest."); ?>
<input type="submit" class="button" value="<?php /*"*/ echo $sg->translator->_g("Log in as guest"); ?>" />
</p>
</form>
/photogallery/templates/admin_default/main.css
0,0 → 1,231
body {
margin: 1em;
font: small sans-serif;
color: #000;
background-color: #fff;
}
 
p, td, th, li, h4 {
font: small sans-serif;
}
 
h1, h2, h3 {
color: #f60;
}
 
h1 {
font-size: large;
}
 
a:link, a:visited {
color: #09f;
text-decoration: underline;
}
 
a:hover {
text-decoration: none;
}
 
input, textarea, select, .inputbox {
border: 1px solid #f60;
color: #000;
background-color: #fff;
}
 
input.radio, input.checkbox {
border: none;
background-color: #fff;
}
 
input.button {
font-weight: bold;
border: 1px outset #fff;
color: #fff;
background-color: #f60;
}
 
label {
cursor: default;
}
 
 
#header {
}
 
#crumb {
}
 
#footer {
text-align: center;
}
 
a img {
border: 0;
}
 
/* image or gallery name header */
.sgTitle {
margin-bottom: 0;
}
 
/* image or gallery artist subheader */
.sgSubTitle {
margin-top: 0;
}
 
table.sgList {
background-color: #fff;
border: 1px solid #888;
width: 100%
}
 
tr.sgRow0 {
background-color: #f0f0f0;
margin: 1px;
}
 
tr.sgRow1 {
background-color: #e0e0e0;
margin: 1px;
}
 
table.formTable input, table.formTable textarea, table.formTable .inputbox {
width: 500px;
}
 
table.formTable td {
vertical-align: top;
}
 
table.formTable input.radio, table.formTable input.checkbox {
width: auto;
height: auto;
}
 
.sgImageInput {
text-align: center;
padding: 2px;
}
 
#sgAdminMessages {
background-color: #fff;
border: 1px dashed #000;
margin: 1em 0;
padding: 5px;
font-size: x-small;
}
 
#sgAdminMessages li.adminError {
list-style-image: url(images/error.gif);
margin-left: 20px;
}
 
#sgAdminMessages li.adminMessage {
list-style-image: url(images/message.gif);
margin-left: 20px;
}
 
#sgAdminBar {
background-color: #f0f0f0;
border: 1px solid #000;
margin: 1em 0 1em 0;
padding: 5px;
font-size: x-small;
}
 
#sgAdminBar a:link, #sgAdminBar a:visited, #sgAdminBar a:active {
color: #000;
font: x-small Verdana, sans-serif;
position: relative;
left: 1px;
top: 1px;
border: 1px solid #f0f0f0;
text-decoration: none;
padding: 2px;
}
 
#sgAdminBar a:hover {
position: relative;
left: 0px;
top: 0px;
border: 1px solid #000;
color: #000;
background-color: #fff;
}
 
span.sgAdminBarSeparator {
border-left: 1px solid #888;
width: 0px;
margin-right: 4px;
}
 
div.sgNavBar, p.sgNavBar {
text-align: center;
float: right;
}
 
 
div.sgContainer {
clear: both;
text-align: center;
}
 
div.sgTab {
padding: 0.25em;
text-align: left;
}
 
div.sgContent {
background-color: #f0f0f0;
border: 1px solid #000;
padding: 1em;
text-align: left;
}
 
table.sgContent {
margin-left: auto;
margin-right: auto;
}
 
div.sgGallery, div.sgThumbnail {
margin: 0.5em;
padding: 0.5em;
border: 1px solid #888;
background-color: #fff;
}
 
td.sgGalleryThumbnail {
width: 60px;
text-align: center;
}
 
p.sgGalleryTitle a {
font-weight: bold;
}
 
div.sgThumbnail {
float: left;
}
 
div.sgThumbnail table {
width: 110px;
height: 110px;
text-align: center;
vertical-align: middle;
}
 
div.stretcher {
clear: both;
}
 
img.sgImage {
border: 1px solid #000;
}
 
input.sgImageCheckbox {
position: absolute;
float: left;
z-index: 10;
}
/photogallery/templates/admin_default/manageusers.tpl.php
0,0 → 1,34
<h1><?php echo $sg->translator->_g("User Management"); ?></h1>
 
<?php if(!$sg->user->isAdmin()) echo '<p>'.$sg->translator->_g("You must be an administrator to access this area.").'</p>'; ?>
 
<table>
<?php
$users = $sg->io->getUsers();
foreach($users as $usr) {
echo "<tr>\n ";
echo "<td><strong>".$sg->translator->_g("Username")."</strong> ";
if($usr->permissions & SG_SUSPENDED) echo "<strike>";
if($usr->permissions & SG_ADMIN) echo "<u>";
echo $usr->username;
if($usr->permissions & SG_ADMIN) echo "</u>";
if($usr->permissions & SG_SUSPENDED) echo "</strike>";
echo "</td>\n ";
echo "<td><strong>".$sg->translator->_g("Email")."</strong> ".$usr->email."</td>\n ";
echo "<td><strong>".$sg->translator->_g("Full name")."</strong> ".$usr->fullname."</td>\n ";
echo '<td><a href="'.$sg->formatAdminURL("edituser", null, null, null, "&amp;user=".$usr->username).'">'.$sg->translator->_g("edit")."</a></td>\n ";
echo '<td><a href="'.$sg->formatAdminURL("deleteuser", null, null, null, "&amp;user=".$usr->username).'">'.$sg->translator->_g("delete")."</a></td>\n ";
echo '<td><a href="'.$sg->formatAdminURL("suspenduser", null, null, null, "&amp;user=".$usr->username).'">'.($usr->permissions & SG_SUSPENDED ? $sg->translator->_g("unsuspend") : $sg->translator->_g("suspend"))."</a></td>\n";
echo "</tr>\n";
}
 
?>
</table>
 
<h2><?php echo $sg->translator->_g("Create New User"); ?></h2>
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post"><p>
<?php echo $sg->translator->_g("Username"); ?>
<input type="hidden" name="action" value="newuser" />
<input type="input" name="user" />
<input type="submit" class="button" value="<?php /*"*/ echo $sg->translator->_g("Create"); ?>" />
</p></form>
/photogallery/templates/admin_default/menu.tpl.php
0,0 → 1,15
<p><?php echo $sg->translator->_g("Please choose an option:") ?></p>
 
<ul>
<li><a href="<?php echo $sg->formatAdminURL("view") ?>"><?php echo $sg->translator->_g("Manage galleries and images") ?></a></li>
<li><a href="<?php echo $sg->formatAdminURL("showgalleryhits") ?>"><?php echo $sg->translator->_g("View gallery hits") ?></a></li>
<?php if(!$sg->user->isGuest()): ?>
<li><a href="<?php echo $sg->formatAdminURL("editpass") ?>"><?php echo $sg->translator->_g("Change password") ?></a></li>
<li><a href="<?php echo $sg->formatAdminURL("editprofile") ?>"><?php echo $sg->translator->_g("My profile") ?></a></li>
<?php endif; ?>
<?php if($sg->user->isAdmin()): ?>
<li><a href="<?php echo $sg->formatAdminURL("manageusers") ?>"><?php echo $sg->translator->_g("Manage users") ?></a></li>
<?php /*<li><a href="<?php echo $sg->formatAdminURL("purgecache") ?>"><?php echo $sg->translator->_g("Purge cached thumbnails") ?></a></li>*/ ?>
<?php endif; ?>
<li><a href="<?php echo $sg->formatAdminURL("logout") ?>"><?php echo $sg->translator->_g("Log out of admin") ?></a></li>
</ul>
/photogallery/templates/admin_default/multimove.tpl.php
0,0 → 1,29
<h1><?php echo $sg->translator->_g("Move or Copy Items") ?></h1>
 
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
<input type="hidden" name="action" value="multimove" />
<input type="hidden" name="gallery" value="<?php echo $sg->gallery->idEntities() ?>" />
<?php
if(isset($_REQUEST["sgGalleries"]))
foreach($_REQUEST["sgGalleries"] as $name => $value)
echo "<input type=\"hidden\" name=\"sgGalleries[$name]\" value=\"$value\" />\n";
elseif(isset($_REQUEST["sgImages"]))
foreach($_REQUEST["sgImages"] as $name => $value)
echo "<input type=\"hidden\" name=\"sgImages[$name]\" value=\"$value\" />\n";
?>
<p>Select the gallery to which you wish to move or copy the selected items.</p>
 
<p><select name="sgMoveTarget">
<?php
foreach($sg->allGalleriesArray() as $gal)
//if(strpos($gal->id, $sg->gallery->id) !== 0)
echo '<option value="'.$gal->idEntities().'">'.$gal->idEntities()." (".$gal->name().")</option>\n";
?>
</select></p>
<p>
<label><input type="radio" name="sgMoveType" value="copy" checked="true" /> <?php /*"*/ echo $sg->translator->_g("Copy") ?></label>
<label><input type="radio" name="sgMoveType" value="move" /> <?php /*"*/ echo $sg->translator->_g("Move") ?></label>
</p>
<p><input type="submit" class="button" name="confirmed" value="<?php /*"*/ echo $sg->translator->_g("confirm|OK") ?>">
<input type="submit" class="button" name="confirmed" value="<?php /*"*/ echo $sg->translator->_g("confirm|Cancel") ?>"></p>
</form>
/photogallery/templates/admin_default/newgallery.tpl.php
0,0 → 1,18
<h1><?php echo $sg->translator->_g("New Gallery") ?></h1>
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
<input type="hidden" name="action" value="addgallery" />
<input type="hidden" name="gallery" value="<?php echo $sg->gallery->idEntities() ?>" />
 
<table class="formTable">
<tr>
<td><?php echo $sg->translator->_g("Identifier") ?></td>
<td><input type="text" name="newgallery" value="" size="40" /></td>
</tr>
<tr>
<td></td>
<td><input type="submit" class="button" value="<?php /*"*/ echo $sg->translator->_g("Create") ?>" /></td>
</tr>
</table>
</form>
/photogallery/templates/admin_default/newimage.tpl.php
0,0 → 1,52
<h1><?php echo $sg->translator->_g("New Image") ?></h1>
 
<?php if($sg->gallery->hasChildGalleries()) echo "<p>".$sg->translator->_g("This image will not be visible because this gallery is not an album: it contains child galleries.")."</p>"; ?>
 
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" enctype="multipart/form-data" method="post">
<input type="hidden" name="action" value="addimage" />
<input type="hidden" name="gallery" value="<?php echo $sg->gallery->idEntities() ?>" />
 
<table class="formTable">
<tr>
<td><input type="radio" class="radio" id="sgLocationChoiceSingle" name="sgLocationChoice" value="single" checked="true" /></td>
<td colspan="2"><label for="sgLocationChoiceSingle"><?php echo $sg->translator->_g("Upload single file") ?></label></td>
<tr>
<tr>
<td></td>
<td><?php echo $sg->translator->_g("Image file to upload:") ?></td>
<td><input type="file" name="sgImageFile" value="" size="40" /></td>
</tr>
<tr>
<td></td>
<td><?php echo $sg->translator->_g("Identifier:") ?></td>
<td>
<label for="sgNameChoiceSame"><input type="radio" class="radio" id="sgNameChoiceSame" name="sgNameChoice" value="same" checked="true" /> <?php echo $sg->translator->_g("Use filename of uploaded file.") ?></label><br />
<label for="sgNameChoiceNew"><input type="radio" class="radio" id="sgNameChoiceNew" name="sgNameChoice" value="new" /> <?php echo $sg->translator->_g("Specify different filename:") ?></label><br />
<input type="text" name="sgFileName" value="" size="40" /></td>
</tr>
<tr>
<td><input type="radio" class="radio" id="sgLocationChoiceMulti" name="sgLocationChoice" value="multi" /></td>
<td colspan="2"><label for="sgLocationChoiceMulti"><?php echo $sg->translator->_g("Upload multiple files") ?></label></td>
<tr>
<tr>
<td></td>
<td><?php echo $sg->translator->_g("ZIP file to upload:") ?></td>
<td><input type="file" name="sgArchiveFile" value="" size="40" /></td>
</tr>
<tr>
<td><input type="radio" class="radio" id="sgLocationChoiceRemote" name="sgLocationChoice" value="remote"></td>
<td colspan="2"><label for="sgLocationChoiceRemote"><?php echo $sg->translator->_g("Add remote file") ?></label></td>
<tr>
<tr>
<td></td>
<td><?php echo $sg->translator->_g("URL of image:") ?></td>
<td><input type="text" name="sgImageURL" value="http://" size="40" /></td>
</tr>
<tr>
<td colspan="2"></td>
<td><input type="submit" class="button" value="<?php /*"*/ echo $sg->translator->_g("Create"); ?>" /></td>
</tr>
</table>
</form>
/photogallery/templates/admin_default/view.tpl.php
0,0 → 1,9
<?php
if($sg->isImagePage()) {
include $sg->config->base_path.$sg->config->pathto_admin_template."viewimage.tpl.php";
} elseif($sg->isAlbumPage()) {
include $sg->config->base_path.$sg->config->pathto_admin_template."viewalbum.tpl.php";
} else {
include $sg->config->base_path.$sg->config->pathto_admin_template."viewgallery.tpl.php";
}
?>
/photogallery/templates/admin_default/viewalbum.tpl.php
0,0 → 1,37
<p class="sgNavBar sgTopNavBar">
<?php if($sg->gallery->hasPrev()) echo $sg->gallery->prevLink()." | "; ?>
<?php if(!$sg->gallery->isRoot()) echo $sg->gallery->parentLink(); ?>
<?php if($sg->gallery->hasNext()) echo " | ".$sg->gallery->nextLink(); ?>
</p>
 
<h2 class="sgTitle"><?php echo $sg->gallery->name(); ?></h2>
 
<div class="sgContainer">
<div class="sgTab"><?php echo $sg->galleryTab()?></div>
<div class="sgContent">
<form action="<?php echo $_SERVER["PHP_SELF"]; ?>" method="post">
<input type="hidden" name="action" value="multi" />
<input type="hidden" name="gallery" value="<?php echo $sg->gallery->idEntities(); ?>" />
<div class="sgGallery">
<?php echo $sg->translator->_g("With selected:"); ?>
<?php /* <input type="submit" class="button" name="subaction" value="<?php echo $sg->translator->_g("Copy or move"); ?>" /> */ ?>
<input type="submit" class="button" name="subaction" value="<?php echo $sg->translator->_g("Delete"); ?>" />
</div>
<?php for($index = $sg->gallery->startat; $index < $sg->gallery->imageCountSelected()+$sg->gallery->startat; $index++): ?>
<div class="sgThumbnail">
<input type="checkbox" class="sgImageCheckbox checkbox" name="sgImages[]" value="<?php echo $sg->gallery->images[$index]->idEntities(); ?>" />
<table><tr><td>
<?php echo $sg->gallery->images[$index]->thumbnailLink() ?>
</td></tr></table>
</div>
<?php endfor; ?>
<div class="stretcher"></div>
</div>
</form>
</div>
<p>
<?php foreach($sg->gallery->detailsArray() as $key => $value): ?>
<strong><?php echo $key ?>:</strong> <?php echo $value ?><br />
<?php endforeach; ?>
</p>
/photogallery/templates/admin_default/viewgallery.tpl.php
0,0 → 1,51
<p class="sgNavBar sgTopNavBar">
<?php if($sg->gallery->hasPrev()) echo $sg->gallery->prevLink()." | "; ?>
<?php if(!$sg->gallery->isRoot()) echo $sg->gallery->parentLink(); ?>
<?php if($sg->gallery->hasNext()) echo " | ".$sg->gallery->nextLink(); ?>
</p>
 
<h2 class="sgTitle"><?php echo $sg->gallery->name(); ?></h2>
 
<div class="sgContainer">
<div class="sgTab"><?php echo $sg->galleryTab()?></div>
<div class="sgContent">
<form action="<?php echo $_SERVER["PHP_SELF"]; ?>" method="post">
<input type="hidden" name="action" value="multi" />
<input type="hidden" name="gallery" value="<?php echo $sg->gallery->idEncoded(); ?>" />
<div class="sgGallery">
<?php echo $sg->translator->_g("With selected:"); ?>
<input type="submit" class="button" name="subaction" value="<?php echo $sg->translator->_g("Copy or move"); ?>" />
<input type="submit" class="button" name="subaction" value="<?php echo $sg->translator->_g("Delete"); ?>" />
<input type="submit" class="button" name="subaction" value="<?php echo $sg->translator->_g("Re-index"); ?>" />
</div>
<?php for($index = $sg->gallery->startat; $index < $sg->gallery->galleryCountSelected()+$sg->gallery->startat; $index++): ?>
<div class="sgGallery"><table>
<tr valign="top">
<td><input type="checkbox" class="checkbox" name="sgGalleries[]" value="<?php echo $sg->gallery->galleries[$index]->idEntities(); ?>" /></td>
<td class="sgGalleryThumbnail"><?php echo $sg->gallery->galleries[$index]->thumbnailHTML() ?></td>
<td>
<?php echo $sg->gallery->galleries[$index]->name() ?> - <?php echo $sg->gallery->galleries[$index]->itemCountText() ?><br />
<?php
echo '<a href="'.$sg->formatAdminURL("view",$sg->gallery->galleries[$index]->idEncoded()).'">'.$sg->translator->_g("admin bar|View gallery")."</a> |\n";
echo '<a href="'.$sg->formatAdminURL("editgallery",$sg->gallery->galleries[$index]->idEncoded()).'">'.$sg->translator->_g("admin bar|Edit gallery")."</a> |\n";
echo '<a href="'.$sg->formatAdminURL("editpermissions",$sg->gallery->galleries[$index]->idEncoded()).'">'.$sg->translator->_g("admin bar|Access control")."</a> |\n";
echo '<a href="'.$sg->formatAdminURL("deletegallery",$sg->gallery->galleries[$index]->idEncoded()).'">'.$sg->translator->_g("admin bar|Delete gallery")."</a> |\n";
echo '<a href="'.$sg->formatAdminURL("newgallery",$sg->gallery->galleries[$index]->idEncoded()).'">'.$sg->translator->_g("admin bar|New subgallery")."</a> |\n";
echo '<a href="'.$sg->formatAdminURL("reindex",$sg->gallery->galleries[$index]->idEncoded()).'">'.$sg->translator->_g("admin bar|Re-index gallery")."</a> |\n";
//echo '<a href="'.$sg->formatAdminURL("newimage",$sg->gallery->galleries[$index]->idEncoded()).'">'.$sg->translator->_g("admin bar|New image")."</a> |\n";
echo '<a href="'.$sg->formatAdminURL("changethumbnail",$sg->gallery->galleries[$index]->idEncoded()).'">'.$sg->translator->_g("admin bar|Change thumbnail")."</a>\n";
?>
</td>
</tr>
</table></div>
<?php endfor; ?>
</form>
</div>
</div>
<p>
<?php foreach($sg->gallery->detailsArray() as $key => $value): ?>
<strong><?php echo $key ?>:</strong> <?php echo $value ?><br />
<?php endforeach; ?>
</p>
/photogallery/templates/admin_default/viewimage.tpl.php
0,0 → 1,30
<p class="sgNavBar sgTopNavBar">
<?php echo $sg->previewThumbnails();?>
<br />
<?php if($sg->image->hasPrev()) echo $sg->image->prevLink()." | "; ?>
<?php echo $sg->image->parentLink(); ?>
<?php if($sg->image->hasNext()) echo " | ".$sg->image->nextLink(); ?>
</p>
<h2 class="sgTitle"><?php echo $sg->image->name(); ?></h2>
<div class="sgContainer">
<table class="sgContent"><tr><td><div class="sgContent">
<?php echo $sg->image->imageHTML() ?>
</div></td></tr></table>
</div>
<div class="sgNavBar sgTopNavBar"><p>
<?php if($sg->image->hasPrev()) echo $sg->image->prevLink()." | "; ?>
<?php echo $sg->image->parentLink(); ?>
<?php if($sg->image->hasNext()) echo " | ".$sg->image->nextLink(); ?>
</p></div>
 
<p><em><?php echo $sg->image->name() ?></em><?php echo $sg->image->byArtistText() ?></p>
<p>
<?php foreach($sg->image->detailsArray() as $key => $value): ?>
<strong><?php echo $key ?>:</strong> <?php echo $value ?><br />
<?php endforeach; ?>
</p>
 
<?php echo $sg->imageMap() ?>
/photogallery/templates/default/album.tpl.php
0,0 → 1,60
<p class="sgNavBar sgTopNavBar">
<?php if($sg->gallery->hasPrev()) echo $sg->gallery->prevLink()." | "; ?>
<?php if(!$sg->gallery->isRoot()) echo $sg->gallery->parentLink(); ?>
<?php if($sg->gallery->hasNext()) echo " | ".$sg->gallery->nextLink(); ?>
</p>
 
<h2 class="sgTitle"><?php echo $sg->gallery->name(); ?></h2>
<h4 class="sgSubTitle"><?php echo $sg->gallery->byArtistText(); ?></h4>
 
<div class="sgShadow"><table class="sgShadow" cellspacing="0">
<tr>
<td class="tabl"></td>
<td class="tabm">
<div><?php echo $sg->galleryTab(); ?></div>
</td>
<td class="tabr"></td>
</tr>
<tr>
<td class="tl"></td>
<td class="tm"></td>
<td class="tr"></td>
</tr>
<tr>
<td class="ml"></td>
<td class="mm">
<?php for($index = $sg->gallery->startat; $index < $sg->gallery->imageCountSelected()+$sg->gallery->startat; $index++): ?>
<div class="sgThumbnail">
<div class="sgThumbnailContent">
<img class="borderTL" src="<?php echo $sg->config->base_url.$sg->config->pathto_current_template ?>images/slide-tl.gif" alt="" />
<img class="borderTR" src="<?php echo $sg->config->base_url.$sg->config->pathto_current_template ?>images/slide-tr.gif" alt="" />
<table><tr><td>
<?php echo $sg->gallery->images[$index]->thumbnailLink(); ?>
</td></tr></table>
<div class="roundedCornerSpacer">&nbsp;</div>
</div>
<div class="bottomCorners">
<img class="borderBL" src="<?php echo $sg->config->base_url.$sg->config->pathto_current_template ?>images/slide-bl.gif" alt="" />
<img class="borderBR" src="<?php echo $sg->config->base_url.$sg->config->pathto_current_template ?>images/slide-br.gif" alt="" />
</div>
</div>
<?php endfor; ?>
</td>
<td class="mr"></td>
</tr>
<tr>
<td class="bl"></td>
<td class="bm"></td>
<td class="br"></td>
</tr>
</table></div>
<p class="sgDetailsList">
<?php foreach($sg->gallery->detailsArray() as $key => $value): ?>
<strong><?php echo $key; ?>:</strong> <?php echo $value; ?><br />
<?php endforeach; ?>
</p>
/photogallery/templates/default/footer.tpl.php
0,0 → 1,12
 
<div id="footer"><p>
<?php echo $sg->allRightsReserved(); ?>
<?php echo $sg->licenseText(); ?>
<br />
<?php echo $sg->poweredByText(); ?>
<?php echo $sg->scriptExecTimeText(); ?> |
<?php echo $sg->adminLink(); ?>
</p></div>
 
</body>
</html>
/photogallery/templates/default/gallery.tpl.php
0,0 → 1,56
<p class="sgNavBar sgTopNavBar">
<?php if($sg->gallery->hasPrev()) echo $sg->gallery->prevLink()." | "; ?>
<?php if(!$sg->gallery->isRoot()) echo $sg->gallery->parentLink(); ?>
<?php if($sg->gallery->hasNext()) echo " | ".$sg->gallery->nextLink(); ?>
</p>
 
<h2 class="sgTitle"><?php echo $sg->gallery->name(); ?></h2>
<h4 class="sgSubTitle"><?php echo $sg->gallery->byArtistText(); ?></h4>
 
<div class="sgShadow"><table class="sgShadow" cellspacing="0">
<tr>
<td class="tabl"></td>
<td class="tabm">
<div><?php echo $sg->galleryTab(); ?></div>
</td>
<td class="tabr"></td>
</tr>
<tr>
<td class="tl"></td>
<td class="tm"></td>
<td class="tr"></td>
</tr>
<tr>
<td class="ml"></td>
<td class="mm">
<?php for($index = $sg->gallery->startat; $index < $sg->gallery->galleryCountSelected()+$sg->gallery->startat; $index++): ?>
<div class="sgGallery"><table class="sgGallery"><tr valign="top">
<td class="sgGalleryThumb">
<?php echo $sg->gallery->galleries[$index]->thumbnailLink(); ?>
</td>
<td>
<p><strong><?php echo $sg->gallery->galleries[$index]->nameLink(); ?></strong></p>
<p><?php echo $sg->gallery->galleries[$index]->summary(); ?></p>
<p>[<?php echo $sg->gallery->galleries[$index]->itemCountText(); ?>]</p>
</td>
</tr></table></div>
<?php endfor; ?>
 
</td>
<td class="mr"></td>
</tr>
<tr>
<td class="bl"></td>
<td class="bm"></td>
<td class="br"></td>
</tr>
</table></div>
 
<p class="sgDetailsList">
<?php foreach($sg->gallery->detailsArray() as $key => $value): ?>
<strong><?php echo $key; ?>:</strong> <?php echo $value; ?><br />
<?php endforeach; ?>
</p>
/photogallery/templates/default/header.tpl.php
0,0 → 1,25
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title><?php echo $sg->pageTitle(); ?></title>
<link rel="stylesheet" type="text/css" href="<?php echo $sg->config->base_url.$sg->config->pathto_current_template ?>main.css" />
<?php echo $sg->navigationLinks(); ?>
<!--
This page was generated by singapore <http://singapore.sourceforge.net>
singapore is free software licensed under the terms of the GNU GPL.
-->
</head>
 
<body>
 
<?php echo $sg->languageFlipper(); ?>
<?php echo $sg->templateFlipper(); ?>
 
<div id="crumb"><?php echo $sg->crumbLine(); ?></div>
 
<div id="header"><img src="<?php echo $sg->config->base_url.$sg->config->pathto_current_template ?>images/header.gif" alt="<?php echo$sg->config->gallery_name ?>" /></div>
 
<!-- start of generated content -->
 
/photogallery/templates/default/image.tpl.php
0,0 → 1,45
<p class="sgNavBar sgTopNavBar">
<?php echo $sg->previewThumbnails(); ?>
<br />
<?php if($sg->image->hasPrev()) echo $sg->image->prevLink()." | "; ?>
<?php echo $sg->image->parentLink(); ?>
<?php if($sg->image->hasNext()) echo " | ".$sg->image->nextLink(); ?>
</p>
<h2 class="sgTitle"><?php echo $sg->image->name(); ?></h2>
<h4 class="sgSubTitle"><?php echo $sg->image->byArtistText(); ?></h4>
<div class="sgShadow"><table class="sgShadow" cellspacing="0">
<tr>
<td class="tl"></td>
<td class="tm"></td>
<td class="tr"></td>
</tr>
<tr>
<td class="ml"></td>
<td class="mm">
<?php echo $sg->image->imageHTML() ?>
</td>
<td class="mr"></td>
</tr>
<tr>
<td class="bl"></td>
<td class="bm"></td>
<td class="br"></td>
</tr>
</table></div>
<p class="sgNavBar sgBottomNavBar">
<?php if($sg->image->hasPrev()) echo $sg->image->prevLink()." | "; ?>
<?php echo $sg->image->parentLink(); ?>
<?php if($sg->image->hasNext()) echo " | ".$sg->image->nextLink(); ?>
</p>
 
<h4 class="sgNameByArtist"><em><?php echo $sg->image->name() ?></em><?php echo $sg->image->byArtistText() ?></h4>
<p class="sgDetailsList">
<?php foreach($sg->image->detailsArray() as $key => $value): ?>
<strong><?php echo $key ?>:</strong> <?php echo $value ?><br />
<?php endforeach; ?>
</p>
 
<?php echo $sg->imageMap() ?>
/photogallery/templates/default/images/blank.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/default/images/header.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/default/images/shadow-bl.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/default/images/shadow-bm.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/default/images/shadow-br.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/default/images/shadow-ml.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/default/images/shadow-mr.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/default/images/shadow-tabl.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/default/images/shadow-tabm.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/default/images/shadow-tabr.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/default/images/shadow-tl.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/default/images/shadow-tm.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/default/images/shadow-tr.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/default/images/slide-bl.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/default/images/slide-br.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/default/images/slide-tl.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/default/images/slide-tr.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/default/index.tpl.php
0,0 → 1,32
<?php
 
/**
* Default singapore template.
*
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @copyright (c)2003, 2004 Tamlyn Rhodes
* @version 1.0
*/
 
//include header file
include $sg->config->base_path.$sg->config->pathto_current_template."header.tpl.php";
 
switch($sg->action) {
case "addcomment" :
include $sg->config->base_path.$sg->config->pathto_current_template."addcomment.tpl.php";
default :
if($sg->isImagePage()) {
//this is an 'image' page so include the 'image' template file
include $sg->config->base_path.$sg->config->pathto_current_template."image.tpl.php";
} elseif($sg->isAlbumPage()) {
//this is an 'album' page so include the 'album' template file
include $sg->config->base_path.$sg->config->pathto_current_template."album.tpl.php";
} else {
//this is a 'gallery' page so include the 'gallery' template file
include $sg->config->base_path.$sg->config->pathto_current_template."gallery.tpl.php";
}
}
//include footer file
include $sg->config->base_path.$sg->config->pathto_current_template."footer.tpl.php";
 
?>
/photogallery/templates/default/main.css
0,0 → 1,232
/* * * * * * * * * * */
/* Generic elements */
/* * * * * * * * * * */
 
body {
margin: 1em;
font: small sans-serif;
color: #000;
background-color: #fff;
}
 
p, td, th, li, h4 {
font: small sans-serif;
}
 
h1, h2, h3 {
color: #f60;
}
 
h1 {
font-size: large;
}
 
a:link, a:visited {
color: #09f;
text-decoration: underline;
}
 
a:hover {
text-decoration: none;
}
 
input, textarea, select, .inputbox {
border: 1px solid #f60;
color: #000;
background-color: #fff;
}
 
input.radio {
border: none;
background-color: #fff;
}
 
input.button {
font-weight: bold;
border: 1px outset #fff;
color: #fff;
background-color: #f60;
}
 
a img {
border: 0;
}
 
 
/* * * * * * * * * * */
/* Elements with IDs */
/* * * * * * * * * * */
 
 
/* header: image and/or title */
#header { }
 
/* crumb line: (You are here: ...) */
#crumb { }
 
/* footer: copyright notices */
#footer {
text-align: center;
}
 
 
/* * * * * * * * * */
/* Custom classes */
/* * * * * * * * * */
 
 
/* image or gallery name header */
.sgTitle {
margin-bottom: 0;
}
 
/* image or gallery artist subheader */
.sgSubTitle {
margin-top: 0;
}
 
/* image and artist name displayed beneath image */
p.sgNameByArtist { }
 
/* image and gallery details such as date, location, camera model, hits etc. */
p.sgDetailsList { }
 
/* language select box and template select box respectively */
div.sgLanguageFlipper, div.sgTemplateFlipper {
float: right;
clear: right;
}
 
div.sgClear {
clear: both;
}
 
/* wraps the drop-shadow table to allow IE to center it */
div.sgShadow {
text-align: center;
padding: 1em;
}
 
/* the main content table that does the drop-shadow effect */
table.sgShadow {
margin-left: auto;
margin-right: auto;
clear: both;
}
 
table.sgShadow {
background-color: #f0f0f0;
padding: 0;
text-align: left;
}
 
table.sgShadow td {
padding: 0;
margin: 0;
}
 
/* div containing each gallery sub-gallery on a gallery page */
div.sgGallery {
margin: 5px;
padding: 5px;
border: 1px solid #ccc;
background-color: #fff;
}
 
/* the table cell containing the gallery thumbnail */
td.sgGalleryThumb {
width: 100px;
text-align: center;
}
 
/* the gallery thumbnail itself */
img.sgGalleryThumb {
border: 1px solid #000;
}
 
/* the descriptive text (title, summary, contents) */
div.sgGallery p {
margin-top: 0;
margin-bottom: 2px;
}
 
 
/* full size image on an image page*/
img.sgImage {
border: none;
}
 
/* the preview thumbnails and previous, thumbnails, next links */
p.sgTopNavBar, p.sgBottomNavBar {
text-align: center;
float: right;
}
 
/* wraps the thumbnail and rounded-corner code on an album page */
div.sgThumbnail {
width: 124px;
height: 124px;
margin: 10px 5px;
float: left;
padding: 0px;
text-align: center;
}
 
div.sgThumbnail table {
width: 114px;
height: 114px;
margin: 0px;
text-align: center;
vertical-align: middle;
}
 
.sgThumbnailContent {
background: #fff;
margin: 0px;
padding: 0px;
border: 1px solid #ccc;
}
 
 
/* the following code does the rounded corners of the 35mm slide effect on
the album pages. Taken from http://www.albin.net/CSS/roundedCorners/ */
.roundedCornerSpacer {
margin: 0px; padding: 0px; border: 0px;
clear: both;
font-size: 1px; line-height: 1px;
}
.borderTL, .borderTR, .borderBL, .borderBR {
width: 5px; height: 5px;
padding: 0px; border: 0px;
z-index: 99;
}
.borderTL, .borderBL { float: left; clear: both; }
.borderTR, .borderBR { float: right; clear: right; }
.borderTL { margin: -1px 0px 0px -1px; }
.borderTR { margin: -1px -1px 0px 0px; }
.borderBL { margin: -5px 0px 0px 0px; }
.borderBR { margin: -5px 0px 0px 0px; }
 
 
/* appropriate background images for drop-shadow effect */
table.sgShadow td.tabl { background-image: url('images/shadow-tabl.gif'); width: 16px; height: 16px; }
table.sgShadow td.tabm { background-color: #fff; }
table.sgShadow td.tabr { background-color: #fff; }
 
table.sgShadow td.tl { background-image: url('images/shadow-tl.gif'); width: 32px; height: 16px; }
table.sgShadow td.tm { background-image: url('images/shadow-tm.gif');}
table.sgShadow td.tr { background-image: url('images/shadow-tr.gif');}
table.sgShadow td.ml { background-image: url('images/shadow-ml.gif');}
table.sgShadow td.mm { padding: 10px;} /* cell containing image */
table.sgShadow td.mr { background-image: url('images/shadow-mr.gif');}
table.sgShadow td.bl { background-image: url('images/shadow-bl.gif');}
table.sgShadow td.bm { background-image: url('images/shadow-bm.gif');}
table.sgShadow td.br { background-image: url('images/shadow-br.gif'); width: 32px; height: 32px; }
 
/* the bit with previous, next */
table.sgShadow td.tabm div {
font-size: 13px;
background: #f0f0f0 url('images/shadow-tabm.gif') top right;
padding-right: 30px;
float: left;
}
/photogallery/templates/default/template.ini
0,0 → 1,50
;Option descriptions have been grouped together here.
;Do not uncomment the following lines, they are for illustration only.
;
;thumb_width_*
; Width in pixels of thumbnails generated by the script.
; This option is affected by the thumb_crop_* option (see below).
;
;thumb_height_*
; Height in pixels of thumbnails generated by the script.
; This option is affected by the thumb_crop_* option (see below).
;
;thumb_crop_*
; By default, width and height are maximum dimensions and images will be
; resized, maintaining the same aspect ratio, to fit within these limits.
; Turn force_size on to make the script crop images to the specified size.
;
;*_gallery
; These options affect gallery pages (those that contain sub-galleries).
;
;*_album
; These options affect album pages (those that contain only images).
;
;*_preview
; These options affect the preview thumbnails displayed on image pages.
;
;*_image
; These options affect full size display images and are only used if
; full_image_resize is on in singapore.ini
 
thumb_width_gallery = 80
thumb_height_gallery = 80
thumb_crop_gallery = off
thumb_number_gallery = 10
;Maximum number of galleries to show on one gallery page.
 
thumb_width_album = 100
thumb_height_album = 100
thumb_crop_album = off
thumb_number_album = 20
;Maximum number of image thumbnails to show on one album page.
 
thumb_width_preview = 50
thumb_height_preview = 50
thumb_crop_preview = off
thumb_number_preview = 5
;Maximum number of preview thumbnails to display (including
;current image). An odd number is usually preferred.
thumb_width_image = 700
thumb_height_image = 500
/photogallery/templates/index.php
0,0 → 1,0
<?php header("Location: ../") ?>
/photogallery/templates/modern/admin.tpl.php
--- photogallery/templates/modern/album.tpl.php (nonexistent)
+++ photogallery/templates/modern/album.tpl.php (revision 645)
@@ -0,0 +1,29 @@
+ <h2><?php echo $sg->gallery->name(); ?></h2>
+ <h4><?php echo $sg->gallery->byArtistText(); ?></h4>
+</div>
+
+<div id="sgMain-nav">
+</div>
+
+<div id="sgContent">
+ <p class="sgTab"><?php echo $sg->galleryTab(); ?></p>
+
+ <div class="sgAlbum">
+ <?php for($index = $sg->gallery->startat; $index < $sg->gallery->imageCountSelected()+$sg->gallery->startat; $index++): ?>
+ <?php echo $sg->gallery->images[$index]->thumbnailLink(); ?>
+ <?php endfor; ?>
+ <div class="sgFoot"></div>
+ </div>
+
+ <p class="sgTab"><?php echo $sg->galleryTab(); ?></p>
+
+ <div class="sgDetailsList">
+ <dl>
+ <?php foreach($sg->gallery->detailsArray() as $key => $value): ?>
+ <dt><?php echo $key; ?>:</dt><dd><?php echo $value; ?></dd>
+ <?php endforeach; ?>
+ </dl>
+ </div>
+
+</div>
+
/photogallery/templates/modern/css/color_bob.css
0,0 → 1,173
/*
Black on Black CSS for Modern - Singapore Template v1.3 (www.sgal.org)
by Ross Howard (www.abitcloser.com)
*/
 
/* Structure */
body {
background-color: #111;
}
 
#sgContainer {
border-right-color: #0A0A0A;
border-left-color: #222;
border-top-color: #222;
border-bottom-color: #0A0A0A;
background-color: #1A1A1A;
}
 
#sgHeader {
border-right-color:#111;
}
 
#sgMain-nav {
border-right-color: #111;
color: #444;
}
 
#sgContent {
border-right-color: #111;
border-bottom-color: #111;
border-top-color: #1A1A1A;
}
 
#sgUpdate {
background-color: #222;
border-bottom-color: #111;
color: #666;
}
 
/* Page Elements */
 
.sgCrumb {
color: #444;
}
 
.sgGallery {
border-color: #1E1E1E;
background-color: #111;
}
 
.sgAlbum {
border-color:#1E1E1E;
background-color: #111;
}
 
.sgImageBox {
background-color: #111;
border-color: #222;
border-right-color: #111;
border-bottom-color: #111;
}
 
img.sgImage {
background: #111 url(../img/loader_b.gif) center bottom no-repeat;
}
 
/* Typography */
 
h2 {
color: #DDD;
}
 
h4 {
color: #666;
}
 
p {
color: #666;
}
 
.sgGallery p.sgCount {
color: #AAA;
}
 
.sgPreview p {
color: #999;
}
 
#sgFooter p {
color: #333;
}
 
a {
color: #22628D;
}
 
#sgFooter a {
color: #22628D;
}
 
/* Links and Thumbnails */
 
.sgAlbum a img {
background-color: #181818;
border-color: #222;
}
 
.sgGallery a img {
background-color: #181818;
border-color: #222;
}
 
a:hover img.sgThumbnailAlbum, a:hover img.sgThumbGallery {
border-color: #333;
}
 
.sgPreview a img {
border-color: #333;
color: #CCC;
}
 
.sgPreview a:hover img, .sgPreview a:hover img.sgThumbnailPreviewCurrent{
border-color: #666;
}
 
/* Details */
 
dl {
color: #999;
}
 
dt {
color: #666;
}
 
/* Forms */
 
select{
color: #666;
}
 
/* In-Image Rollovers */
 
.sgImageBox a {
background-color: #111;
}
 
.sgImageBox a.prev {
border-right-color: #111;
}
 
.sgImageBox a.thumb {
border-bottom-color: #111;
}
 
.sgImageBox a.next {
border-left-color: #111;
}
 
.sgImageBox a.control {
border-top-color: #111;
}
 
/* Slideshow */
 
body#slideshow {
background-color: #000;
}
 
#slideshow div.sgImageBox {
background-color: #000;
}
/photogallery/templates/modern/css/color_wob.css
0,0 → 1,173
/*
White on Black CSS for Modern - Singapore Template v1.3 (www.sgal.org)
by Ross Howard (www.abitcloser.com)
*/
 
/* Structure */
body {
background-color: #111;
}
 
#sgContainer {
border-right-color: #0A0A0A;
border-left-color: #222;
border-top-color: #222;
border-bottom-color: #0A0A0A;
background-color: #FFF;
}
 
#sgHeader {
border-right-color: #C3C3C3;
}
 
#sgMain-nav {
border-right-color: #C3C3C3;
color: #999;
}
 
#sgContent {
border-right-color: #C3C3C3;
border-bottom-color: #C3C3C3;
border-top-color: #FFF;
}
 
#sgUpdate {
background-color: #222;
border-bottom-color: #111;
color: #666;
}
 
/* Page Elements */
 
.sgCrumb {
color: #999;
}
 
.sgGallery {
border-color: #CCC;
background-color: #EEE;
}
 
.sgAlbum {
border-color: #CCC;
background-color: #EEE;
}
 
.sgImageBox {
background-color: #EEE;
border-color: #DDD;
border-right-color: #AAA;
border-bottom-color: #AAA;
}
 
img.sgImage {
background: #EEE url(../img/loader_w.gif) center bottom no-repeat;
}
 
/* Typography */
 
h2 {
color: #555;
}
 
h4 {
color: #666;
}
 
p {
color: #666;
}
 
.sgGallery p.sgCount {
color: #AAA;
}
 
.sgPreview p {
color: #999;
}
 
#sgFooter p {
color: #333;
}
 
a {
color: #29A9FF;
}
 
#sgFooter a {
color: #22628D;
}
 
/* Links and Thumbnails */
 
.sgAlbum a img {
background-color: #FFF;
border-color: #DDD;
}
 
.sgGallery a img {
background-color: #FFF;
border-color: #DDD;
}
 
a:hover img.sgThumbnailAlbum, a:hover img.sgThumbGallery {
border-color: #BBB;
}
 
.sgPreview a img {
border-color: #CCC;
color: #CCC;
}
 
.sgPreview a:hover img, .sgPreview a:hover img.sgThumbnailPreviewCurrent{
border-color: #29A9FF;
}
 
/* Details */
 
dl {
color: #999;
}
 
dt {
color: #666;
}
 
/* Forms */
 
select{
color: #666;
}
 
/* In-Image Rollovers */
 
.sgImageBox a {
background-color: #222;
}
 
.sgImageBox a.prev {
border-right-color: #111;
}
 
.sgImageBox a.thumb {
border-bottom-color: #111;
}
 
.sgImageBox a.next {
border-left-color: #111;
}
 
.sgImageBox a.control {
border-top-color: #111;
}
 
/* Slideshow */
 
body#slideshow {
background-color: #000;
}
 
#slideshow div.sgImageBox {
background-color: #000;
}
/photogallery/templates/modern/css/color_wow.css
0,0 → 1,173
/*
White on White CSS for Modern - Singapore Template v1.3 (www.sgal.org)
by Ross Howard (www.abitcloser.com)
*/
 
/* Structure */
body {
background-color: #E5E5E5;
}
 
#sgContainer {
border-right-color: #DEDEDE;
border-left-color: #DEDEDE;
border-top-color: #DEDEDE;
border-bottom-color: #DEDEDE;
background-color: #FFF;
}
 
#sgHeader {
border-right-color: #C3C3C3;
}
 
#sgMain-nav {
border-right-color: #C3C3C3;
color: #999;
}
 
#sgContent {
border-right-color: #C3C3C3;
border-bottom-color: #C3C3C3;
border-top-color: #FFF;
}
 
#sgUpdate {
background-color: #FFF;
border-bottom-color: #DEDEDE;
color: #666;
}
 
/* Page Elements */
 
.sgCrumb {
color: #999;
}
 
.sgGallery {
border-color: #CCC;
background-color: #EEE;
}
 
.sgAlbum {
border-color: #CCC;
background-color: #EEE;
}
 
.sgImageBox {
background-color: #EEE;
border-color: #DDD;
border-right-color: #AAA;
border-bottom-color: #AAA;
}
 
img.sgImage {
background: #EEE url(../img/loader_w.gif) center bottom no-repeat;
}
 
/* Typography */
 
h2 {
color: #555;
}
 
h4 {
color: #666;
}
 
p {
color: #666;
}
 
.sgGallery p.sgCount {
color: #AAA;
}
 
.sgPreview p {
color: #999;
}
 
#sgFooter p {
color: #AAA;
}
 
a {
color: #29A9FF;
}
 
#sgFooter a {
color: #29A9FF;
}
 
/* Links and Thumbnails */
 
.sgAlbum a img {
background-color: #FFF;
border-color: #DDD;
}
 
.sgGallery a img {
background-color: #FFF;
border-color: #DDD;
}
 
a:hover img.sgThumbnailAlbum, a:hover img.sgThumbGallery {
border-color: #BBB;
}
 
.sgPreview a img {
border-color: #CCC;
color: #CCC;
}
 
.sgPreview a:hover img, .sgPreview a:hover img.sgThumbnailPreviewCurrent{
border-color: #29A9FF;
}
 
/* Details */
 
dl {
color: #999;
}
 
dt {
color: #666;
}
 
/* Forms */
 
select{
color: #666;
}
 
/* In-Image Rollovers */
 
.sgImageBox a {
background-color: #222;
}
 
.sgImageBox a.prev {
border-right-color: #111;
}
 
.sgImageBox a.thumb {
border-bottom-color: #111;
}
 
.sgImageBox a.next {
border-left-color: #111;
}
 
.sgImageBox a.control {
border-top-color: #111;
}
 
/* Slideshow */
 
body#slideshow {
background-color: #000;
}
 
#slideshow div.sgImageBox {
background-color: #000;
}
/photogallery/templates/modern/css/ie.css
0,0 → 1,46
/* IE Hacks */
body {
text-align: center;
}
 
.sgAlbum, #sgContent, h3, .sgGallery p {
height: 1%;
}
 
#sgContent div.sgImageWrapper {
text-align: center;
}
 
p.sgTab {
position: relative;
margin-top: 0px;
}
 
#sgContainer {
text-align: left;
}
 
.sgAlbum a {
display: inline;
margin: 0 18px 20px 19px;
}
 
.sgPreview a:hover img, a:hover img.sgThumbnailAlbum, a:hover img.sgThumbGallery {
filter: alpha(opacity=100);
}
 
img.sgThumbnailPreviewCurrent {
filter: alpha(opacity=60);
}
 
.sgImageBox a {
filter: alpha(opacity=0);
}
 
.sgImageBox a:hover {
filter: alpha(opacity=90);
}
 
.sgGalleryFloat {
display: inline;
}
/photogallery/templates/modern/css/layout.css
0,0 → 1,348
/*
Layout CSS for Modern - Singapore Template v1.3 (www.sgal.org)
by Ross Howard (www.abitcloser.com)
*/
 
/* Structure */
/* For editing and customisation read these notes */
body {
padding: 0;
margin: 0;
font-family: Arial, Helvetica, sans-serif; /* Set the font here to effect entire template */
}
 
#sgContainer {
width: 740px; /* This is the page width, if you want a full-screen/liquid layout use 'auto' */
border-right: 4px solid; /* If you use full-screen/liquid layout you probably want to set all borders to 'none' */
border-left: 1px solid;
border-top: 1px solid;
border-bottom: 4px solid;
margin: 24px auto 0 auto;
}
 
#sgHeader {
border-right: 1px solid;
}
 
#sgOptions {
text-align: right;
float: right;
margin: 6px 0 0 0;
}
 
#sgMain-nav {
border-right: 1px solid;
padding-top: 12px;
margin: 0 0 0 26px;
font-size: 11px;
}
 
#sgContent {
border-right: 1px solid;
border-bottom: 1px solid;
border-top: 1px solid;
}
 
#sgFooter {
width: 760px;
margin: 16px auto 0 auto;
padding: 0 0 16px 0;
text-align: center;
}
 
#sgUpdate {
font-size: 11px;
padding: 8px 0 8px 0;
text-align: center;
border-bottom: 1px solid;
}
 
 
/* Page Elements */
 
.sgCrumb {
font-size: 11px;
line-height: 16px;
padding: 20px 0 16px 26px;
}
 
.sgGallery {
border: 1px solid;
margin: 18px 24px 24px 24px;
padding: 12px 12px 10px 12px;
}
 
.sgGalleryFloat {
margin: 18px 4px 12px 24px;
float: left;
width: 304px;
}
 
.sgAlbum {
border: 1px solid;
margin: 18px 24px 32px 24px;
padding: 22px 0 0 0;
clear: both;
}
 
.sgImageBox {
margin: 24px auto 24px auto;
position: relative;
font-size: 11px;
padding: 5px;
border: 1px solid;
border-right: 1px solid;
border-bottom: 1px solid;
}
 
img.sgImage {
display: block;
}
 
.sgPreview {
text-align: center;
margin: 28px 0 24px 0;
}
 
.sgFoot {
clear: both;
}
 
 
/* Typography */
 
h2 {
font-size: 32px;
line-height: 32px;
font-weight: normal;
margin: 0 200px 0 24px;
padding: 0;
}
 
h3 {
font-size: 16px;
line-height: 18px;
font-weight: normal;
margin: 0px 0 6px 130px;
padding: 0;
}
 
h4 {
font-size: 11px;
line-height: 12px;
font-weight: normal;
margin: 0 0 0 26px;
padding: 0;
}
 
p {
font-size: 11px;
line-height: 16px;
margin: 6px 16px 4px 16px;
}
 
.sgGallery p {
border: none;
margin: 0 0 4px 130px;
}
 
#sgFooter p {
text-align: center;
}
 
p.sgLinks {
margin: 24px 0 -38px 24px;
padding: 0 0 6px 0;
}
 
p.sgTab {
line-height: 16px;
text-align: right;
margin: -16px 32px 0 24px;
padding: 0 0 0 0;
clear: both;
}
 
p.sgTab a{
margin-right: 0px;
}
 
p.sgFullsize {
text-align: center;
margin: 0;
padding: 0;
}
 
a {
text-decoration: none;
}
 
a:hover {
text-decoration: underline;
}
 
/* Links and Thumbnails */
 
.sgAlbum a {
width: 134px; /* This equals template.ini 'thumb_width_album' + padding and borders of inside img */
height: 134px; /* This equals template.ini 'thumb_height_album' + padding and borders of inside img */
float: left;
text-align: center;
margin: 0 19px 20px 19px;
}
 
.sgAlbum a img {
padding: 16px; /* 16px x 2 = 32px */
border: 1px solid ; /* 1px x 2 = 2px = 34px */
}
 
.sgGallery a img {
padding: 16px;
border: 1px solid;
float: left;
margin: 0 -150px 0 0;
}
 
a:hover img.sgThumbnailAlbum, a:hover img.sgThumbGallery {
border: 1px solid;
}
 
.sgPreview a {
border: none;
}
 
.sgPreview a img {
border: 1px solid;
margin: 0 4px 0 4px;
padding: 2px;
}
 
img.sgThumbnailPreviewCurrent {
opacity: .6;
}
 
.sgPreview a:hover img, .sgPreview a:hover img.sgThumbnailPreviewCurrent{
border: 1px solid;
opacity: 1;
}
 
/* Details */
 
dl {
font-size: 11px;
line-height: 16px;
margin: 12px 64px 24px 64px;
padding: 0;
text-align: center;
}
 
dt {
display: inline;
margin: 0 4px 0 0;
padding: 0;
}
 
dd {
display: inline;
margin: 0;
padding: 0;
}
 
/* Forms */
 
#sgOptions form{
border: none;
margin: 0 0 0 12px;
padding: 0 12px 0 0;
font-size: 10px;
display: inline;
}
 
input {
font-size: 10px;
margin: 12px 0 0 0;
}
 
select{
font-size: 10px;
}
 
/* Utility */
 
.clear {
display: block;
clear:both;
float: none;
}
 
/* In-Image Rollovers */
 
.sgImageBox a {
display: block;
position: absolute;
text-indent: -3000px;
font-size: 15px;
opacity: .0;
width: 80px;
text-align: center;
}
 
.sgImageBox a:hover {
opacity: .9;
text-indent: 0px;
text-decoration: none;
}
 
.sgImageBox a span{
display: block;
}
 
.sgImageBox a.thumb span, .sgImageBox a.control span{
margin-top: 22px;
}
 
.sgImageBox a.prev {
top: 5px;
left: 5px;
border-right: 1px solid;
}
 
.sgImageBox a.thumb {
top: 5px;
left: 5px;
height: 60px;
border-bottom: 1px solid;
}
 
.sgImageBox a.next {
top: 5px;
right: 5px;
border-left: 1px solid;
}
 
.sgImageBox a.control {
left: 5px;
bottom: 4px;
height: 60px;
border-top: 1px solid;
}
 
/* Slideshow */
 
body#slideshow div.sgImageWrapper{
position: absolute;
top: 50%;
left: 0px;
width: 100%;
}
 
#slideshow div.sgImageBox {
margin: 0 auto 0 auto;
font-size: 11px;
padding: 5px;
border: none;
}
 
body#slideshow div img{
margin: 0px auto 0px;
}
/photogallery/templates/modern/footer.tpl.php
0,0 → 1,17
<!-- start of footer.tpl.php -->
</div>
<div id="sgFooter">
<p>
<?php echo $sg->allRightsReserved(); ?>
<?php echo $sg->licenseText(); ?>
<br />
<?php echo $sg->poweredByText(); ?>
<?php echo $sg->scriptExecTimeText(); ?> |
<?php echo $sg->adminLink(); ?>
</p>
</div>
<?php
if (!defined('EXTERNAL')) {
echo '</body>
</html>';
}
/photogallery/templates/modern/gallery.tpl.php
0,0 → 1,41
<h2><?php echo $sg->gallery->name(); ?></h2>
<h4><?php echo $sg->gallery->byArtistText(); ?></h4>
</div>
 
<div id="sgMain-nav">
<?php if($sg->gallery->hasPrev()) echo $sg->gallery->prevLink()." | "; ?>
<?php if(!$sg->gallery->isRoot()) echo $sg->gallery->parentLink(); ?>
<?php if($sg->gallery->hasNext()) echo " | ".$sg->gallery->nextLink(); ?>
</div>
 
<div id="sgContent">
<p class="sgTab"><?php echo $sg->galleryTab(); ?></p>
<?php for($index = $sg->gallery->startat; $index < $sg->gallery->galleryCountSelected()+$sg->gallery->startat; $index++): ?>
<div class="sgGallery <?php if ($sg->config->thumb_float_gallery == 1) { echo 'sgGalleryFloat';} ?>">
<?php echo $sg->gallery->galleries[$index]->thumbnailLink(); ?>
<h3 title="View Gallery"><?php echo $sg->gallery->galleries[$index]->nameLink(); ?></h3>
<p><?php echo $sg->gallery->galleries[$index]->summary(); ?></p>
<p class="sgCount"><?php echo $sg->gallery->galleries[$index]->itemCountText(); ?></p>
<?php if ($sg->config->show_slideshowURL == 1) { ?>
<?php if ($sg->gallery->galleries[$index]->hasImages() && !$sg->gallery->galleries[$index]->hasChildGalleries()) { ?>
<p><a href="<?php echo $sg->gallery->galleries[$index]->images[0]->URL(); if (!strstr($sg->gallery->galleries[$index]->images[0]->URL(), '?')) { echo '?'; } else { echo '&'; } ?>action=slideshow">View Slideshow</a></p>
<?php } ?>
<?php } ?>
<div class="sgFoot"></div>
</div>
<?php // The number below equals the number of boxes before a new line starts. 1 will never echo the clear
if($index % 2) {echo '<div class="clear"></div>';} ?>
<?php endfor; ?>
 
<p class="sgTab"><?php echo $sg->galleryTab(); ?></p>
<div class="sgDetailsList">
<dl>
<?php foreach($sg->gallery->detailsArray() as $key => $value): ?>
<dt><?php echo $key; ?>:</dt><dd><?php echo $value; ?></dd>
<?php endforeach; ?>
</dl>
</div>
 
</div>
/photogallery/templates/modern/header.tpl.php
0,0 → 1,36
<?php
if (!defined('EXTERNAL')) {
echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>'.$sg->config->gallery_name.' - '.$sg->pageTitle().'</title>
<style type="text/css">@import url('.$sg->config->base_url.$sg->config->pathto_current_template.'css/layout.css);</style>
<style type="text/css">@import url('.$sg->config->base_url.$sg->config->pathto_current_template.'css/color_'.$sg->config->template_scheme.'.css);</style>
<!--[if IE]><link rel="stylesheet" type="text/css" media="all" href="'.$sg->config->base_url.$sg->config->pathto_current_template.'css/ie.css"><![endif]-->
<link rel="alternate" type="application/rss+xml" title="'.$sg->pageTitle().'" href="'.$_SERVER["PHP_SELF"]; if (isset($_GET["gallery"])) { echo '?gallery='.$_GET["gallery"];} echo '&template=rss" />
'.$sg->navigationLinks().'</head>
<body>
';
}
if (!isset($_GET["gallery"]) && $sg->config->update_check == 1 && $sg->isLoggedIn()) {
$handle = fopen($sg->config->update_url."update.php", "r");
$buffer = fgets($handle);
$thisBuffer = str_replace(' ', '', $buffer);
if ($thisBuffer != $sg->config->current_version) { echo '<div id="sgUpdate">There is a new version of Modern ('.$thisBuffer.') - <a href="'.$sg->config->update_url.$thisBuffer.'.zip">Download</a> - <a href="http://www.abitcloser.com/projects/singapore/">Read More</a></div>'; };
fclose($handle);
}
?>
 
<!--
This page was generated by singapore <http://singapore.sourceforge.net>
singapore is free software licensed under the terms of the GNU GPL.
 
Modern Template <? echo $sg->config->current_version ?> by Ross Howard
http://www.abitcloser.com/projects/singapore
-->
<div id="sgContainer">
<div id="sgHeader">
<div id="sgOptions"><?php echo $sg->languageFlipper(); ?><?php echo $sg->templateFlipper(); ?></div>
<div class="sgCrumb"><?php echo $sg->crumbLine(); ?></div>
<!-- end of header.tpl.php -->
/photogallery/templates/modern/image.tpl.php
0,0 → 1,36
<h2><?php echo $sg->image->name(); ?></h2>
<h4><?php echo $sg->image->byArtistText(); ?></h4>
</div>
<div id="sgContent">
 
<div class="sgImageWrapper">
<div class="sgImageBox" style="width: <?php echo $sg->image->width(); ?>px; ">
<?php echo $sg->image->imageHTML() ?>
<a class="thumb" style="width: <?php echo $sg->image->width().'px;" href="'.$sg->image->parent->URL().'"><span>'.$sg->translator->_g("image|Thumbnails").'</span></a>'; ?>
<?php if($sg->image->hasPrev()) {echo '<a class="prev" style="height:'.$sg->image->height().'px;" href="'.$sg->image->prevURL().'"><span style="margin-top:'.floor(($sg->image->height())/2).'px;">'.$sg->translator->_g("image|Previous").'</span></a>'; } ?>
<?php if($sg->image->hasNext()) {echo '<a class="next" style="height:'.$sg->image->height().'px;" href="'.$sg->image->nextURL().'"><span style="margin-top:'.floor(($sg->image->height())/2).'px;">'.$sg->translator->_g("image|Next").'</span></a>'; } ?>
</div>
</div>
 
<?php if ($sg->config->show_fullsizeURL == 1) { ?>
<p class="sgFullsize"><a href="<?php echo $sg->image->realURL(); ?>"><?php echo $sg->translator->_g("image|View Full Size Image"); ?></a> <a href="<?php echo $sg->image->realURL(); ?>" target="_new">[+]</a></p>
<?php } ?>
 
<div class="sgDetailsList">
<dl>
<?php foreach($sg->image->detailsArray() as $key => $value): ?>
<dt><?php echo $key; ?>:</dt><dd><?php echo $value; ?></dd>
<?php endforeach; ?>
</dl>
</div>
 
<div class="sgPreview">
<?php echo $sg->previewThumbnails(); ?>
<p>
<?php if($sg->image->hasPrev()) echo "&#8249; ".$sg->image->prevLink()." &nbsp;&nbsp; "; ?>
<?php echo $sg->image->parentLink(); ?>
<?php if($sg->image->hasNext()) echo " &nbsp;&nbsp; ".$sg->image->nextLink()." &#8250;"; ?>
</p>
</div>
</div>
<?php echo $sg->imageMap() ?>
/photogallery/templates/modern/img/loader_b.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/modern/img/loader_w.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/photogallery/templates/modern/index.tpl.php
0,0 → 1,49
<?php
 
/**
* Modern Template by Ross Howard
* http://www.abitcloser.com/projects/singapore
*/
 
//debugging code
//error_reporting(E_ALL);
 
// set embed to false
$embed = false;
 
//load user details (must be done after session_start)
$sg->loadUser();
 
//if slideshow then set external
if($sg->action == 'slideshow') {$embed = true;}
 
//include header file
if ($embed == false) {
include $sg->config->base_path.$sg->config->pathto_current_template."header.tpl.php";
}
 
//watch actions and pagetypes
switch($sg->action) {
case "addcomment" :
include $sg->config->base_path.$sg->config->pathto_current_template."addcomment.tpl.php";
default :
if($sg->action == 'slideshow') {
//this is an 'slideshow' page so include the 'slideshow' template file
include $sg->config->base_path.$sg->config->pathto_current_template."slideshow.tpl.php";
} elseif($sg->isImagePage()) {
//this is an 'image' page so include the 'image' template file
include $sg->config->base_path.$sg->config->pathto_current_template."image.tpl.php";
} elseif($sg->isAlbumPage()) {
//this is an 'album' page so include the 'album' template file
include $sg->config->base_path.$sg->config->pathto_current_template."album.tpl.php";
} else {
//this is a 'gallery' page so include the 'gallery' template file
include $sg->config->base_path.$sg->config->pathto_current_template."gallery.tpl.php";
}
}
//include footer file
if ($embed == false) {
include $sg->config->base_path.$sg->config->pathto_current_template."footer.tpl.php";
}
?>
/photogallery/templates/modern/readme.txt
0,0 → 1,60
Modern - singapore template v1.3.2
by Ross Howard (www.abitcloser.com/projects/singapore)
 
Modern is a lightweight xHTML/CSS template for singapore.
 
It includes gallery, album and image pages, and also has
a built-in slideshow, and full-size image pop-up ability.
 
It uses common naming conventions (albeit with an sg prefix)
and a clean div structure to allow you to easily and simply customise
it to suit your needs.
 
It supports both fixed-width, and scaling page sizes, and is intended to
be web standard compliant and render correctly on a wide range of browsers.
These include Mozilla/Firefox 1.5, Safari, Opera and IE6.
 
Modern comes standard with a default 'black on black' colour scheme, but also
includes CSS files for 'white on black' and 'white on white'.
 
By default, Modern uses the 'Arial, Helvetica, sans-serif;' font family, as
declared for the body CSS. Simply changing this one line will effect the
entire template.
 
If you make any changes to template.ini please make sure to check the CSS file
too, in case you need to adjust page or thumbnail block widths.
 
TODO - Future Versions
 
Add Javascript UI library
Add AJAX Slideshow
 
CHANGELOG
 
1.3.2 - NEW RSS included as <link> in each page - Uses RSS template
1.3.2 - NEW Update check system checks for new version of Modern when logged in and viewing root public page
1.3.2 - NEW versioning number system
 
1.3 - FIX stop slideshow link for galleries with child galleries
1.3 - FIX template.ini thumb_force_size renamed to thumb_crop_
1.3 - FIX CSS image urls
1.3 - FIX Slideshow rollovers wrong size with resized images
1.3 - FIX slideshow links for galleries with no images
1.3 - Rewrote CSS to separate structure from colour
 
1.2 - Added 'Loading' GIF
1.2 - Added Play/Pause for Slideshow
1.2 - All text now utilised translator
1.2 - Added ability to use old image map in image page (not in slideshow) but have set it as off in template.ini which overwrites singapore.ini
1.2 - Rewrite URL coding to work without mod_rewrite and handles variable stack detection in URL
1.2 - Set colour scheme to 'black on black' by default, can be set via template.ini
1.2 - Added ability to float galleries next to each other via template.ini
1.2 - Added simple HTML slideshow that can be enabled via template.ini
1.2 - Added link to full size image when current image is resized, can enabled via template.ini
1.2 - Added rollover behaviour for image navigation which replaces imagemap
 
1.1 - Added support for external.php and prefixed selectors with sg
 
1.0 - Added IE conditional comments
 
0.9 - Original working build
/photogallery/templates/modern/slideshow.tpl.php
0,0 → 1,34
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title><?php echo $sg->translator->_g("image|Slideshow").' - '.$sg->pageTitle(); ?></title>
<style type="text/css">@import url("<?php echo $sg->config->base_url.$sg->config->pathto_current_template.'css/layout.css");</style>'; ?>
<style type="text/css">@import url("<?php echo $sg->config->base_url.$sg->config->pathto_current_template.'css/color_'.$sg->config->template_scheme.'.css");</style>'; ?>
<!--[if IE]><link rel="stylesheet" type="text/css" media="all" href="<?php echo $sg->config->base_url.$sg->config->pathto_current_template; ?>css/ie.css"><![endif]-->
<?php if($sg->image->hasNext() && !isset($control)) {
echo '<meta http-equiv="refresh" content="5;url='.$sg->image->nextURL('slideshow').'" />';
} ?>
</head>
<body id="slideshow">
<!--
This page was generated by singapore <http://singapore.sourceforge.net>
singapore is free software licensed under the terms of the GNU GPL.
-->
<div class="sgImageWrapper">
<div class="sgImageBox" style="width: <?php echo $sg->image->width(); ?>px; margin-top:-<?php echo floor($sg->image->height()/2); ?>px;" title="<?php foreach($sg->image->detailsArray() as $key => $value): ?><?php echo $key; ?>: <?php echo $value; ?><?php endforeach; ?>">
<?php echo $sg->image->imageHTML() ?>
<a class="thumb" style="width: <?php echo $sg->image->width(); ?>px;" href="<?php echo $sg->image->parent->URL().'"><span>'.$sg->translator->_g("image|Thumbnails").'</span></a>'; ?>
<?php if($sg->image->hasPrev()) {echo '<a class="prev" style="height:'.$sg->image->height().'px;" href="'.$sg->image->prevURL(); if (!strstr($sg->image->prevURL(), '?')) { echo '?'; } else { echo '&'; } echo 'action=slideshow"><span style="margin-top:'.floor(($sg->image->height())/2).'px;">'.$sg->translator->_g("image|Previous").'</span></a>';}?>
<?php if($sg->image->hasNext()) {echo '<a class="next" style="height:'.$sg->image->height().'px;" href="'.$sg->image->nextURL(); if (!strstr($sg->image->nextURL(), '?')) { echo '?'; } else { echo '&'; } echo 'action=slideshow"><span style="margin-top:'.floor(($sg->image->height())/2).'px;">'.$sg->translator->_g("image|Next").'</span></a>';}?>
<?php if (!isset($control)) {
echo '<a class="control" style="width:'.$sg->image->width().'px;" href="'.$sg->image->URL(); if (!strstr($sg->image->URL(), '?')) { echo '?'; } else { echo '&'; } echo 'action=slideshow&control=pause"><span>'.$sg->translator->_g("image|Pause").'</span></a>';
}
else {
echo '<a class="control" style="width:'.$sg->image->width().'px;" href="'.$sg->image->URL(); if (!strstr($sg->image->URL(), '?')) { echo '?'; } else { echo '&'; } echo 'action=slideshow"><span>'.$sg->translator->_g("image|Play").'</span></a>';
}
?>
</div>
</div>
</body>
</html>
/photogallery/templates/modern/template.ini
0,0 → 1,69
;Option descriptions have been grouped together here.
;Do not uncomment the following lines, they are for illustration only.
;
;thumb_width_*
; Width in pixels of thumbnails generated by the script.
; This option is affected by the thumb_force_size_* option (see below).
;
;thumb_height_*
; Height in pixels of thumbnails generated by the script.
; This option is affected by the thumb_force_size_* option (see below).
;
;thumb_force_size_*
; By default, width and height are maximum dimensions and images will be
; resized, maintaining the same aspect ratio, to fit within these limits.
; Turn force_size on to make the script crop images to the specified size.
;
;*_gallery
; These options affect gallery pages (those that contain sub-galleries).
;
;*_album
; These options affect album pages (those that contain only images).
;
;*_preview
; These options affect the preview thumbnails displayed on image pages.
;
;*_image
; These options affect full size display images and are only used if
; full_image_resize is on in singapore.ini
 
template_scheme = bob
;bob - black on black, wob - white on black, wow - white on white
imagemap_navigation = off
; typically set in singapore.ini but set here to stop cursor behaviour
 
thumb_width_gallery = 80
thumb_height_gallery = 80
thumb_force_size_gallery = off
thumb_number_gallery = 10
;Maximum number of galleries to show on one gallery page.
thumb_float_gallery = on
;Float gallery blocks side-by-side
 
thumb_width_album = 100
thumb_height_album = 100
thumb_force_size_album = off
thumb_number_album = 20
;Maximum number of image thumbnails to show on one album page.
 
thumb_width_preview = 50
thumb_height_preview = 50
thumb_force_size_preview = off
thumb_number_preview = 3
;Maximum number of preview thumbnails to display (including
;current image). An odd number is usually preferred.
 
show_fullsizeURL = on
;Turn this on to display link to the full size image
 
show_slideshowURL = on
;Turn this on to show a link to slideshow on gallery page
 
thumb_width_image = 700
thumb_height_image = 500
 
;Modern Update Checker - Connects to my site to check for new version
update_check = yes
update_url = http://www.abitcloser.com/files/
current_version = modern-v1.3.2
/photogallery/templates/rss/index.tpl.php
0,0 → 1,56
<?php
 
/**
* RSS 2.0 output for singapore.
*
* @author Ross Howard <abitcloser.com
* @copyright (c)2006 Tamlyn Rhodes
* @version 0.8
*/
 
if(headers_sent())
die("ERROR: Unable to send XML content-type header.");
else
header("Content-type: application/rss+xml; charset=".$sg->character_set);
 
echo '<?xml version="1.0" encoding="ISO-8859-1"?>'; ?>
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title><?php echo $sg->gallery->name(); ?></title>
<link><?php echo "http://".$_SERVER['HTTP_HOST'].($sg->config->use_mod_rewrite ? '' : dirname($_SERVER['PHP_SELF']).'/').str_replace("template=rss", "", $sg->gallery->URL()); ?></link>
<description><?php echo $sg->gallery->name(); ?> Feed</description>
<?php if(($timestamp = @strtotime($sg->gallery->date())) !== false && $timestamp != -1)
echo '<pubDate>'.date('r', $timestamp).'</pubDate>'; ?>
<generator>http://www.sgal.org/</generator>
<?php if($sg->isAlbumPage()) { ?>
<?php for($index = $sg->gallery->startat; $index < $sg->gallery->imageCountSelected()+$sg->gallery->startat; $index++): ?>
<item>
<title><?php echo $sg->gallery->images[$index]->name; ?></title>
<link><?php echo "http://".$_SERVER['HTTP_HOST'].str_replace("?template=rss", "", $sg->gallery->images[$index]->url()); ?></link>
<?php if(($timestamp = @strtotime($sg->gallery->images[$index]->date())) !== false && $timestamp != -1)
echo '<pubDate>'.date('r', $timestamp).'</pubDate>'; ?>
<dc:creator><?php echo $sg->gallery->images[$index]->artist(); ?></dc:creator>
<description>
<![CDATA[ <?php echo $sg->gallery->images[$index]->description(); ?> ]]>
</description>
</item>
<?php endfor; ?>
<?php } elseif($sg->isGalleryPage()) { ?>
<?php for($index = $sg->gallery->startat; $index < $sg->gallery->galleryCountSelected()+$sg->gallery->startat; $index++): ?>
<item>
<title><![CDATA[<?php echo $sg->gallery->galleries[$index]->name(); ?> ]]></title>
<link><?php echo "http://".$_SERVER['HTTP_HOST'].str_replace("?template=rss", "", $sg->gallery->galleries[$index]->url()); ?></link>
<?php if(($timestamp = @strtotime($sg->gallery->date())) !== false && $timestamp != -1)
echo '<pubDate>'.date('r', $timestamp).'</pubDate>'; ?>
<dc:creator><?php echo $sg->gallery->galleries[$index]->artist(); ?></dc:creator>
<description>
<![CDATA[ <?php echo $sg->gallery->galleries[$index]->description(); ?>]]>
</description>
</item>
<?php endfor; ?>
<?php } ?>
</channel>
</rss>
/photogallery/templates/rss/template.ini
0,0 → 1,10
 
thumb_number_gallery = 100
;Maximum number of gallery items to show in one feed.
 
thumb_number_album = 100
;Maximum number of image items to show in one feed.
track_views = false
;Turn off hit logging as we don't want to count every hit
;to the RSS feed
/photogallery/galleries/Readme.txt
0,0 → 1,0
This directory is used to store galleries and images. It must be writable (CHMOD 777).
/photogallery/galleries/index.php
0,0 → 1,0
<?php header("Location: ../") ?>
/photogallery/data/languages.cache
0,0 → 1,0
a:32:{s:7:"cs_utf8";s:13:"Czech (UTF-8)";s:2:"en";s:7:"English";}
/photogallery/data/index.php
0,0 → 1,0
<?php header("Location: ../") ?>
/photogallery/data/users.csv.php
0,0 → 1,3
<?php die("The contents of this file are hidden"); ?>username,md5(pass),permissions,group(s),email,name,description,stats
admin,5f4dcc3b5aa765d61d8327deb882cf99,1024,"","","Administrator","Default administrator account",""
guest,5f4dcc3b5aa765d61d8327deb882cf99,2048,"","","Guest","Restricted use account for guests who do not have a user account",""
/photogallery/locale/index.php
0,0 → 1,0
<?php header("Location: ../") ?>
/photogallery/locale/singapore.admin.cs_utf8.pmo
0,0 → 1,5
a:139:{s:53:"You do not have permission to perform this operation.";s:43:"Nemáte oprávnění provést tuto operaci.";s:13:"Gallery added";s:17:"Galerie přidána";s:18:"An error occurred:";s:14:"Nastala chyba:";s:11:"Image added";s:17:"Obrázek přidán";s:22:"Archive contents added";s:22:"Přidán obsah archivu";s:10:"confirm|OK";s:2:"OK";s:17:"Thumbnail changed";s:16:"Náhled změněn";s:14:"confirm|Cancel";s:7:"Zrušit";s:15:"Gallery deleted";s:16:"Galerie smazána";s:14:"delete gallery";s:14:"Smazat galerii";s:118:"Gallery %s is not empty.
Are you sure you want to irretrievably delete it and all subgalleries and images it contains?";s:131:"Galerie %s není prázdná.
Jste si jist(a), že chcete ji, všechny její subgalerie a obrázky co obsahují, nenávratně smazat?";s:13:"Image deleted";s:16:"Obrázek smazán";s:12:"delete image";s:15:"Smazat obrázek";s:71:"Are you sure you want to irretrievably delete image %s from gallery %s?";s:73:"Jste si jist(a), že chcete nenávratně smazat obrázek %s z galerie %s?";s:12:"User deleted";s:17:"Uživatel smazán";s:11:"delete user";s:17:"Smazat uživatele";s:52:"Are you sure you want to permanently delete user %s?";s:58:"Jste si jist(a), že chcete trvale odstranit uživatee %s?";s:27:"Welcome to singapore admin!";s:50:"Vítejte v administrační sekci sinapore galerie!";s:22:"Thank you and goodbye!";s:29:"Děkujeme vám a nashledanou!";s:22:"Thumbnail cache purged";s:29:"Cache náhledů vyčištěna.";s:23:"purge cached thumbnails";s:25:"Vyčistit cache náhledů";s:57:"Are you sure you want to delete all %s cached thumbnails?";s:74:"Jste si jist(a), že chcete odstranit všech %s nacacheovaných náhledů?";s:36:"Gallery re-indexed. %s images added.";s:47:"Galerie přeindexována. %s obrázů přidáno.";s:18:"Gallery info saved";s:23:"Uloženo info o galerii";s:24:"Image saved successfully";s:28:"Obrázek uložen úspěšně";s:14:"Password saved";s:14:"Heslo uloženo";s:17:"Permissions saved";s:15:"Práva uložena";s:15:"User info saved";s:32:"Uživatelské informace uloženy";s:14:"admin bar|Back";s:5:"Zpět";s:15:"admin bar|Admin";s:5:"Admin";s:19:"admin bar|Galleries";s:7:"Galerie";s:17:"admin bar|Log out";s:9:"Odhlásit";s:22:"admin bar|Edit gallery";s:16:"Editovat galerii";s:26:"admin bar|Edit permissions";s:15:"Editovat práva";s:24:"admin bar|Delete gallery";s:14:"Smazat galerii";s:24:"admin bar|New subgallery";s:16:"Nová podgalerie";s:26:"admin bar|Re-index gallery";s:21:"Přeindexovat galerii";s:20:"admin bar|Edit image";s:17:"Editovat obrázek";s:22:"admin bar|Delete image";s:15:"Smazat obrázek";s:19:"admin bar|New image";s:14:"Nový obrázek";s:24:"Could not save user info";s:37:"Nelze uložit uživatelské informace";s:54:"New password must be between 6 and 16 characters long.";s:45:"Nové heslo musí mít mezi 6ti a 16ti znaky.";s:43:"The new passwords you entered do not match.";s:33:"Nově zadané heslo se neshoduje.";s:72:"The current password you entered does not match the one in the database.";s:63:"Současné heslo vámi zadané se neshoduje s tím z databáze.";s:53:"The username specified was not found in the database.";s:56:"Zadané uživatelské jméno se nenachází v databázi.";s:31:"Your account has been suspended";s:38:"Váš účet byl dočasně pozastaven.";s:34:"Username and/or password incorrect";s:48:"Uživatelské jméno a/nebo heslo je nesprávné";s:38:"You must enter a username and password";s:42:"Musíte zadat uživatelské jméno a heslo";s:27:"Could not save gallery info";s:33:"Nelze uložit informace o galerii";s:23:"Username already exists";s:34:"Uživatelské jméno již existuje";s:31:"Cannot delete built in accounts";s:31:"Nelze smazat vestavěné účty";s:23:"Username not recognised";s:39:"Uživatelské jméno nebylo rozpoznáno";s:22:"Gallery already exists";s:21:"Galerie již existuje";s:26:"Could not create directory";s:25:"Nelze vytvořit adresář";s:37:"Cannot delete the top level directory";s:34:"Nelze smazat nejvyšší adresář";s:19:"File already exists";s:20:"Soubor již existuje";s:21:"Could not upload file";s:20:"Nelze nahrát soubor";s:30:"Could not add image to gallery";s:33:"Nelze přidat obrázek do galerie";s:38:"Could not find temporary storage space";s:35:"Nelze najít dočasné úložiště";s:28:"Could not decompress archive";s:21:"Nelze rozbalit archiv";s:40:"Some archive contents could not be added";s:42:"Část obsahu archivu se nepovedlo přidat";s:32:"Could not save image information";s:34:"Nelze uložit informace o obrázku";s:22:"Could not delete image";s:21:"Nelze smazat obrázek";s:17:"Select gallery...";s:18:"Vyberte galerii...";s:16:"choose thumbnail";s:14:"Zvolte náhled";s:64:"Choose the filename of the image used to represent this gallery.";s:54:"Zvolte jméno souboru, který bude zastupovat galerii.";s:14:"thumbnail|None";s:8:"Žádné";s:16:"thumbnail|Random";s:9:"Náhodné";s:12:"edit gallery";s:16:"Editovat galerii";s:9:"Thumbnail";s:7:"Náhled";s:16:"Random
thumbnail";s:17:"Náhodný
náhled";s:19:"thumbnail|Change...";s:10:"Změnit...";s:12:"Gallery name";s:14:"Jméno galerie";s:11:"Artist name";s:13:"Jméno autora";s:7:"Summary";s:8:"Shrnutí";s:10:"edit image";s:17:"Editovat obrázek";s:5:"Image";s:8:"Obrázek";s:10:"Image name";s:15:"Jméno obrázku";s:15:"change password";s:13:"Změnit heslo";s:67:"Please choose a new password between 6 and 16 characters in length.";s:52:"Zvolte, prosím, nové heslo délky 6 až 16 znaků.";s:17:"Current password:";s:17:"Současné heslo:";s:13:"New password:";s:12:"Nové heslo:";s:17:"Confirm password:";s:17:"Potvrzení heslo:";s:16:"edit permissions";s:15:"Editovat práva";s:5:"Owner";s:9:"Vlastník";s:6:"Groups";s:7:"Skupiny";s:17:"Group permissions";s:13:"Práva skupin";s:16:"permissions|Read";s:7:"Čtení";s:16:"permissions|Edit";s:7:"Editace";s:15:"permissions|Add";s:10:"Přidání";s:18:"permissions|Delete";s:8:"Mazání";s:17:"World permissions";s:17:"Globální práva";s:15:"user management";s:19:"Správa uživatelů";s:8:"Username";s:20:"Uživatelské jméno";s:4:"Type";s:3:"Typ";s:13:"Administrator";s:14:"Administrátor";s:4:"User";s:9:"Uživatel";s:9:"Full name";s:12:"Celé jméno";s:8:"Password";s:5:"Heslo";s:22:"admin bar|View gallery";s:16:"Zobrazit galerii";s:26:"admin bar|Change thumbnail";s:15:"Změnit náhled";s:16:"hits table|Graph";s:4:"Graf";s:15:"hits table|Hits";s:10:"Zobrazení";s:19:"hits table|Last hit";s:20:"Poslední zobrazení";s:14:"Admin message:";s:15:"Zpráva admina:";s:6:"log in";s:14:"Přihlášení";s:52:"Please enter your admin username and password below.";s:72:"Zadejte, prosím, vaše administrátorské uživatelské jméno a heslo.";s:9:"Username:";s:21:"Uživatelské jméno:";s:9:"Password:";s:6:"Heslo:";s:61:"If you do not have a username then you may log in as a guest.";s:70:"Pokud nemáte uživatelské jméno, můžete se přihlásit jako host.";s:49:"You must be an administrator to access this area.";s:57:"Musíte být administrátor pro přístup do této sekce.";s:6:"Email:";s:6:"Email:";s:10:"Full name:";s:13:"Celé jméno:";s:4:"edit";s:8:"Editovat";s:6:"delete";s:6:"Smazat";s:7:"suspend";s:10:"Pozastavit";s:9:"unsuspend";s:12:"Odpozastavit";s:15:"create new user";s:28:"Vytvořit nového uživatele";s:24:"Please choose an option:";s:30:"Prosím vyberte jednu z voleb:";s:27:"Manage galleries and images";s:28:"Spravovat galerie a obrázky";s:17:"View gallery hits";s:30:"Statistiky zobrazení galerií";s:15:"Change password";s:12:"Změna hesla";s:10:"My profile";s:11:"Můj profil";s:12:"Manage users";s:20:"Spravovat uživatele";s:23:"Purge cached thumbnails";s:32:"Vyčistit nacacheované náhledy";s:16:"Log out of admin";s:26:"Odhlásit se z admin sekce";s:11:"new gallery";s:13:"Nová galerie";s:11:"Identifier:";s:15:"Identifikátor:";s:9:"new image";s:14:"Nový obrázek";s:74:"This image will not be visible because this gallery contains subgalleries.";s:72:"Tento obrázek nebude vidět, protože tato galerie obsahuje subgalerie.";s:18:"Upload single file";s:20:"Nahrát jeden soubor";s:21:"Image file to upload:";s:28:"Soubor obrázku k nahrání:";s:30:"Use filename of uploaded file.";s:33:"Použij název nahraného souboru";s:27:"Specify different filename:";s:26:"Zadej jiné název souboru";s:21:"Upload multiple files";s:22:"Nahrát více souborů";s:19:"ZIP file to upload:";s:23:"ZIP archiv k nahrání:";s:15:"Add remote file";s:25:"Přidat vzdálený soubor";s:13:"URL of image:";s:13:"URL obrázku:";i:0;a:3:{s:7:"charset";s:5:"UTF-8";s:8:"language";s:13:"Czech (UTF-8)";s:6:"plural";s:31:"$nplurals=1; $plural=$n==1?0:1;";}}
/photogallery/locale/singapore.cs_utf8.pmo
0,0 → 1,3
a:44:{s:22:"Gallery not found '%s'";s:23:"Galerie '%s' nenalezena";s:20:"Image not found '%s'";s:23:"Obrázek '%s' nenalezen";s:8:"email|at";s:9:"zavináč";s:9:"email|dot";s:6:"tečka";s:26:"Page created in %s seconds";s:35:"Stránka vygenerována za %s sekund";s:23:"singapore|Powered by %s";s:18:"Provozováno na %s";s:20:"All rights reserved.";s:26:"Všechna práva vyhrazena.";s:104:"Images may not be reproduced in any form without the express written permission of the copyright holder.";s:113:"Obrázky nesmí být jakkoli reprodukovány či kopírovány bez písemného souhlasu autora či držitele práv.";s:6:"Log in";s:14:"Přihlášení";s:24:"crumb line|You are here:";s:18:"Nacházíte se v: ";s:10:"image|Next";s:7:"Další";s:16:"image|Thumbnails";s:8:"Náhledy";s:14:"image|Previous";s:11:"Předchozí";s:18:"Select language...";s:16:"Vyberte jazyk...";s:2:"Go";s:5:"Vstup";s:18:"Select template...";s:19:"Vyberte šablonu...";s:10:"%s gallery";a:2:{i:0;s:10:"%s galerie";i:1;s:11:"%s galerií";}s:8:"%s image";a:2:{i:0;s:11:"%s obrázek";i:1;s:12:"%s obrázků";}s:12:"No
thumbnail";s:13:"Není
náhled";s:25:"Sample image from gallery";s:27:"Vzorový obrázek z galerie";s:19:"Showing %s-%s of %s";s:20:"Zobrazuji %s-%s z %s";s:10:"gallery|Up";s:6:"Nahoru";s:20:"gallery|Up one level";s:23:"Nahoru o jednu úroveň";s:16:"gallery|Previous";s:11:"Předchozí";s:13:"gallery|First";s:6:"První";s:12:"gallery|Next";s:7:"Další";s:12:"gallery|Last";s:9:"Poslední";s:17:"artist name|by %s";s:5:"od %s";s:5:"Email";s:5:"Email";s:11:"Description";s:5:"Popis";s:9:"Copyright";s:9:"Copyright";s:6:"Viewed";s:9:"Zobrazeno";s:14:"viewed|%s time";a:2:{i:0;s:8:"%s krát";i:1;s:8:"%s krát";}s:13:"Add a comment";s:18:"Přidat komentář";s:11:"image|First";s:6:"První";s:10:"image|Last";s:9:"Poslední";s:8:"Location";s:6:"Místo";s:4:"Date";s:5:"Datum";s:6:"Camera";s:11:"Fotoaparát";s:4:"Lens";s:7:"Čočka";s:4:"Film";s:4:"Film";s:21:"Darkroom manipulation";s:22:"Zpracování v komoře";s:20:"Digital manipulation";s:24:"Digitální zpracování";i:0;a:3:{s:7:"charset";s:5:"UTF-8";s:8:"language";s:13:"Czech (UTF-8)";s:6:"plural";s:31:"$nplurals=1; $plural=$n==1?0:1;";}}
/photogallery/singapore.ini
0,0 → 1,272
; singapore main configuration file <http://singapore.sourceforge.net>
;
; Split into sections (Basic, Paths, Functionality, SQL & Advanced)
; for ease of reading. Sections are ignored by the script.
;
; Any of these settings can be overridden in gallery.ini or
; template.ini files. See the readme for more information.
;
; Template specific settings may be found in the template.ini
; file located in the template's root directory.
 
 
[Basic]
;
; settings that most users will want to look at and possibly change
;
 
thumbnail_software = "gd2"
;the software to use to generate the thumbnails
; gd1 = GD v1.x
; gd2 = GD v2.x
; im = ImageMagick v5.x
; im6 = ImageMagick v6.x
gallery_name = "MLAB"
;this is the text that will appear in the title bar of all
;generated pages and also the root node of the crumb line
default_template = "MLAB"
;the name of the template to use when none is specified
default_language = "cs_utf8"
;the language code for the language that you would like to use.
;you must have the appropriate language file in the locale directory.
 
gallery_sort_order = "x"
;the order in which galleries will be displayed. Can take the following values:
; p = sort by directory name (ascending)
; P = sort by directory name (descending)
; n = sort by gallery name (ascending)
; N = sort by gallery name (descending)
; i = sort by gallery name (case insensitive, ascending)
; I = sort by gallery name (case insensitive, descending)
; a = sort by artist name (ascending)
; A = sort by artist name (descending)
; d = sort by date (ascending)
; D = sort by date (descending)
; note: date comparison is done as a string comparison on the 'date' database
; field. So for example "2003-10-22" comes before "22 October 2003"
; x = do not sort (default)
image_sort_order = "x"
;the order in which images will be displayed. Can take the following values:
; f = sort by file name (ascending)
; F = sort by file name (descending)
; n = sort by image name (ascending)
; N = sort by image name (descending)
; i = sort by image name (case insensitive, ascending)
; I = sort by image name (case insensitive, descending)
; a = sort by artist name (ascending)
; A = sort by artist name (descending)
; d = sort by date (ascending)
; D = sort by date (descending)
; note: date comparison is done as a string comparison on the 'date' database
; field. So for example "2003-10-22" comes before "22 October 2003"
; l = sort by location (ascending)
; L = sort by location (descending)
; x = do not sort (default)
upload_overwrite = 2
;what to do when uploading an image or gallery that already exists:
; 0 do not overwrite, raise an error (default)
; 1 overwrite without prompting
; 2 attempt to generate a new unique name
 
[Functionality]
;
; some features are turned off by default. Try them out by turning them on here.
;
 
language_flipper = on
;turn on to display a select box which allows users to select a language
 
template_flipper = on
;turn on to display a select box which allows users to select a template
 
full_image_resize = off
;turn on to force all full-size images to be resized to the size specified
;in the current template's template.ini
imagemap_navigation = off
;turns full-size images into image maps so that clicking on
;them takes you forward/backward/up
track_views = on
;whether to keep track of how many times images and
;galleries have been viewed
 
show_views = on
;whether to display how many times images and galleries
;have been viewed
 
show_execution_time = on
;display script execution time in milliseconds
 
enable_iifn = on
;enables parsing of directory and file names of the form
;'artist_name - image_name' into metadata information
obfuscate_email = on
;tries to conceal email addresses from spambots by
;replacing '.' with ' dot ' and '@' with ' at '
enable_clickable_urls = on
;makes the script detect URLs in image & gallery descriptions
;and make them 'clickable' by adding the appropriate HTML
 
remove_jpeg_profile = off
;true to tell ImageMagick to remove any profile information
;from generated thumbnails. This has been known to cause some
;problems hence it being disabled by default
progressive_thumbs = on
;generate progressive JPEG and interlaced GIF & PNG images.
use_mod_rewrite = off
;format generated URLs for use with Apache mod_rewrite
;you need to enable mod_rewrite and create an appropriate .htaccess file
detect_language = off
;attempt to detect user language from browser information
;if this fails the default_language will be used
 
[Paths]
;
; The default paths will be fine for most people.
;
 
pathto_templates = "templates/"
;path to directory containing templates
;must be specified relative to singapore root
pathto_data_dir = "data/"
;path to writable data directory
;must be specified relative to singapore root
pathto_galleries = "galleries/"
;path to galleries directory
;must be specified relative to singapore root
pathto_locale = "locale/"
;path to directory containing internationalisation files (singapore.LANG.pmo)
;must be specified relative to singapore root
 
pathto_convert = "convert"
;full path to ImageMagick convert utility if it is not in your PATH
pathto_unzip = "unzip"
;full path to Info-Zip unzip utility or equivalent if it is not in your PATH
 
;base_path option is in the [Advanced] section below
 
[SQL]
;
; settings relevant to all the SQL backends (except SQLite).
; You may ignore these if you are not using one of these backends.
; For security reasons username and password are stored in secret.ini.php
;
 
sql_host = "localhost"
;name of computer running MySQL server (usually localhost)
;a port number may be included as in "example.com:1234"
sql_database = "singapore"
;database in which information will be stored. this must already exist.
 
sql_prefix = "sg_"
;this will be prefixed to the names of the tables created (galleries, images & users).
;each singapore installation running on same database should have a different prefix.
 
[FTP]
;
; The safe_mode hack uses FTP to create galleries.
; You may ignore these settings if your server is not runing in safe_mode.
; For security reasons username and password are stored in secret.ini.php
;
 
safe_mode_hack = off
;set to on to enable the hack
 
ftp_server = ""
;the hostname you use to login to your website
;a port number may be included as in "example.com:1234"
ftp_base_path = ""
;path from ftp root to singapore root
[Advanced]
;
; settings most users will not need to change
;
 
io_handler = "mysql"
;the type of database to use. recognised values are:
; csv = flat file, no database needed (default)
; mysql = MySQL database (configure sql_* settings above and in secret.ini.php)
; sqlite = SQLite database (does not require any further configuration)
allow_dir_upload = 1
;allow uploading archives containing arbitrary files.
; 0 = allow no one
; 1 = allow all registered users
; 2 = allow only administrators
admin_template_name = "admin_default"
;the name of the admin template to use
thumbnail_quality = 75
;the JPEG quality of generated thumbnails
;100 is the highest quality 0 is the lowest
session_name = "PHPSESSID"
;the name of the admin session. each independent singapore
;installation on the same domain should have a different name
default_charset = "utf-8"
;the character encoding to use for generated pages if none
;is specified in the current language file
index_file_url = "index.php?"
;filename of index file plus any query-string
;if a path is specified it must be absolute
base_path = ""
;file-system-view absolute or relative path to installation
;can usually be left blank
base_url = ""
;web-view absolute or relative url of installation.
;can usually be left blank
recognised_extensions = "jpeg|jpg|jpe|png|gif|bmp|tif|tiff"
;list of file extensions that will be recognised as images
;this forms part of a pcre hence the vertical bars (meaning OR)
 
allowed_tags = "<a><b><i><u><em><strong><strike>"
;list of HTML tags which will be allowed in multiline database entries
;such as description and summary
directory_mode = 0777
;the permissions to set on directories
;(i.e. galleries) created by the script
 
file_mode = 0666
;the permissions to set on files (thumbnails, logs,
;images & metadata files) created by the script.
[GET variable names]
;
; names of variables used to pass information in URLs
; you will only need to change these if there is a conflict with
; already existing variables and the installation is being integrated.
;
 
url_gallery = "gallery"
url_image = "image"
url_startat = "startat"
url_action = "action"
url_lang = "lang"
url_template = "template"
/photogallery/secret.ini.php
0,0 → 1,23
; singapore secret configuration file <http://singapore.sourceforge.net>
;
; <?php die("The contents of this file are hidden"); ?>
;
; these options are hidden from web users
 
[SQL]
;
; settings relevant to all the SQL backends.
; You may ignore these if you are not using this backend.
;
 
sql_user = "gallery"
sql_pass = "MQbanQdt83x9UD:d"
 
[FTP]
;
; settings used by the safe_mode hack.
; You may ignore these if your server is not running in safe_mode.
;
 
ftp_user = ""
ftp_pass = ""
/photogallery/Readme.txt
0,0 → 1,21
 
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* singapore - Copyright 2003 Tamlyn Rhodes <tam@zenology.org> *
* *
* singapore is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation; either version 2 of the License, *
* or (at your option) any later version. *
* *
* singapore is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this; if not, write to the Free Software Foundation, *
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 
See docs/ or http://singapore.sourceforge.net/ for more information.
/photogallery/index.php
0,0 → 1,37
<?php
 
/**
* Main file drives the gallery.
*
* Do not include this file into another page; include external.php instead.
*
* @package singapore
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003, 2004 Tamlyn Rhodes
* @version $Id: index.php,v 1.21 2006/08/05 19:56:32 thepavian Exp $
*/
 
//include main class
require_once "includes/singapore.class.php";
 
//create a wrapper
$sg = new Singapore();
 
//set session arg separator to be xml compliant
ini_set("arg_separator.output", "&amp;");
 
//only start session if session is already registered
if(isset($_REQUEST[$sg->config->session_name])) {
//start session
session_name($sg->config->session_name);
@session_start();
}
 
//send content-type and character encoding header
@header("Content-type: text/html; charset=".$sg->character_set);
 
//pass control over to template
@include $sg->config->base_path.$sg->config->pathto_current_template."index.tpl.php";
 
?>
/photogallery/external.php
0,0 → 1,54
<?php
 
/**
* Alternate file to drive the gallery designed to be included within another
* page.
*
* This page will only send content-type headers if they have not already
* been sent. Placing a call to ob_start() within the including page before any
* content has been output will allow singapore to use non-default charsets.
*
* @package singapore
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003-2005 Tamlyn Rhodes
* @version $Id: external.php,v 1.4 2006/08/07 10:04:28 thepavian Exp $
*/
 
//you may leave this blank as it will be automatically detected
$relativePath = "";
 
//check whether this file has been included by another and if
//so calculate the relative path and instantiate $sg with it
if(isset($_SERVER["SCRIPT_FILENAME"]) && realpath(__FILE__) != realpath($_SERVER["SCRIPT_FILENAME"])) {
//split each path into chunks
$you = explode(DIRECTORY_SEPARATOR,dirname(realpath($_SERVER["SCRIPT_FILENAME"])));
$me = explode(DIRECTORY_SEPARATOR,dirname(realpath(__FILE__)));
$i=0;
//find at what level paths first differ
while($i<count($you) && $i<count($me) && $you[$i] == $me[$i]) $i++;
//travel up appropriate number of directories
for($j=$i;$j<count($you);$j++) $relativePath .= "../";
//travel down appropriate directories
for($j=$i;$j<count($me); $j++) $relativePath .= $me[$j]."/";
 
//otherwise print an error as this is not how external.php is supposed to work.
} else {
die("This file is not intended to be used in this way. Please see the singapore integration guide.");
}
 
//include main class
require_once $relativePath."includes/singapore.class.php";
 
//create a wrapper
$sg = new Singapore($relativePath);
 
//send content-type and character encoding header
if(!headers_sent())
header("Content-type: text/html; charset=".$sg->character_set);
 
//pass control over to template
@include $sg->config->base_path.$sg->config->pathto_current_template."index.tpl.php";
 
?>
/photogallery/admin.php
0,0 → 1,43
<?php
 
/**
* Admin interface file.
*
* Checks the selected 'action', checks user permissions, calls the appropriate
* methods and sets the required include file. Finally it includes the admin
* template's index file.
*
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @package singapore
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003, 2004 Tamlyn Rhodes
* @version $Id: admin.php,v 1.36 2006/01/27 13:31:24 tamlyn Exp $
*/
 
//include admin class
require_once "includes/admin.class.php";
 
//create the admin object
$sg = new sgAdmin();
 
//set session arg separator to be xml compliant
ini_set("arg_separator.output", "&amp;");
 
//start session
session_name($sg->config->session_name);
@session_start();
 
//load user details (must be done after session_start)
$sg->loadUser();
 
//send content-type and character encoding header
@header("Content-type: text/html; charset=".$sg->character_set);
 
//perform admin action
$sg->doAction();
 
//pass control over to template
include $sg->config->pathto_admin_template."index.tpl.php";
 
 
?>
/photogallery/tools/cleanup.php
0,0 → 1,59
<?php
 
/**
* This file attempts to recursively make all files in the parent directory
* (i.e. the singapore root directory) writable. This will, in general, only
* succeed on server-owned content hence making it deletable by FTP users.
*
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2004 Tamlyn Rhodes
* @version $Id: cleanup.php,v 1.4 2006/03/02 16:14:03 tamlyn Exp $
*/
 
/**
* Recursively attempts to make all files and directories in $dir writable
*
* @param string full directory name (must end with /)
*/
function makeWritable($dir)
{
if (is_dir($dir)) {
$d = dir($dir);
while (($file = $d->read()) !== false) {
//ignore current and parent dirs and php files
if ($file == '.' || $file == '..' || substr($file, strlen($file)-4)=='.php') continue;
$fullfile = $d->path . $file;
if(@chmod($fullfile,0777))
echo "Made $fullfile writable.<br />";
if (is_dir($fullfile))
makeWritable($fullfile."/");
}
}
}
 
 
 
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>cleanup script</title>
<link rel="stylesheet" type="text/css" href="tools.css" />
</head>
 
<body>
 
<h1>Fixing file permissions</h1>
 
<p><?php
//start with parent directory (singapore root)
makeWritable("../");
?></p>
 
<p>All done! <a href="index.html">Return</a> to tools.</p>
 
</body>
</html>
/photogallery/tools/compile.php
0,0 → 1,215
<?php
/**
* This file merges the two PO template files (singapore.pot and singapore.admin.pot)
* with all existing language files (singapore.LANG.po)
*
* @author Joel Sjögren <joel dot sjogren at nonea dot se>
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003-2005 Tamlyn Rhodes
* @version $Id: compile.php,v 1.9 2006/04/29 16:18:52 tamlyn Exp $
*/
 
// Programs to call (insert path to them if necessary)
$GETTEXT_MERGE = "msgmerge";
$BASEPATH = realpath("..")."/";
 
 
//require config class
require_once $BASEPATH."includes/config.class.php";
 
//get config object
$config = sgConfig::getInstance();
$config->loadConfig($BASEPATH."singapore.ini");
 
$OUTPUTPATH = $BASEPATH.$config->pathto_locale;
$standardPot = $OUTPUTPATH."singapore.pot";
$adminPot = $OUTPUTPATH."singapore.admin.pot";
$createbackups = true;
 
/**
* Parses a directory and returns full path to all the files
* matching the filter (file name suffix)
*
* @param string $dir full directory name (must end with /)
* @param string $filter file name suffixes separated by | (optional, default don't filter)
* @return array an array with all files
**/
function parseDirectory ($dir, $filter = 'php|html|tpl|inc')
{
$ret = array();
if (is_dir($dir)) {
$d = dir($dir);
while (($file = $d->read()) !== false) {
if ($file == '.' || $file == '..') continue;
$fullfile = $d->path . $file;
if (is_dir($fullfile)) $ret = array_merge($ret,parseDirectory($fullfile."/"));
else if (!$filter || preg_match("/\.({$filter})$/i", $file)) $ret[] = $fullfile;
}
}
return $ret;
}
 
 
/**
* Parses a PO file and writes a file with
* serialized strings for PHP
*
* @param string $input file to read from
* @param string $output file to write to
* @return bool success
**/
function parsePO ($input, $output)
{
// Open PO-file
file_exists($input) or die("The file {$input} doesn't exit.\n");
$fp = @fopen($input, "r") or die("Couldn't open {$input}.\n");
 
$type = 0;
$strings = array();
$escape = "\n";
$string = "";
$plural = 0;
$header = "";
while (!feof($fp)) {
$line = trim(fgets($fp,1024));
if ($line == "" || $line[0] == "#") continue;
// New (msgid "text")
if (preg_match("/msgid[[:space:]]+\"(.+)\"$/i", $line, $m)) {
$type = 1;
$string = stripcslashes($m[1]);
// New id on several rows (msgid "") or header
} elseif (preg_match("/msgid[[:space:]]+\"\"$/i", $line, $m)) {
$type = 2;
$string = "";
// Add to id on several rows ("")
} elseif (preg_match("/^\"(.*)\"$/i", $line, $m) && ($type == 1 || $type == 2 || $type == 3)) {
$type = 3;
$string .= stripcslashes($m[1]);
// New string (msgstr "text")
} elseif (preg_match("/msgstr[[:space:]]+\"(.+)\"$/i", $line, $m) && ($type == 1 || $type == 3) && $string) {
$strings[$string] = stripcslashes($m[1]);
$type = 4;
// New string on several rows (msgstr "")
} elseif (preg_match("/msgstr[[:space:]]+\"\"$/i", $line, $m) && ($type == 1 || $type == 3) && $string) {
$type = 4;
$strings[$string] = "";
// Add to string on several rows ("")
} elseif (preg_match("/^\"(.*)\"$/i", $line, $m) && $type == 4 && $string) {
$strings[$string] .= stripcslashes($m[1]);
/////Plural forms/////
// New plural id (msgid_plural "text")
} elseif (preg_match("/msgid_plural[[:space:]]+\".*\"$/i", $line, $m)) {
$type = 6;
// New plural string (msgstr[N] "text")
} elseif (preg_match("/msgstr\[(\d+)\][[:space:]]+\"(.+)\"$/i", $line, $m) && ($type == 6) && $string) {
$plural = $m[1];
$strings[$string][$plural] = stripcslashes($m[2]);
$type = 6;
// New plural string on several rows (msgstr[N] "")
} elseif (preg_match("/msgstr\[(\d+)\][[:space:]]+\"\"$/i", $line, $m) && ($type == 6) && $string) {
$plural = $m[1];
$strings[$string][$plural] = "";
$type = 6;
// Add to plural string on several rows ("")
} elseif (preg_match("/^\"(.*)\"$/i", $line, $m) && $type == 6 && $string) {
$strings[$string][$plural] .= stripcslashes($m[1]);
/////Header section/////
// Start header section
} elseif (preg_match("/msgstr[[:space:]]+\"(.+)\"$/i", $line, $m) && $type == 2 && !$string) {
$header = stripcslashes($m[1]);
$type = 5;
// Start header section
} elseif (preg_match("/msgstr[[:space:]]+\"\"$/i", $line, $m) && !$string) {
$header = "";
$type = 5;
// Add to header section
} elseif (preg_match("/^\"(.*)\"$/i", $line, $m) && $type == 5) {
$header .= stripcslashes($m[1]);
// Reset
} else {
unset($strings[$string]);
$type = 0;
$string = "";
$plural = 0;
}
}
 
// Close PO-file
fclose($fp);
// Extract plural forms from header
if(preg_match("/Plural-Forms:[[:space:]]+(.+)/i", $header, $m)) {
$pluralString = str_replace("n","\$n",$m[1]);
$pluralString = str_replace(" plural","\$plural",$pluralString);
} else {
$pluralString = "\$nplurals=1; \$plural=\$n==1?0:1;";
}
// Extract character set from header
if(preg_match("/Content-Type:(.+)charset=(.+)/i", $header, $m))
$charset = $m[2];
else
$charset = "";
// Extract language name from header
if(preg_match("/Language-Team:[[:space:]]+([^<\n]+)/i", $header, $m))
$language = $m[1];
else
$language = "Unknown";
$strings[0]["charset"] = $charset;
$strings[0]["language"] = $language;
$strings[0]["plural"] = $pluralString;
// Open data file for writing
$fp = @fopen($output, "wb") or die("Couldn't open file ({$output}).\n");
fwrite($fp, serialize($strings));
fclose($fp);
//set permissions on new PMO file
@chmod($output, octdec($GLOBALS['config']->file_mode));
 
// Return
return true;
}
 
 
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>i18n po compiler</title>
<link rel="stylesheet" type="text/css" href="tools.css" />
</head>
 
<body>
 
<h1>i18n po compiler</h1>
 
<p><?php
$files = parseDirectory($OUTPUTPATH, 'po');
foreach ($files as $file) {
if (!preg_match("/singapore\.(admin\.)?[\w]+\.po$/i", $file)) continue;
$outfile = preg_replace("/\.[^\.]+$/", ".pmo", $file);
if(parsePO($file, $outfile))
echo "Parsed $file to $outfile<br />";
else
echo "Could not parse $file<br />";
}
 
?>
</p>
 
<p>All operations complete. <a href="index.html">Return</a> to tools.</p>
 
</body>
</html>
/photogallery/tools/convertdb.php
0,0 → 1,278
<?php
 
//permissions bit flags
define("SG_GRP_READ", 1);
define("SG_GRP_EDIT", 2);
define("SG_GRP_ADD", 4);
define("SG_GRP_DELETE", 8);
define("SG_WLD_READ", 16);
define("SG_WLD_EDIT", 32);
define("SG_WLD_ADD", 64);
define("SG_WLD_DELETE", 128);
 
 
function getGallery($path)
{
$gal = new sgGallery('.');
 
$fp = @fopen($path."/metadata.csv","r");
if($fp) {
 
while($temp[] = fgetcsv($fp,2048));
fclose($fp);
@list(
$gal->filename,
,
$gal->owner,
$gal->groups,
$gal->permissions,
$gal->categories,
$gal->name,
$gal->artist,
$gal->email,
$gal->copyright,
$gal->desc,
$gal->summary,
$gal->date
) = $temp[1];
for($i=0;$i<count($temp)-3;$i++) {
$gal->images[$i] = new sgImage();
list(
$gal->images[$i]->filename,
$gal->images[$i]->thumbnail,
$gal->images[$i]->owner,
$gal->images[$i]->groups,
$gal->images[$i]->permissions,
$gal->images[$i]->categories,
$gal->images[$i]->name,
$gal->images[$i]->artist,
$gal->images[$i]->email,
$gal->images[$i]->copyright,
$gal->images[$i]->desc,
$gal->images[$i]->location,
$gal->images[$i]->date,
$gal->images[$i]->camera,
$gal->images[$i]->lens,
$gal->images[$i]->film,
$gal->images[$i]->darkroom,
$gal->images[$i]->digital
) = $temp[$i+2];
//don't get image size and type
}
} else {
//selected gallery does not exist or no metadata
return null;
}
return $gal;
}
 
function putGallery($gallery, $path) {
//backup data file
copy($path."/metadata.csv", $path."/metadata.bak");
$fp = fopen($path."/metadata.csv","w");
if(!$fp) return false;
$success = true;
 
$success &= (bool) fwrite($fp,"filename,thumbnail,owner,group(s),permissions,catergories,image name,artist name,artist email,copyright,image description,image location,date taken,camera info,lens info,film info,darkroom manipulation,digital manipulation");
$success &= (bool) fwrite($fp,"\n\"".
$gallery->filename."\",,".
$gallery->owner.",".
$gallery->groups.",".
$gallery->permissions.",".
$gallery->categories.',"'.
str_replace('"','""',$gallery->name).'","'.
str_replace('"','""',$gallery->artist).'","'.
str_replace('"','""',$gallery->email).'","'.
str_replace('"','""',$gallery->copyright).'","'.
str_replace('"','""',$gallery->desc).'","'.
str_replace('"','""',$gallery->summary).'","'.
str_replace('"','""',$gallery->date).'"'
);
for($i=0;$i<count($gallery->images);$i++)
$success &= (bool) fwrite($fp,"\n\"".
$gallery->images[$i]->filename."\",".
$gallery->images[$i]->thumbnail.",".
$gallery->images[$i]->owner.",".
$gallery->images[$i]->groups.",".
$gallery->images[$i]->permissions.",".
$gallery->images[$i]->categories.',"'.
str_replace('"','""',$gallery->images[$i]->name).'","'.
str_replace('"','""',$gallery->images[$i]->artist).'","'.
str_replace('"','""',$gallery->images[$i]->email).'","'.
str_replace('"','""',$gallery->images[$i]->copyright).'","'.
str_replace('"','""',$gallery->images[$i]->desc).'","'.
str_replace('"','""',$gallery->images[$i]->location).'","'.
str_replace('"','""',$gallery->images[$i]->date).'","'.
str_replace('"','""',$gallery->images[$i]->camera).'","'.
str_replace('"','""',$gallery->images[$i]->lens).'","'.
str_replace('"','""',$gallery->images[$i]->film).'","'.
str_replace('"','""',$gallery->images[$i]->darkroom).'","'.
str_replace('"','""',$gallery->images[$i]->digital).'"'
);
$success &= (bool) fclose($fp);
 
return $success;
}
 
function setPerms($obj) {
$obj->permissions = 0;
if(!empty($_POST["sgGrpRead"])) $obj->permissions |= SG_GRP_READ;
if(!empty($_POST["sgGrpEdit"])) $obj->permissions |= SG_GRP_EDIT;
if(!empty($_POST["sgGrpAdd"])) $obj->permissions |= SG_GRP_ADD;
if(!empty($_POST["sgGrpDelete"])) $obj->permissions |= SG_GRP_DELETE;
if(!empty($_POST["sgWldRead"])) $obj->permissions |= SG_WLD_READ;
if(!empty($_POST["sgWldEdit"])) $obj->permissions |= SG_WLD_EDIT;
if(!empty($_POST["sgWldAdd"])) $obj->permissions |= SG_WLD_ADD;
if(!empty($_POST["sgWldDelete"])) $obj->permissions |= SG_WLD_DELETE;
$obj->groups = $_REQUEST["sgGroups"];
$obj->owner = $_REQUEST["sgOwner"];
return $obj;
}
 
 
function convertDirectory ($path)
{
if (is_dir($path)) {
$gallery = getGallery($path);
echo "<ul><li>Checking $path<br />\n";
if($gallery) {
if($gallery->summary != "" && empty($_REQUEST["convertOverwrite"]))
echo "Did NOT overwrite non-empty summary in $path<br />\n";
else {
if($_REQUEST["convertType"]!='none')
$gallery->summary = $gallery->desc;
if($_REQUEST["convertType"]=='move')
$gallery->desc = "";
}
 
$gallery = setPerms($gallery);
for($i=0; $i<count($gallery->images); $i++)
$gallery->images[$i] = setPerms($gallery->images[$i]);
if(putGallery($gallery,$path))
echo "Successfully converted $path<br />\n";
else
echo "Problem saving data file for $path<br />\n";
} else
echo "Skipping $path<br />\n";
$d = dir($path);
while (($file = $d->read()) !== false) {
if ($file == '.' || $file == '..') continue;
$path = $d->path."/".$file;
if (is_dir($path)) {
convertDirectory($path);
}
}
echo "</li></ul>\n";
}
}
 
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>database converter</title>
<link rel="stylesheet" type="text/css" href="tools.css" />
</head>
 
<body>
 
<h1>database converter</h1>
 
<?php
if(isset($_REQUEST["convertType"])) {
 
include "../includes/config.class.php";
include "../includes/gallery.class.php";
include "../includes/image.class.php";
$config = new sgConfig("../singapore.ini");
$config->base_path = "../";
//echo "<ul>\n";
convertDirectory($config->base_path.$config->pathto_galleries);
//echo "</ul>\n";
echo "<p>All operations complete.</p>\n";
 
} else { ?>
<p>This will convert all your metadata files from singapore 0.9.6, 0.9.7, 0.9.8 or 0.9.9 to 0.9.10.</p>
 
<form method="post" action="<?php echo $_SERVER["PHP_SELF"]; ?>">
<h3>summary field</h3>
<p>There is a new gallery summary field that is displayed instead of the
description in the parent gallery. You can choose to either copy or move the
old description field to the summary field or leave both untouched:</p>
 
<p><input type="radio" class="radio" name="convertType" value="copy" checked="true" /> Copy<br />
<input type="radio" class="radio" name="convertType" value="move" /> Move<br />
<input type="radio" class="radio" name="convertType" value="none" /> Neither<br />
 
<p>By default only empty summary fields will be written to. Check this option to
allow the summary field to be overwritten <input type="checkbox" class="checkbox" name="convertOverwrite" /></p>
 
<h3>permissions</h3>
 
<p>This version introduces multiple authorised users and image &amp; gallery
permissions. Please choose the default permissions that you would like all
objects to be set to. The default permissions selected below are recommended as
they will make all images &amp; galleries readable by everyone but only
modifiable by administrators. See the readme for more information on the
permissions model used by singapore.</p>
<table>
<tr>
<td>Owner</td>
<td><input type="text" name="sgOwner" value="__nobody__" /></td>
</tr>
<tr>
<td>Groups</td>
<td><input type="text" name="sgGroups" value="" /></td>
</tr>
<tr>
<td>Group permissions</td>
<td><div class="inputbox">
<input type="checkbox" class="checkbox" name="sgGrpRead" checked="true"/> Read
<input type="checkbox" class="checkbox" name="sgGrpEdit" /> Edit
<input type="checkbox" class="checkbox" name="sgGrpAdd" /> Add
<input type="checkbox" class="checkbox" name="sgGrpDelete" /> Delete
</div></td>
</tr>
<tr>
<td>World permissions</td>
<td><div class="inputbox">
<input type="checkbox" class="checkbox" name="sgWldRead" checked="true"/> Read
<input type="checkbox" class="checkbox" name="sgWldEdit" /> Edit
<input type="checkbox" class="checkbox" name="sgWldAdd" /> Add
<input type="checkbox" class="checkbox" name="sgWldDelete" /> Delete
</div></td>
</tr>
</table>
 
 
<p>Please note that while the script will create backups of your metadata files
it is highly recommended that you create your own backups for added security.</p>
 
<input type="submit" class="button" value="Go" /></p>
</form>
<?php } ?>
 
<p><a href="index.html">Return</a> to tools.</p>
 
</body>
</html>
/photogallery/tools/extract.php
0,0 → 1,133
<?php
 
/**
* This file searches for strings in all project files matching the filter and
* creates two PO template files (singapore.pot and singapore.admin.pot)
*
* @author Joel Sjögren <joel dot sjogren at nonea dot se>
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003-2005 Tamlyn Rhodes
* @version $Id: extract.php,v 1.14 2006/06/24 22:36:15 tamlyn Exp $
*/
 
// Programs to call (insert path to them if necessary)
$GETTEXT_EXTRACT = "xgettext";
$BASEPATH = realpath("..")."/";
 
 
//require config class
require_once $BASEPATH."includes/config.class.php";
 
//get config object
$config = sgConfig::getInstance();
$config->loadConfig($BASEPATH."singapore.ini");
 
$OUTPUTPATH = $BASEPATH.$config->pathto_locale;
$standardPot = $OUTPUTPATH."singapore.pot";
$adminPot = $OUTPUTPATH."singapore.admin.pot";
 
 
/**
* Parses a directory and returns full path to all the files
* matching the filter (file name suffix)
*
* @param string $dir full directory name (must end with /)
* @param string $filter file name suffixes separated by | (optional, default don't filter)
* @return array an array with all files
**/
function parseDirectory ($dir, $filter = "php|html|tpl|inc")
{
$ret = array();
if (is_dir($dir)) {
$d = dir($dir);
while (($file = $d->read()) !== false) {
if ($file == '.' || $file == '..') continue;
$fullfile = $d->path . $file;
if (is_dir($fullfile)) $ret = array_merge($ret,parseDirectory($fullfile."/"));
else if (!$filter || preg_match("/\.({$filter})$/i", $file)) $ret[] = $fullfile;
}
}
return $ret;
}
 
 
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>i18n string extractor</title>
<link rel="stylesheet" type="text/css" href="tools.css" />
</head>
 
<body>
 
<h1>i18n string extractor</h1>
 
<p><?php
// Create tempfile
$temp = $OUTPUTPATH."/".'~tempfile';
$fp = fopen($temp, 'wb') or die("Couldn't open tempfile {$temp} for writing.\n");
// Get all files matching pattern in current template
$files = parseDirectory("../".$config->pathto_templates.$config->default_template.'/');
$files[] = "../includes/image.class.php";
$files[] = "../includes/item.class.php";
$files[] = "../includes/gallery.class.php";
$files[] = "../includes/singapore.class.php";
$files[] = "../includes/user.class.php";
fwrite($fp, implode("\n", $files));
// Close tempfile
fclose($fp);
// Call gettext
$res = shell_exec("{$GETTEXT_EXTRACT} --debug --keyword=_g --keyword=_ng:1,2 --keyword=__g -C -F --output=\"" . $standardPot . "\" --files-from=\"" . $temp . "\"");
if (trim($res)) die("Something seemed to go wrong with gettext:\n" . $res . "\n");
else echo "Standard strings extracted $standardPot<br />";
// Remove tempfile
unlink($temp);
//set permissions on new POT file
@chmod($standardPot, octdec($config->file_mode));
///////admin///////////
 
// Create tempfile
$temp = $OUTPUTPATH."/".'~tempfile';
$fp = fopen($temp, 'w') or die("Couldn't open tempfile {$temp} for writing.\n");
// Get all files matching pattern in current template
$files = parseDirectory("../".$config->pathto_templates.$config->admin_template_name.'/');
$files[] = "../includes/admin.class.php";
$files[] = "../admin.php";
fwrite($fp, implode("\n", $files));
// Close tempfile
fclose($fp);
// Call gettext
$res = shell_exec("{$GETTEXT_EXTRACT} --debug --keyword=_g --keyword=_ng:1,2 -C -F -x \"" . $standardPot . "\" --output=\"" . $adminPot . "\" --files-from=\"" . $temp . "\"");
if (trim($res)) die("Something seemed to go wrong with gettext:\n" . $res . "\n");
else echo "Admin strings extracted to $adminPot<br />";
// Remove tempfile
unlink($temp);
 
//set permissions on new POT file
@chmod($adminPot, octdec($config->file_mode));
?>
</p>
 
<p>You may now <a href="merge.php">merge</a> the strings into all previously
translated PO files.</p>
 
</body>
</html>
/photogallery/tools/generate.php
0,0 → 1,68
<?php
 
/**
* Use this script to batch generate all main and preview thumbnails for all
* galleries. Galleries which contain sub-galleries are skipped as are hidden
* galleries.
*
* Currently this is a bit of a hack. Hopefully a later version of the script
* will be built more robustly using the singapore class to greater advantage.
*
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2004-2005 Tamlyn Rhodes
* @version 0.1
*/
 
//relative path to the singapore base installation
$basePath = '../';
 
//remove the built in time limit
set_time_limit(0);
 
// require main class
require_once $basePath."includes/singapore.class.php";
 
//create singapore object
$sg = new Singapore($basePath);
 
function showAllThumbnails(&$sg, &$gal)
{
echo "<li>Entering <code>".$gal->name()."</code></li>\n";
echo "<ul>\n";
echo "<li>".$gal->thumbnailHTML()."</li>\n";
if($gal->isGallery()) {
foreach($gal->galleries as $subgal)
showAllThumbnails($sg, $sg->io->getGallery($subgal->id, $gal));
} else
foreach($gal->images as $img)
echo "<li>".$img->thumbnailHTML().$img->thumbnailHTML("","preview")."</li>\n";
 
echo "</ul>\n";
}
 
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>batch thumbnail generator</title>
<link rel="stylesheet" type="text/css" href="tools.css" />
</head>
 
<body>
 
<h1>Generating thumbnails</h1>
 
<?php
//start recursive thumbnail generation
showAllThumbnails($sg, $sg->gallery);
?>
 
<p>All done! <a href="index.html">Return</a> to tools.</p>
 
</body>
</html>
/photogallery/tools/index.html
0,0 → 1,58
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>singapore tools</title>
<link rel="stylesheet" type="text/css" href="tools.css" />
</head>
 
<body>
 
<h1>singapore tools</h1>
 
<p>This is a collection of tools for use with the singapore image gallery. They
must be located in a child directory of the main singapore directory
(<code>tools/</code> by default). Since they are PHP scripts they must be run
on a PHP enabled web server</p>
 
<h1>language tools</h1>
 
<p>These tools are to aid translators. They require GNU Gettext to be available
on the host system but do not require the Gettext PHP extension. Please
see the <a href="../docs/Translation.html">translation</a> readme for more
information.</p>
 
<ol>
<li><a href="extract.php">Extractor</a> - for developers. Extracts
translatable strings from singapore files and current template and creates
PO template files. Unless you have edited text in the sources you do not need
to execute this.</li>
<li><a href="merge.php">Merger</a> - for translators. Merges new strings from
the PO templates with all currently available PO files.</li>
<li><a href="compile.php">Compiler</a> - for translators. Compiles all
currently available PO files into PHP serialized objects for use with singapore.</li>
<li><a href="localecache.php">Cache updater</a> - for anyone. Caches the names
of all installed languages for use with the language flipper.</li>
</ol>
 
<h1>misc tools</h1>
 
<ul>
<!--<li><a href="convertdb.php">Database converter</a> - copies or moves the
gallery description field of pre v0.9.10 to the summary field of v0.9.10.</li>-->
<li><a href="generate.php">Batch thumbnail generator</a> - use to generate all
album and preview thumbnails for all galleries in one go. Particularly useful
on slow servers to run overnight.</li>
<li><a href="cleanup.php">Cleanup script</a> - use this script to make all
server generated content world readable allowing you to delete it. Since this
script does not actually delete anything it is safe to be run by anyone.</li>
<li><a href="mod_rewrite.htaccess">mod_rewrite</a> - The .htaccess file you
need for use with Apache mod_rewrite. See readme for more info.</li>
</ul>
 
 
<p><a href="../">Return</a> to singapore.</p>
 
</body>
</html>
/photogallery/tools/localecache.php
0,0 → 1,98
<?php
/**
* This file merges the two PO template files (singapore.pot and singapore.admin.pot)
* with all existing language files (singapore.LANG.po)
*
* @author Joel Sjögren <joel dot sjogren at nonea dot se>
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003, 2004 Tamlyn Rhodes
* @version $Id: localecache.php,v 1.5 2005/12/15 17:18:47 tamlyn Exp $
*/
 
//require config class
$BASEPATH = "../";
require_once $BASEPATH."includes/config.class.php";
require_once $BASEPATH."includes/translator.class.php";
 
//get config object
$sgConfig = sgConfig::getInstance();
$sgConfig->loadConfig($BASEPATH."singapore.ini");
$sgConfig->base_path = $BASEPATH;
 
$OUTPUTPATH = $sgConfig->base_path.$sgConfig->pathto_locale;
$OUTPUTFILE = $sgConfig->base_path.$sgConfig->pathto_data_dir."languages.cache";
/**
* Parses a directory and returns full path to all the files
* matching the filter (file name suffix)
*
* @param string $dir full directory name (must end with /)
* @param string $filter file name suffixes separated by | (optional, default don't filter)
* @return array an array with all files
**/
function parseDirectory ($dir, $filter = 'php|html|tpl|inc')
{
$ret = array();
if (is_dir($dir)) {
$d = dir($dir);
while (($file = $d->read()) !== false) {
if ($file == '.' || $file == '..') continue;
$fullfile = $d->path . $file;
if (is_dir($fullfile)) $ret = array_merge($ret,parseDirectory($fullfile."/"));
else if (!$filter || preg_match("/\.({$filter})$/i", $file)) $ret[] = $fullfile;
}
}
return $ret;
}
 
function saveCache($availableLanguages, $output)
{
// Open data file for writing
$fp = @fopen($output, "wb") or die("Couldn't open file ({$output}).\n");
fwrite($fp, serialize($availableLanguages));
return fclose($fp);
}
 
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>language cache updater</title>
<link rel="stylesheet" type="text/css" href="tools.css" />
</head>
 
<body>
 
<h1>language cache updater</h1>
 
<p><?php
$files = parseDirectory($OUTPUTPATH, 'pmo');
$availableLanguages = array();
foreach ($files as $file) {
if (!preg_match("/singapore\.([\w]+)\.pmo$/i", $file, $matches)) continue;
$i18n = Translator::getInstance($matches[1]);
$i18n->readLanguageFile($sgConfig->base_path.$sgConfig->pathto_locale."singapore.".$i18n->language.".pmo");
$availableLanguages[$matches[1]] = $i18n->languageStrings[0]['language'];
echo "Added $matches[1] => ".$i18n->languageStrings[0]['language']." to available languages.<br />\n";
}
//add english which has no translation files
$availableLanguages["en"] = "English";
ksort($availableLanguages);
if(saveCache($availableLanguages, $OUTPUTFILE))
echo "Cache file saved as ".$OUTPUTFILE;
else
echo "Could not save cache file as ".$OUTPUTFILE;
?>
</p>
 
<p>All operations complete. <a href="index.html">Return</a> to tools.</p>
 
</body>
</html>
/photogallery/tools/merge.php
0,0 → 1,115
<?php
 
/**
* This file merges the two PO template files (singapore.pot and singapore.admin.pot)
* with all existing language files (singapore.LANG.po)
*
* @author Joel Sjögren <joel dot sjogren at nonea dot se>
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003-2005 Tamlyn Rhodes
* @version $Id: merge.php,v 1.8 2006/05/08 09:40:02 thepavian Exp $
*/
 
// Programs to call (insert path to them if necessary)
$GETTEXT_MERGE = "msgmerge";
$BASEPATH = realpath("..")."/";
 
//require config class
require_once $BASEPATH."includes/config.class.php";
 
//get config object
$config = sgConfig::getInstance();
$config->loadConfig($BASEPATH."singapore.ini");
 
$OUTPUTPATH = $BASEPATH.$config->pathto_locale;
$standardPot = $OUTPUTPATH."singapore.pot";
$adminPot = $OUTPUTPATH."singapore.admin.pot";
$createbackups = true;
 
/**
* Parses a directory and returns full path to all the files
* matching the filter (file name suffix)
*
* @param string $dir full directory name (must end with /)
* @param string $filter file name suffixes separated by | (optional, default don't filter)
* @return array an array with all files
**/
function parseDirectory ($dir, $filter = 'php|html|tpl|inc')
{
$ret = array();
if (is_dir($dir)) {
$d = dir($dir);
while (($file = $d->read()) !== false) {
if ($file == '.' || $file == '..') continue;
$fullfile = $d->path . $file;
if (is_dir($fullfile)) $ret = array_merge($ret,parseDirectory($fullfile."/"));
else if (!$filter || preg_match("/\.({$filter})$/i", $file)) $ret[] = $fullfile;
}
}
return $ret;
}
 
 
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>i18n string merger</title>
<link rel="stylesheet" type="text/css" href="tools.css" />
</head>
 
<body>
 
<h1>i18n string merger</h1>
 
<p><?php
$files = parseDirectory($OUTPUTPATH, 'po');
foreach ($files as $file) {
if (!preg_match("/singapore\.[\w]+\.po$/i", $file)) continue;
$backup = $file . '.bak';
if (file_exists($backup)) @unlink($backup);
@rename($file, $backup);
$res = shell_exec("{$GETTEXT_MERGE} --strict \"{$backup}\" \"" . $standardPot . "\" > \"{$file}\"");
if (trim($res)) echo "Something seemed to go wrong with msgmerge:\n" . $res . "\n";
else echo "$standardPot merged with $file<br />";
// Remove backup?
if (!@$createbackups) @unlink($backup);
//set permissions on new POT file
@chmod($standardPot, octdec($config->file_mode));
}
 
///////admin///////////
 
$files = parseDirectory($OUTPUTPATH, 'po');
foreach ($files as $file) {
if (!preg_match("/singapore\.admin\.[\w]+\.po$/i", $file)) continue;
$backup = $file . '.bak';
if (file_exists($backup)) @unlink($backup);
@rename($file, $backup);
$res = shell_exec("{$GETTEXT_MERGE} --strict \"{$backup}\" \"" . $adminPot . "\" > \"{$file}\"");
if (trim($res)) echo "Something seemed to go wrong with msgmerge:\n" . $res . "\n";
else echo "$adminPot merged with $file<br />";
// Remove backup?
if (!@$createbackups) @unlink($backup);
//set permissions on new POT file
@chmod($adminPot, octdec($config->file_mode));
}
 
?>
</p>
 
<p>Once you have translated the updated PO files you may
<a href="compile.php">compile</a> them into PHP serialized objects for use with
singapore.</p>
 
</body>
</html>
/photogallery/tools/mod_rewrite.htaccess
0,0 → 1,33
# WHAT YOU NEED TO EDIT
#
# There are just two things you need to edit to make this file work on your
# installation. On each of the two lines below starting 'RewriteRule' about
# half way along the line there is a '/singapore/'. Change this to the full
# path to your installation (e.g. the bit after the .com, .org or whatever)
# then rename this file to .htaccess and put it in the singapore root
# directory (the one containing thumb.php). Finally don't forget to turn on
# use_mod_rewrite and update the base_path in singapore.ini. Voila!
 
 
Options +FollowSymlinks
RewriteEngine On
 
# rewrite galleries
# url must end in / and gallery names must not contain commas (,)
# example: /singapore/gallery/subgallery,20/
# becomes: /singapore/index.php?gallery=gallery/subgallery&startat=20
RewriteRule ^([^,]+)(,([0-9]+))?/$ /singapore/index.php?gallery=$1&startat=$3&%{QUERY_STRING} [ne]
 
# rewrite images
# do not rewrite requests to files and directories that really exist
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
 
# example: /singapore/gallery/subgallery/myphoto.jpeg
# becomes: /singapore/index.php?gallery=gallery/subgallery&image=myphoto.jpeg
RewriteRule ^((.*)/)?([^/]+\.(jpeg|jpg|jpe|png|gif|bmp|tif|tiff))$ /singapore/index.php?gallery=$2&image=$3&%{QUERY_STRING} [ne,nc]
 
# rewrite feed.xml to the rss template
# example: /singapore/gallery/feed.xml
# becomes: /singapore/index.php?gallery=gallery&template=rss
RewriteRule ^((.*)/)?feed.xml$ /singapore/index.php?gallery=$2&template=rss&%{QUERY_STRING} [ne]
/photogallery/tools/tools.css
0,0 → 1,82
body {
margin: 1em;
font: small sans-serif;
color: #000;
background-color: #fff;
}
 
p, td, th, li, dd, dt {
font: small sans-serif;
}
 
h1, h2, h3, h4{
color: #f60;
}
 
h1, h2 {
font-size: medium;
border-bottom: 1px solid #ccc;
letter-spacing: 0.3em;
text-transform: uppercase;
}
 
code, pre {
color: #444;
}
 
p, td, th, li, dt, h3, h4, pre {
margin-left: 2em;
}
 
dd {
margin-left: 3em;
}
 
dt {
margin-top: 0.5em;
}
 
a:link {
color: #09f;
text-decoration: underline;
}
 
a:visited {
color: #05a;
text-decoration: underline;
}
 
a:hover {
text-decoration: none;
}
 
input, textarea, select, .inputbox {
border: 1px solid #f60;
color: #000;
background-color: #fff;
}
 
input.radio {
border: none;
background-color: #fff;
}
 
input.button {
font-weight: bold;
border: 1px outset #fff;
color: #fff;
background-color: #f60;
}
 
ul.things > li {
margin-top: 0.75em;
}
 
.note {
color: #d00;
}
 
.boxed, .note {
border: 1px dashed #ccc;
padding: 0.5em;
}
/photogallery/install/index.html
0,0 → 1,27
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>singapore setup</title>
<link rel="stylesheet" type="text/css" href="../docs/docstyle.css" />
</head>
 
<body>
 
<h1>singapore Setup</h1>
 
<p>Welcome to the singapore setup process. This should take no more than a minute.</p>
 
<ul>
<li><a href="install.php">Install singapore</a></li>
<li><a href="uninstall.php">Uninstall singapore</a></li>
<!--<li><a href="migrate.php">Migrate database information</a></li>-->
<li><a href="../">Return to singapore</a></li>
</ul>
 
<p>Once you have completed the setup process you must delete or protect this
<code>install/</code> directory to prevent unauthorised access.</p>
 
</body>
</html>
/photogallery/install/install.inc.php
0,0 → 1,258
<?php
 
/**
* Contains functions used during the install process.
*
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003-2005 Tamlyn Rhodes
* @version $Id: install.inc.php,v 1.4 2006/01/22 03:25:37 tamlyn Exp $
*/
 
/**
* Test server configuration.
* @return bool true if no errors occurred; false otherwise
*/
function testServer()
{
setupHeader("Testing PHP version");
setupMessage("PHP version is ".phpversion());
$bits = explode(".",phpversion());
if(strcmp($bits[0],"4")<0 || strcmp($bits[0],"4")==0 && strcmp($bits[1],"1")<0)
return setupError("singapore requires PHP 4.1.0 or higher ");
$success = true;
setupHeader("Testing PHP configuration");
//setupMessage("If any of these tests fail, you may be able to change the configuration ".
// "directive (specified in brackets) either in php.ini or by adding ".
// "<code>ini_set(\"<b>directive_name</b>, 1)</code> to <code>includes/header.php</code>");
 
if(!ini_get("safe_mode")) setupMessage("Safe mode disabled");
else $success &= setupError("PHP is running in 'safe mode' (<code>safe_mode</code>). Singapore may still function correctly but safe mode operation is not supported");
$session_save_path = ini_get("session.save_path");
if(!empty($session_save_path) && is_writable($session_save_path) || ini_get("session.save_handler")!="files") setupMessage("Session save path seems to be correctly specified");
else $success &= setupError("Session save path does not exist or is not writable (<code>session.save_path</code>). Singapore will function but you may not be able to use the admin interface");
 
if(ini_get("session.use_trans_sid")) setupMessage("Transparent session id support enabled");
else setupMessage("Transparent session id support disabled (<code>use_trans_sid</code>). Singapore will function but will <b>require</b> cookies for the admin interface to function");
 
if(ini_get("file_uploads")) setupMessage("File uploading enabled");
else $success &= setupError("File uploading disabled (<code>file_uploads</code>). Singapore will function but you will not be able to upload images via the admin interface");
 
$upload_tmp_dir = ini_get("upload_tmp_dir");
if(empty($upload_tmp_dir) || is_writable($upload_tmp_dir)) setupMessage("Upload temp directory seems to be correctly specified");
else $success &= setupError("Upload directory directory does not exist or is not writable (<code>upload_tmp_dir</code>). Singapore will function but you may not be able to upload images via the admin interface");
//setupMessage("Maximum upload size is ".floor(ini_get("upload_max_filesize")/1024)."KB. You will not be able to upload files larger than this via the admin interface");
if(ini_get("allow_url_fopen")) setupMessage("Remote file handling enabled");
else $success &= setupError("Remote file handling disabled (<code>allow_url_fopen</code>). Singapore will function but you will not be able to generate thumbnails for remotely hosted files");
setupHeader("Testing for config file");
if(file_exists($GLOBALS['basePath']."singapore.ini")) setupMessage("Config file found");
else $success &= setupError("Config file not found - singapore.ini must be located in the root singapore directory");
setupHeader("Testing for GD");
//get phpinfo data
ob_start();
phpinfo(8);
$phpinfo = ob_get_contents();
ob_end_clean();
//find gd version
$phpinfo = strip_tags($phpinfo);
$phpinfo = stristr($phpinfo,"gd version");
$phpinfo = stristr($phpinfo,"version");
if(!$phpinfo) $success &= setupError("GD not found. You may be able to use ImageMagick instead");
else {
//extract text version and number version
$gd_version_text = substr($phpinfo,0,strpos($phpinfo,"\n"));
$gd_version_number = substr($gd_version_text,0,strpos($gd_version_text,"."));
$gd_version_number = substr($gd_version_number, strlen($gd_version_number)-1);
setupMessage("Found GD: $gd_version_text");
if($gd_version_number=="1") setupMessage("Please change the <code>thumbnail_software</code> option in singapore.ini to \"gd1\". Note: GD1 produces very poor quality thumbnails so please use GD2 or ImageMagick if available");
}
setupHeader("Testing for ImageMagick");
$foundIM = exec("mogrify");
$whereIM = exec("whereis mogrify");
if($foundIM) {
if($whereIM) setupMessage("Found ImageMagick at $whereIM");
else setupMessage("Found ImageMagick");
setupMessage("To take advantage of ImageMagick change the <code>thumbnail_software</code> option in singapore.ini to \"im\"");
} else setupMessage("ImageMagick not found but that doesn't mean it's not there. If it really is not available you may be able to install it yourself (even without shell access to the server)");
return $success;
}
 
 
/**
* Creates cache and logs directories required to run singapore and ensures
* all required directories are writeable.
* @return bool true if no errors occurred; false otherwise
*/
function createDirectories($config)
{
$success = true;
setupHeader("Creating directories");
if(is_writable($config->base_path.$config->pathto_data_dir)) {
setupMessage("Data directory is writable");
if(file_exists($config->base_path.$config->pathto_cache))
if(is_writable($config->base_path.$config->pathto_cache))
setupMessage("Cache directory already exists at ".$config->base_path.$config->pathto_cache." and is writable");
else
$success = setupError("Cache directory already exists at ".$config->base_path.$config->pathto_cache." but is not writable. Please CHMOD to 777");
else
if(mkdir($config->base_path.$config->pathto_cache, $config->directory_mode)) {
@chmod($config->base_path.$config->pathto_cache, $config->directory_mode);
setupMessage("Created cache directory at ".$config->base_path.$config->pathto_cache);
} else
$success = setupError("Could not create cache directory at ".$config->base_path.$config->pathto_cache);
if($config->track_views)
if(file_exists($config->base_path.$config->pathto_logs))
if(is_writable($config->base_path.$config->pathto_logs))
setupMessage("Logs directory already exists at ".$config->base_path.$config->pathto_logs." and is writable");
else
$success = setupError("Logs directory already exists at ".$config->base_path.$config->pathto_logs." but is not writable. Please CHMOD to 777");
else
if(mkdir($config->base_path.$config->pathto_logs, $config->directory_mode)) {
@chmod($config->base_path.$config->pathto_logs, $config->directory_mode);
setupMessage("Created logs directory at ".$config->base_path.$config->pathto_logs);
} else
$success = setupError("Could not create logs directory at ".$config->base_path.$config->pathto_logs);
else
setupMessage("View logging disabled. Logs directory not created");
}
else
$success = setupError("Data directory (".$config->base_path.$config->pathto_data_dir.") is not writable. Please CHMOD to 777");
 
return $success;
}
 
/**
* Creates the tables and inserts the default users.
* @param sgIO_sql pointer to a singapore SQL backend object
*/
function sqlCreateTables(&$io) {
$success = true;
setupHeader("Creating tables");
if(@$io->query("SELECT * FROM ".$io->config->sql_prefix."galleries"))
setupMessage("'".$io->config->sql_prefix."galleries' table already exists - skipped");
elseif($io->query("CREATE TABLE ".$io->config->sql_prefix."galleries (".
"id varchar(250) NOT NULL, ".
"lang varchar(16) NOT NULL DEFAULT '', ".
"filename varchar(200), ".
"owner varchar(32), ".
"groups varchar(64), ".
"permissions int UNSIGNED, ".
"categories varchar(255), ".
"name varchar(255), ".
"artist varchar(255), ".
"email varchar(255), ".
"copyright varchar(255), ".
"description text, ".
"summary text, ".
"date varchar(255),".
"hits smallint UNSIGNED,".
"lasthit int UNSIGNED,".
"PRIMARY KEY (id, lang)".
")")) setupMessage("'".$io->config->sql_prefix."galleries' table created");
else
$success = setupError("Unable to create '".$io->config->sql_prefix."galleries' table:".$io->error());
if(@$io->query("SELECT * FROM ".$io->config->sql_prefix."images"))
setupMessage("'".$io->config->sql_prefix."images' table already exists - skipped");
elseif($io->query("CREATE TABLE ".$io->config->sql_prefix."images (".
"galleryid varchar(250) NOT NULL, ".
"filename varchar(200) NOT NULL, ".
"lang varchar(16) NOT NULL DEFAULT '', ".
"thumbnail varchar(255), ".
"owner varchar(32), ".
"groups varchar(64), ".
"permissions int, ".
"categories varchar(64), ".
"name varchar(255), ".
"artist varchar(255), ".
"email varchar(255), ".
"copyright varchar(255), ".
"description text, ".
"width smallint UNSIGNED, ".
"height smallint UNSIGNED, ".
"type tinyint UNSIGNED, ".
"location varchar(255), ".
"date varchar(255), ".
"camera varchar(255), ".
"lens varchar(255), ".
"film varchar(255), ".
"darkroom text, ".
"digital text, ".
"hits smallint UNSIGNED,".
"lasthit int UNSIGNED,".
"PRIMARY KEY (galleryid, filename, lang)".
")")) setupMessage("'".$io->config->sql_prefix."images' table created");
else
$success = setupError("Unable to create '".$io->config->sql_prefix."images' table:".$io->error());
if(@$io->query("SELECT * FROM ".$io->config->sql_prefix."users"))
setupMessage("'".$io->config->sql_prefix."users' table already exists - skipped");
elseif($io->query("CREATE TABLE ".$io->config->sql_prefix."users (".
"username varchar(32) NOT NULL, ".
"userpass char(32) NOT NULL, ".
"permissions int UNSIGNED, ".
"groups varchar(64), ".
"email varchar(255), ".
"fullname varchar(255), ".
"description varchar(255), ".
"stats varchar(255), ".
"PRIMARY KEY (username)".
")")) {
setupMessage("'".$io->config->sql_prefix."users' table created");
if($io->query("INSERT INTO ".$io->config->sql_prefix."users VALUES".
'("admin", "5f4dcc3b5aa765d61d8327deb882cf99", 1024, "", "", "Administrator", "Default administrator account", "")') &&
$io->query("INSERT INTO ".$io->config->sql_prefix."users VALUES".
'("guest", "5f4dcc3b5aa765d61d8327deb882cf99", 0, "", "", "Guest", "Restricted use account for guests who do not have a user account", "")'))
setupMessage("Inserted default users into '".$io->config->sql_prefix."users' table");
else
$success = setupError("Unable to insert default users into '".$io->config->sql_prefix."users' table:".$io->error());
} else
$success = setupError("Unable to create '".$io->config->sql_prefix."users' table:".$io->error());
return $success;
}
 
 
//output functions
function setupHeader($var)
{
echo "\n</p>\n\n<h2>{$var}</h2>\n\n<p>\n";
}
 
/**
* Print an information message. Always returns true.
* @return true
*/
function setupMessage($var)
{
echo "{$var}.<br />\n";
return true;
}
 
/**
* Print an error message. Always returns false.
* @return false
*/
function setupError($var)
{
echo "<span class=\"error\">{$var}</span>.<br />\n";
return false;
}
 
?>
/photogallery/install/install.php
0,0 → 1,151
<?php
 
/**
* Performs necessary actions to install singapore.
*
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003, 2004 Tamlyn Rhodes
* @version $Id: install.php,v 1.6 2006/02/04 02:12:12 tamlyn Exp $
*/
 
//path to singapore root
$basePath = "../";
 
require_once "install.inc.php";
require_once $basePath."includes/config.class.php";
 
//determine current step in setup process
$setupStep = isset($_REQUEST["step"]) ? $_REQUEST["step"] : "test";
 
if($setupStep=="phpinfo") {
phpinfo();
exit;
}
 
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>singapore setup</title>
<link rel="stylesheet" type="text/css" href="../docs/docstyle.css" />
</head>
 
<body>
 
<?php
//if file is parsed by php then this block will never be executed
if(false) {
?>
</p>
 
<h1>Oh dear...</h1>
 
<p>PHP is not installed or is not configured correctly. See the
<a href="http://www.php.net/manual/">PHP manual</a> for more information.
 
<?php
} //end php test
 
switch($setupStep) {
case "test" :
setupHeader("Step 1 of 2: Test Server");
setupMessage("Attempting to find out if your server is capable of running singapore");
setupMessage("No changes are made at this time");
if(testServer()) {
setupHeader("OK");
setupMessage("All tests completed successfully");
} else {
setupHeader("Oops!");
setupError("One or more problems were encountered. You may want to fix them and <a href=\"install.php?step=test\">retry this step</a>");
}
echo '<br /><a href="index.html">&lt;&lt; Previous: welcome</a>';
echo ' | <a href="install.php?step=phpinfo">View PHP configuration</a>';
echo ' | <a href="install.php?step=database">Next: setup database &gt;&gt;</a>';
//echo ' | <a href="index.html">Finish</a>';
//echo ' | <a href="install.php?step=directories">Next: create directories &gt;&gt;</a>';
break;
case "directories" :
setupHeader("Step 2 of 3: Create Directories");
setupMessage("Setup will now create the directories necessary to store thumbnails and logs");
//create config object
$config = new sgConfig($basePath."singapore.ini");
$config->pathto_logs = $config->pathto_data_dir."logs/";
$config->pathto_cache = $config->pathto_data_dir."cache/";
$config->base_path = $basePath;
if(createDirectories($config)) {
setupHeader("OK");
setupMessage("This step completed successfully");
} else {
setupHeader("Oops!");
setupError('There was a problem. Please fix it and <a href="install.php?step=directories">retry this step</a>');
}
echo '<br /><a href="install.php?step=test">&lt;&lt; Previous: test server</a>';
echo ' | <a href="install.php?step=database">Next: setup database &gt;&gt;</a>';
break;
case "database" :
setupHeader("Step 2 of 2: Setup Database");
//create config object
$config =& sgConfig::getInstance();
$config->loadConfig($basePath."singapore.ini");
$config->base_path = $basePath;
switch($config->io_handler) {
case "csv" :
setupMessage("The default CSV file database does not require any further setting up");
setupHeader("OK");
setupMessage("This step completed successfully");
break;
case "mysql" :
include_once $basePath."includes/io_mysql.class.php";
$config->loadConfig($basePath."secret.ini.php");
setupMessage("Setup will now create the tables necessary to run singapore on a MySQL database");
setupHeader("Connecting to database");
$io = new sgIO_mysql();
if(!$io) setupError("Error connecting to database. Please ensure database settings are correct");
if(sqlCreateTables($io)) {
setupHeader("OK");
setupMessage("This step completed successfully");
} else {
setupHeader("Oops!");
setupError('There was a problem. Please fix it and <a href="install.php?step=database">retry this step</a>');
}
break;
case "sqlite" :
include_once $basePath."includes/io_sqlite.class.php";
setupMessage("Setup will now create the database and tables necessary to run singapore on SQLite");
setupHeader("Opening database file");
$io = new sgIO_sqlite();
if(!$io) {
setupError("Error connecting to database. Please ensure database settings are correct");
break;
} else setupMessage("Success");
if(sqlCreateTables($io)) {
setupHeader("OK");
setupMessage("This step completed successfully");
} else {
setupHeader("Oops!");
setupError('There was a problem. Please fix it and <a href="install.php?step=database">retry this step</a>');
}
break;
default :
setupError("Unrecognised io_handler.");
}
setupMessage("Don't forget to delete or protect this <code>install</code> directory to prevent unauthorised access");
echo '<br /><a href="install.php?step=test">&lt;&lt; Previous: test server</a>';
//echo '<br /><a href="install.php?step=directories">&lt;&lt; Previous: create directories</a>';
echo ' | <a href="index.html">Finish</a>';
break;
}
?>
 
</body>
</html>
/photogallery/install/migrate.inc.php
0,0 → 1,95
<?php
 
/**
* Contains functions used during the database migration process.
*
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003, 2004 Tamlyn Rhodes
* @version $Id: migrate.inc.php,v 1.2 2004/12/15 17:04:56 tamlyn Exp $
*/
 
 
function setPerms($obj) {
$obj->permissions = 0;
if(!empty($_POST["sgGrpRead"])) $obj->permissions |= SG_GRP_READ;
if(!empty($_POST["sgGrpEdit"])) $obj->permissions |= SG_GRP_EDIT;
if(!empty($_POST["sgGrpAdd"])) $obj->permissions |= SG_GRP_ADD;
if(!empty($_POST["sgGrpDelete"])) $obj->permissions |= SG_GRP_DELETE;
if(!empty($_POST["sgWldRead"])) $obj->permissions |= SG_WLD_READ;
if(!empty($_POST["sgWldEdit"])) $obj->permissions |= SG_WLD_EDIT;
if(!empty($_POST["sgWldAdd"])) $obj->permissions |= SG_WLD_ADD;
if(!empty($_POST["sgWldDelete"])) $obj->permissions |= SG_WLD_DELETE;
$obj->groups = $_REQUEST["sgGroups"];
$obj->owner = $_REQUEST["sgOwner"];
return $obj;
}
 
 
function convertDirectory ($path, $io_in, $io_out)
{
if (is_dir($path)) {
$gallery = $io_in->getGallery($path);
echo "<ul><li>Checking $path<br />\n";
if($gallery) {
if($gallery->summary != "" && empty($_REQUEST["convertOverwrite"]))
echo "Did NOT overwrite non-empty summary in $path<br />\n";
else {
if($_REQUEST["convertType"]!='none')
$gallery->summary = $gallery->desc;
if($_REQUEST["convertType"]=='move')
$gallery->desc = "";
}
 
$gallery = setPerms($gallery);
for($i=0; $i<count($gallery->images); $i++)
$gallery->images[$i] = setPerms($gallery->images[$i]);
if($io_out->putGallery($gallery))
echo "Successfully converted $path<br />\n";
else
echo "Problem saving data file for $path<br />\n";
} else
echo "Skipping $path<br />\n";
$d = dir($path);
while (($file = $d->read()) !== false) {
if ($file == '.' || $file == '..') continue;
$path = $d->path."/".$file;
if (is_dir($path)) {
convertDirectory($path);
}
}
echo "</li></ul>\n";
}
}
 
//output functions
function setupHeader($var)
{
echo "\n</p>\n\n<h2>{$var}</h2>\n\n<p>\n";
}
 
/**
* Print an information message. Always returns true.
* @return true
*/
function setupMessage($var)
{
echo "{$var}.<br />\n";
return true;
}
 
/**
* Print an error message. Always returns false.
* @return false
*/
function setupError($var)
{
echo "<span class=\"error\">{$var}</span>.<br />\n";
return false;
}
 
?>
/photogallery/install/migrate.php
0,0 → 1,203
<?php
 
//permissions bit flags
define("SG_GRP_READ", 1);
define("SG_GRP_EDIT", 2);
define("SG_GRP_ADD", 4);
define("SG_GRP_DELETE", 8);
define("SG_WLD_READ", 16);
define("SG_WLD_EDIT", 32);
define("SG_WLD_ADD", 64);
define("SG_WLD_DELETE", 128);
 
$basePath = "../";
 
//determine current step in setup process
$setupStep = isset($_REQUEST["step"]) ? $_REQUEST["step"] : "choose";
 
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>singapore database migration</title>
<link rel="stylesheet" type="text/css" href="../docs/docstyle.css" />
</head>
 
<body>
 
<?php
 
require_once $basePath."includes/config.class.php";
require_once $basePath."includes/gallery.class.php";
require_once $basePath."includes/image.class.php";
$config = new sgConfig($basePath."singapore.ini");
 
 
switch($setupStep) {
case "select" :
setupHeader("Step 1 of 2: Select databases");
setupMessage("Nothing is deleted at this time");
makeWritable($basePath);
setupHeader("OK");
setupMessage("This step completed successfully");
setupHeader("WARNING!");
setupMessage("The following step will delete all gallery, image and user information from the currently selected database. Gallery directories and image files will not be deleted but all extended information (e.g. name, artist, copyright etc.) will be irretrievably lost");
echo '<br /><a href="index.html">Finish</a>';
echo ' | <a href="uninstall.php?step=database">Next: I AM SURE I WANT TO delete database information &gt;&gt;</a>';
break;
case "defaults" :
setupHeader("Step 2 of 3: Select default permissions");
setupMessage("Nothing is deleted at this time");
makeWritable($basePath);
setupHeader("OK");
setupMessage("This step completed successfully");
setupHeader("WARNING!");
setupMessage("The following step will delete all gallery, image and user information from the currently selected database. Gallery directories and image files will not be deleted but all extended information (e.g. name, artist, copyright etc.) will be irretrievably lost");
echo '<br /><a href="index.html">Finish</a>';
echo ' | <a href="uninstall.php?step=database">Next: I AM SURE I WANT TO delete database information &gt;&gt;</a>';
break;
case "convert" :
setupHeader("Step 2 of 2: Delete database information");
//create config object
$config = new sgConfig($basePath."singapore.ini");
$config->loadConfig($basePath."secret.ini.php");
$config->base_path = $basePath;
//include base classes
require_once $basePath."includes/io.class.php";
require_once $basePath."includes/io_sql.class.php";
switch($config->io_handler) {
case "csv" :
setupMessage("The default CSV file database does not require uninstalling");
setupHeader("OK");
setupMessage("This step completed successfully");
break;
case "mysql" :
require_once $basePath."includes/io_mysql.class.php";
setupMessage("Setup will now delete all gallery, image and user information");
setupHeader("Connecting to MySQL database");
$io = new sgIO_mysql($config);
if(!$io) {
setupError("Error connecting to database. Please ensure database settings are correct");
break;
} else setupMessage("Connected");
if(sqlDropTables($io)) {
setupHeader("OK");
setupMessage("This step completed successfully");
} else {
setupHeader("Oops!");
setupError('There was a problem. Please fix it and <a href="migrate.php?step=database">retry this step</a>');
}
break;
case "sqlite" :
setupMessage("Setup will now delete all gallery, image and user information");
setupHeader("Deleting SQLite database file");
if(unlink($basePath.$config->pathto_data_dir."sqlite.dat")) {
setupMessage("Deleted database file '".$basePath.$config->pathto_data_dir."sqlite.dat'");
setupHeader("OK");
setupMessage("This step completed successfully");
} else {
setupError("Unable to delete database file '".$basePath.$config->pathto_data_dir."sqlite.dat'");
setupHeader("Oops!");
setupError('There was a problem. Please fix it and <a href="migrate.php?step=database">retry this step</a>');
}
break;
default :
setupError("Unrecognised io_handler");
}
echo '<br /><a href="uninstall.php?step=reset">&lt;&lt; Previous: Reset permissions</a>';
echo ' | <a href="index.html">Finish</a>';
break;
}
 
if(isset($_REQUEST["convertType"])) {
 
require_once $basePath."includes/config.class.php";
require_once $basePath."includes/gallery.class.php";
require_once $basePath."includes/image.class.php";
require_once $basePath."includes/io.class.php";
require_once $basePath."includes/io_sql.class.php";
$config = new sgConfig($basePath."singapore.ini");
$config->base_path = $basePath;
//echo "<ul>\n";
convertDirectory($config->base_path.$config->pathto_galleries);
//echo "</ul>\n";
echo "<p>All operations complete.</p>\n";
 
} else { ?>
<p>This will convert all your metadata files from singapore 0.9.6, 0.9.7, 0.9.8 or 0.9.9 to 0.9.10.</p>
 
<form method="post" action="<?php echo $_SERVER["PHP_SELF"]; ?>">
<h3>summary field</h3>
<p>There is a new gallery summary field that is displayed instead of the
description in the parent gallery. You can choose to either copy or move the
old description field to the summary field or leave both untouched:</p>
 
<p><input type="radio" class="radio" name="convertType" value="copy" checked="true" /> Copy<br />
<input type="radio" class="radio" name="convertType" value="move" /> Move<br />
<input type="radio" class="radio" name="convertType" value="none" /> Neither<br />
 
<p>By default only empty summary fields will be written to. Check this option to
allow the summary field to be overwritten <input type="checkbox" class="checkbox" name="convertOverwrite" /></p>
 
<h3>permissions</h3>
 
<p>This version introduces multiple authorised users and image &amp; gallery
permissions. Please choose the default permissions that you would like all
objects to be set to. The default permissions selected below are recommended as
they will make all images &amp; galleries readable by everyone but only
modifiable by administrators. See the readme for more information on the
permissions model used by singapore.</p>
<table>
<tr>
<td>Owner</td>
<td><input type="text" name="sgOwner" value="__nobody__" /></td>
</tr>
<tr>
<td>Groups</td>
<td><input type="text" name="sgGroups" value="" /></td>
</tr>
<tr>
<td>Group permissions</td>
<td><div class="inputbox">
<input type="checkbox" class="checkbox" name="sgGrpRead" checked="true"/> Read
<input type="checkbox" class="checkbox" name="sgGrpEdit" /> Edit
<input type="checkbox" class="checkbox" name="sgGrpAdd" /> Add
<input type="checkbox" class="checkbox" name="sgGrpDelete" /> Delete
</div></td>
</tr>
<tr>
<td>World permissions</td>
<td><div class="inputbox">
<input type="checkbox" class="checkbox" name="sgWldRead" checked="true"/> Read
<input type="checkbox" class="checkbox" name="sgWldEdit" /> Edit
<input type="checkbox" class="checkbox" name="sgWldAdd" /> Add
<input type="checkbox" class="checkbox" name="sgWldDelete" /> Delete
</div></td>
</tr>
</table>
 
 
<p>Please note that while the script will create backups of your metadata files
it is highly recommended that you create your own backups for added security.</p>
 
<input type="submit" class="button" value="Go" /></p>
</form>
<?php } ?>
 
<p><a href="index.html">Return</a> to tools.</p>
 
</body>
</html>
/photogallery/install/uninstall.inc.php
0,0 → 1,91
<?php
 
/**
* Contains functions used during the uninstall process.
*
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003, 2004 Tamlyn Rhodes
* @version $Id: uninstall.inc.php,v 1.1 2004/12/02 12:01:59 tamlyn Exp $
*/
 
/**
* Recursively attempts to make all files and directories in $dir writable
*
* @param string full directory name (must end with /)
*/
function makeWritable($dir)
{
if (is_dir($dir)) {
$d = dir($dir);
while (($file = $d->read()) !== false) {
if ($file == '.' || $file == '..') continue;
$fullfile = $d->path . $file;
if(!is_writable($fullfile) && @chmod($fullfile,0777))
setupMessage("Made $fullfile writable");
if (is_dir($fullfile))
makeWritable($fullfile."/");
}
}
}
 
 
/**
* Drops all tables created by singapore.
* @param sgIO_sql pointer to a singapore SQL backend object
*/
function sqlDropTables($io) {
$success = true;
setupHeader("Deleting tables");
if(!$io->query("SELECT * FROM ".$io->config->sql_prefix."galleries"))
setupMessage("'".$io->config->sql_prefix."galleries' table not found - skipped");
elseif($io->query("DROP TABLE ".$io->config->sql_prefix."galleries"))
setupMessage("'".$io->config->sql_prefix."galleries' table deleted");
else
$success = setupError("Unable to delete '".$io->config->sql_prefix."galleries' table:".$io->error());
if(!$io->query("SELECT * FROM ".$io->config->sql_prefix."images"))
setupMessage("'".$io->config->sql_prefix."images' table not found - skipped");
elseif($io->query("DROP TABLE ".$io->config->sql_prefix."images"))
setupMessage("'".$io->config->sql_prefix."images' table deleted");
else
$success = setupError("Unable to delete '".$io->config->sql_prefix."images' table:".$io->error());
if(!$io->query("SELECT * FROM ".$io->config->sql_prefix."users"))
setupMessage("'".$io->config->sql_prefix."users' table not found - skipped");
elseif($io->query("DROP TABLE ".$io->config->sql_prefix."users"))
setupMessage("'".$io->config->sql_prefix."users' table deleted");
else
$success = setupError("Unable to delete '".$io->config->sql_prefix."users' table:".$io->error());
return $success;
}
 
 
//output functions
function setupHeader($var)
{
echo "\n</p>\n\n<h2>{$var}</h2>\n\n<p>\n";
}
 
/**
* Print an information message. Always returns true.
* @return true
*/
function setupMessage($var)
{
echo "{$var}.<br />\n";
return true;
}
 
/**
* Print an error message. Always returns false.
* @return false
*/
function setupError($var)
{
echo "<span class=\"error\">{$var}</span>.<br />\n";
return false;
}
 
?>
/photogallery/install/uninstall.php
0,0 → 1,107
<?php
 
/**
* Performs necessary actions to uninstall singapore.
*
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003, 2004 Tamlyn Rhodes
* @version $Id: uninstall.php,v 1.3 2006/01/20 12:31:08 tamlyn Exp $
*/
 
//path to singapore root
$basePath = "../";
 
require_once "uninstall.inc.php";
require_once $basePath."includes/config.class.php";
 
//determine current step in setup process
$setupStep = isset($_REQUEST["step"]) ? $_REQUEST["step"] : "reset";
 
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>singapore setdown</title>
<link rel="stylesheet" type="text/css" href="../docs/docstyle.css" />
</head>
 
<body>
 
<?php
 
switch($setupStep) {
case "reset" :
setupHeader("Step 1 of 2: Reset permissions");
setupMessage("Resetting file permissions on server-generated content");
setupMessage("Nothing is deleted at this time");
makeWritable($basePath);
setupHeader("OK");
setupMessage("This step completed successfully");
setupHeader("WARNING!");
setupMessage("The following step will delete all gallery, image and user information from the currently selected database. Gallery directories and image files will not be deleted but all extended information (e.g. name, artist, copyright etc.) will be irretrievably lost");
echo '<br /><a href="index.html">Finish</a>';
echo ' | <a href="uninstall.php?step=database">Next: I AM SURE I WANT TO delete database information &gt;&gt;</a>';
break;
case "database" :
setupHeader("Step 2 of 2: Delete database information");
//create config object
$config =& sgConfig::getInstance();
$config->loadConfig($basePath."singapore.ini");
$config->base_path = $basePath;
switch($config->io_handler) {
case "csv" :
setupMessage("The default CSV file database does not require uninstalling");
setupHeader("OK");
setupMessage("This step completed successfully");
break;
case "mysql" :
$config->loadConfig($basePath."secret.ini.php");
include_once $basePath."includes/io_mysql.class.php";
setupMessage("Setup will now delete all gallery, image and user information");
setupHeader("Connecting to MySQL database");
$io = new sgIO_mysql($config);
if(!$io) {
setupError("Error connecting to database. Please ensure database settings are correct");
break;
} else setupMessage("Connected");
if(sqlDropTables($io)) {
setupHeader("OK");
setupMessage("This step completed successfully");
} else {
setupHeader("Oops!");
setupError('There was a problem. Please fix it and <a href="uninstall.php?step=database">retry this step</a>');
}
break;
case "sqlite" :
$config->loadConfig($basePath."secret.ini.php");
setupMessage("Setup will now delete all gallery, image and user information");
setupHeader("Deleting SQLite database file");
if(unlink($basePath.$config->pathto_data_dir."sqlite.dat")) {
setupMessage("Deleted database file '".$basePath.$config->pathto_data_dir."sqlite.dat'");
setupHeader("OK");
setupMessage("This step completed successfully");
} else {
setupError("Unable to delete database file '".$basePath.$config->pathto_data_dir."sqlite.dat'");
setupHeader("Oops!");
setupError('There was a problem. Please fix it and <a href="uninstall.php?step=database">retry this step</a>');
}
break;
default :
setupError("Unrecognised io_handler");
}
echo '<br /><a href="uninstall.php?step=reset">&lt;&lt; Previous: Reset permissions</a>';
echo ' | <a href="index.html">Finish</a>';
break;
}
?>
 
</body>
</html>
/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;
}
 
}
 
 
?>
/photogallery/includes/config.class.php
0,0 → 1,57
<?php
 
/**
* Config class.
*
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003-2005 Tamlyn Rhodes
* @version $Id: config.class.php,v 1.8 2005/11/30 23:02:18 tamlyn Exp $
*/
 
/**
* Reads configuration data from data/singapore.ini and stores the values
* as properties of itself.
*
* @package singapore
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @copyright (c)2003, 2004 Tamlyn Rhodes
*/
class sgConfig
{
 
/**
* Implements the Singleton design pattern by always returning a reference
* to the same sgConfig object. Use instead of 'new'.
*/
function &getInstance()
{
static $instance;
if(!is_object($instance))
//note that the new config object is NOT assigned by reference as
//references are not stored in static variables (don't ask me...)
$instance = new sgConfig();
return $instance;
}
/**
* Parses an ini file for configuration directives and imports the values
* into the current object overwriting any previous values.
* @param string relative or absolute path to the ini file to load
* @return boolean true on success; false otherwise
*/
function loadConfig($configFilePath)
{
if(!file_exists($configFilePath)) return false;
//get values from ini file
$ini_values = parse_ini_file($configFilePath);
 
//import values into object scope
foreach($ini_values as $key => $value) $this->$key = $value;
return true;
}
}
 
?>
/photogallery/includes/gallery.class.php
0,0 → 1,320
<?php
 
/**
* Gallery class.
*
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003-2005 Tamlyn Rhodes
* @version $Id: gallery.class.php,v 1.19 2006/09/12 11:53:18 thepavian Exp $
*/
 
//include the base class
require_once dirname(__FILE__)."/item.class.php";
/**
* Data-only class used to store gallery data.
*
* @package singapore
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @copyright (c)2003-2005 Tamlyn Rhodes
*/
class sgGallery extends sgItem
{
/**
* Filename of the image used to represent this gallery.
* Special values:
* - __none__ no thumbnail is displayed
* - __random__ a random image is chosen every time
* @var string
*/
var $filename = "__none__";
/**
* Short multiline summary of gallery contents
* @var string
*/
var $summary = "";
/**
* Array of {@link sgImage} objects
* @var array
*/
var $images = array();
/**
* Array of {@link sgGallery} objects
* @var array
*/
var $galleries = array();
/**
* Constructor
* @param string gallery id
* @param sgGallery reference to the parent gallery
*/
function sgGallery($id, &$parent)
{
$this->id = $id;
$this->parent =& $parent;
$this->config =& sgConfig::getInstance();
$this->translator =& Translator::getInstance();
}
/** @return bool true if this is a non-album gallery; false otherwise */
function isGallery() { return $this->hasChildGalleries(); }
/** @return bool true if this is an album; false otherwise */
function isAlbum() { return !$this->isGallery(); }
/** @return bool true if this is the root gallery; false otherwise */
function isRoot() { return $this->id == "."; }
/** @return bool true if this gallery has child galleries; false otherwise */
function hasChildGalleries() { return $this->galleryCount() != 0; }
/** @return bool true if this gallery contains one or more images; false otherwise */
function hasImages() { return $this->imageCount() != 0; }
function imageCount() { return count($this->images); }
function galleryCount() { return count($this->galleries); }
function imageCountText() { return $this->translator->_ng("%s image", "%s images", $this->imageCount()); }
function galleryCountText() { return $this->translator->_ng("%s gallery", "%s galleries", $this->galleryCount()); }
/**
* Caches returned value for use with repeat requests
* @return string the rawurlencoded version of the gallery id
*/
function idEncoded()
{
return isset($this->idEncoded) ? $this->idEncoded : $this->idEncoded = $this->encodeId($this->id);
}
/**
* rawurlencode() supplied string but preserve / character for cosmetic reasons.
* @param string id to encode
* @return string encoded id
* @static
*/
function encodeId($id)
{
$in = explode("/",$id);
$out = array();
for($i=1;$i<count($in);$i++)
$out[$i-1] = rawurlencode($in[$i]);
return $out ? implode("/",$out) : ".";
}
function nameForce()
{
if($this->name)
return $this->name;
elseif($this->isRoot())
return $this->config->gallery_name;
else
return substr($this->id, strrpos($this->id,'/')+1);
}
/**
* If the gallery is an album then it returns the number of
* images contained otherwise the number of sub-galleries is returned
* @return string the contents of the specified gallery
*/
function itemCountText()
{
if($this->isAlbum())
return $this->imageCountText();
else
return $this->galleryCountText();
}
/**
* If the gallery is an album then it returns the number of
* images contained otherwise the number of sub-galleries is returned
* @return int the contents of the specified gallery
*/
function itemCount()
{
if($this->isAlbum())
return $this->imageCount();
else
return $this->galleryCount();
}
/**
* @return int number of galleries in current view
*/
function galleryCountSelected()
{
return min($this->galleryCount() - $this->startat, $this->config->thumb_number_gallery);
}
/**
* @return int number of image in current view
*/
function imageCountSelected()
{
return min($this->imageCount() - $this->startat, $this->config->thumb_number_album);
}
/**
* @return string the absolute, canonical system path to the image
*/
function realPath()
{
return realpath($this->config->base_path.$this->config->pathto_galleries.$this->id);
}
function thumbnailURL($type = "gallery")
{
$thumb = $this->thumbnail($type);
return $thumb->URL();
}
function thumbnailHTML($class = "sgThumbGallery", $type = "gallery")
{
$thumb = $this->thumbnail($type);
if($thumb == null) {
$ret = nl2br($this->translator->_g("No\nthumbnail"));
} else {
$ret = '<img src="'.$thumb->URL().'" ';
$ret .= 'class="'.$class.'" ';
$ret .= 'width="'.$thumb->width().'" height="'.$thumb->height().'" ';
$ret .= 'alt="'.$this->translator->_g("Sample image from gallery").'" />';
}
return $ret;
}
function thumbnailLink($class = "sgThumbGallery", $type = "gallery")
{
return '<a href="'.$this->URL().'">'.$this->thumbnailHTML($class, $type).'</a>';
}
/**
* Removes script-generated HTML (BRs and URLs) but leaves any other HTML
* @return string the summary of the gallery
*/
function summaryStripped()
{
return str_replace("<br />","\n",$this->summary());
}
function hasPrev()
{
return (bool) $this->index();
}
function hasNext()
{
$index = $this->index();
return $index !== false && $index < $this->parent->galleryCount()-1;
}
function &prevGallery()
{
$tmp =& new sgGallery($this->parent->id.'/'.$this->parent->galleries[$this->index()-1], $this->parent);
return $tmp;
}
function &nextGallery()
{
$tmp =& new sgGallery($this->parent->id.'/'.$this->parent->galleries[$this->index()+1], $this->parent);
return $tmp;
}
function prevURL($action = null)
{
$tmp =& $this->prevGallery();
return $tmp->URL(null, $action);
}
function nextURL($action = null)
{
$tmp =& $this->nextGallery();
return $tmp->URL(null, $action);
}
function prevLink($action = null)
{
return '<a href="'.$this->prevURL($action).'">'.$this->prevText().'</a>';
}
function nextLink($action = null)
{
return '<a href="'.$this->nextURL($action).'">'.$this->nextText().'</a>';
}
function prevText()
{
return $this->translator->_g("gallery|Previous");
}
function nextText()
{
return $this->translator->_g("gallery|Next");
}
/**
* finds position of current gallery in parent array
*/
function index()
{
if(!$this->isRoot())
foreach($this->parent->galleries as $key => $galleryId)
if(basename($this->id) == $galleryId)
return $key;
return false;
}
/** Accessor methods */
function summary() { return $this->summary; }
/** Private methods */
function thumbnail($type)
{
//only create thumbnail if it doesn't already exist
if(!isset($this->thumbnails[$type])) {
if($this->filename == "__none__" || $this->imageCount() == 0)
return;
elseif($this->filename == "__random__") {
srand(time()); //seed random number generator and select random image
$img =& $this->images[rand(0,count($this->images)-1)];
} else
$img =& $this->findImage($this->filename);
//create thumbnail
$this->thumbnails[$type] =& new sgThumbnail($img, $type);
}
return $this->thumbnails[$type];
}
/**
* Finds 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 sgImage the image found
*/
function &findImage($image)
{
if(is_string($image))
foreach($this->images as $index => $img)
if($img->id == $image)
return $this->images[$index];
elseif(is_int($image) && $image >= 0 && $image < $this->imageCount())
return $this->images[$image];
return null;
}
}
 
 
?>
/photogallery/includes/image.class.php
0,0 → 1,339
<?php
 
/**
* Image class.
*
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003-2005 Tamlyn Rhodes
* @version $Id: image.class.php,v 1.22 2006/08/06 13:50:20 thepavian Exp $
*/
 
//include the base class
require_once dirname(__FILE__)."/item.class.php";
/**
* Data-only class used to store image data.
* @package singapore
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @copyright (c)2003-2005 Tamlyn Rhodes
*/
class sgImage extends sgItem
{
/**
* Width in pixels of the image
* @var int
*/
var $width = 0;
/**
* Height in pixels of the image
* @var int
*/
var $height = 0;
/**
* Image file format flag as returned by GetImageSize()
* @var int
*/
var $type;
/**
* Configurable field
*/
var $camera = "";
var $lens = "";
var $film = "";
var $darkroom = "";
var $digital = "";
/**
* Constructor
* @param string image id
* @param sgGallery reference to the parent gallery
*/
function sgImage($id, &$parent)
{
$this->id = $id;
$this->parent =& $parent;
$this->config =& sgConfig::getInstance();
$this->translator =& Translator::getInstance();
}
/**
* Over-rides the method in the item class
* @return true returns true
*/
function isImage() { return true; }
/**
* @return bool true if image height is greater than width
*/
function isPortrait()
{
return $this->width()/$this->height() > 1;
}
/**
* @return bool true if image height is greater than width
*/
function isLandscape()
{
return $this->width()/$this->height() < 1;
}
function hasPrev()
{
return (bool) $this->index();
}
function hasNext()
{
$index = $this->index();
return $index !== false && $index < $this->parent->imageCount()-1;
}
function &firstImage()
{
return $this->parent->images[0];
}
function &prevImage()
{
return $this->parent->images[$this->index()-1];
}
function &nextImage()
{
return $this->parent->images[$this->index()+1];
}
function &lastImage()
{
return $this->parent->images[count($this->parent->images)-1];
}
function firstLink($action = null)
{
if(!$this->hasPrev())
return "";
$tmp =& $this->firstImage();
return '<a href="'.$tmp->URL(null, $action).'">'.$this->firstText().'</a>';
}
function prevLink($action = null)
{
if(!$this->hasPrev())
return "";
return '<a href="'.$this->prevURL($action).'">'.$this->prevText().'</a>';
}
function nextLink($action = null)
{
if(!$this->hasNext())
return "";
return '<a href="'.$this->nextURL($action).'">'.$this->nextText().'</a>';
}
function lastLink($action = null)
{
if(!$this->hasNext())
return "";
$tmp =& $this->lastImage();
return '<a href="'.$tmp->URL(null, $action).'">'.$this->lastText().'</a>';
}
function prevURL($action = null)
{
$tmp =& $this->prevImage();
return $tmp->URL(null, $action);
}
function nextURL($action = null)
{
$tmp =& $this->nextImage();
return $tmp->URL(null, $action);
}
function firstText() { return $this->translator->_g("image|First"); }
function prevText() { return $this->translator->_g("image|Previous"); }
function nextText() { return $this->translator->_g("image|Next"); }
function lastText() { return $this->translator->_g("image|Last"); }
function parentText() { return $this->translator->_g("image|Thumbnails"); }
function imageURL()
{
if($this->config->full_image_resize) {
$img = $this->thumbnail("image");
return $img->URL();
} else
return $this->realURL();
}
function realURL()
{
if($this->isRemote())
return $this->id;
else
return $this->config->base_url.$this->config->pathto_galleries.$this->parent->idEncoded()."/".$this->idEncoded();
}
function imageHTML($class = "sgImage")
{
$ret = "<img src=\"".$this->imageURL().'" ';
$ret .= 'class="'.$class.'" ';
$ret .= 'width="'.$this->width().'" height="'.$this->height().'" ';
if($this->config->imagemap_navigation) $ret .= 'usemap="#sgNavMap" border="0" ';
$ret .= 'alt="'.$this->name().$this->byArtistText().'" />';
return $ret;
}
function thumbnailURL($type = "album")
{
$thumb = $this->thumbnail($type);
return $thumb->URL();
}
function thumbnailHTML($class = "sgThumbnailAlbum", $type = "album")
{
$thumb = $this->thumbnail($type);
$ret = "<img src=\"".$thumb->URL().'" ';
$ret .= 'class="'.$class.'" ';
$ret .= 'width="'.$thumb->width().'" height="'.$thumb->height().'" ';
$ret .= 'alt="'.$this->name().$this->byArtistText().'" />';
return $ret;
}
function thumbnailLink($class = "sgThumbnailAlbum", $type = "album")
{
return '<a href="'.$this->URL().'">'.$this->thumbnailHTML($class, $type).'</a>';
}
function thumbnailPopupLink($class = "sgThumbnailAlbum", $type = "album")
{
$ret = '<a href="'.$this->URL().'" onclick="';
$ret .= "window.open('".$this->imageURL()."','','toolbar=0,resizable=1,";
$ret .= "width=".($this->width()+20).",";
$ret .= "height=".($this->height()+20)."');";
$ret .= "return false;\">".$this->thumbnailHTML($class, $type)."</a>";
return $ret;
}
function nameForce()
{
if($this->name)
return $this->name;
elseif($this->isRemote())
return substr($this->id, strrpos($this->id,'/') + 1, strrpos($this->id,'.') - strrpos($this->id,'/') - 1);
else
return substr($this->id, 0, strrpos($this->id,'.'));
}
/**
* checks if image is remote (filename starts with 'http://')
*/
function isRemote($image = null)
{
if($image == null) $image = $this->id;
return substr($image, 0, 7) == "http://";
}
/**
* @return string the absolute, canonical system path to the image
*/
function realPath()
{
if($this->isRemote())
return $this->id;
else
return realpath($this->config->base_path.$this->config->pathto_galleries.$this->parent->id."/".$this->id);
}
/**
* @return string the rawurlencoded version of the image id
*/
function idEncoded()
{
return rawurlencode($this->id);
}
function width()
{
if($this->config->full_image_resize) {
$img = $this->thumbnail("image");
return $img->width();
} else
return $this->realWidth();
}
function height()
{
if($this->config->full_image_resize) {
$img = $this->thumbnail("image");
return $img->height();
} else
return $this->realHeight();
}
/**
* finds position of current image in parent array
*/
function index()
{
foreach($this->parent->images as $key => $img)
if($this->id == $img->id)
return $key;
return false;
}
function realWidth()
{
//try to load image dimensions if not already loaded
if($this->width == 0) {
$size = @GetImageSize($this->realPath());
if($size)
list($this->width, $this->height, $this->type) = $size;
else
return $this->config->thumb_width_image;
}
return $this->width;
}
function realHeight()
{
//try to load image dimensions if not already loaded
if($this->height == 0) {
$size = @GetImageSize($this->realPath());
if($size)
list($this->width, $this->height, $this->type) = $size;
else
return $this->config->thumb_height_image;
}
return $this->height;
}
/** Accessor methods */
function type() { return $this->type; }
/* Private methods */
function &thumbnail($type)
{
//only create thumbnail if it doesn't already exist
if(!isset($this->thumbnails[$type]))
$this->thumbnails[$type] =& new sgThumbnail($this, $type);
return $this->thumbnails[$type];
}
}
 
?>
/photogallery/includes/index.php
0,0 → 1,0
<?php header("Location: ../") ?>
/photogallery/includes/io.class.php
0,0 → 1,174
<?php
 
/**
* IO class.
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003-2005 Tamlyn Rhodes
* @version $Id: io.class.php,v 1.11 2005/12/04 04:39:46 tamlyn Exp $
*/
 
/**
* Abstract superclass of all IO classes. Also implements iifn code.
* @package singapore
* @abstract
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @copyright (c)2003, 2004 Tamlyn Rhodes
*/
class sgIO
{
/**
* Reference to a {@link sgConfig} object representing the current
* script configuration
* @var sgConfig
*/
var $config;
/**
* Constructor. Can be over-ridden by subclass but does not need to be.
* @param sgConfig pointer to current script configuration object
*/
function sgIO()
{
$this->config =& sgConfig::getInstance();
}
/**
* Pseudo-abstract method to be over-ridden in subclasses.
*/
function getName()
{
return "undefined";
}
 
/**
* Pseudo-abstract method to be over-ridden in subclasses.
*/
function getVersion()
{
return "undefined";
}
 
/**
* Pseudo-abstract method to be over-ridden in subclasses.
*/
function getAuthor()
{
return "undefined";
}
 
/**
* Pseudo-abstract method to be over-ridden in subclasses.
*/
function getDescription()
{
return "undefined";
}
 
/**
* Fetches gallery info for the specified gallery (and immediate children).
* @param string gallery id
* @param sgItem reference to parent gallery
* @param int number of levels of child galleries to fetch (optional)
* @param string language code spec for this request (optional, ignored)
*/
function &getGallery($galleryId, &$parent, $getChildGalleries = 1, $language = null)
{
$gal =& new sgGallery($galleryId, $parent);
if(file_exists($this->config->base_path.$this->config->pathto_galleries.$galleryId)) {
$bits = explode("/",$gal->id);
$temp = strtr($bits[count($bits)-1], "_", " ");
if($temp == ".")
$gal->name = $this->config->gallery_name;
elseif($this->config->enable_iifn && strpos($temp, " - "))
list($gal->artist,$gal->name) = explode(" - ", $temp);
else
$gal->name = $temp;
$dir = Singapore::getListing($this->config->base_path.$this->config->pathto_galleries.$gal->id."/", $this->config->recognised_extensions);
//set gallery thumbnail to first image in gallery (if any)
if(isset($dir->files[0])) $gal->filename = $dir->files[0];
for($i=0; $i<count($dir->files); $i++)
//always get the first image for the gallery thumbnail
//but only get the rest if child galleries are requested
if($getChildGalleries || $i==0) {
$gal->images[$i] =& new sgImage($dir->files[$i], $gal);
//trim off file extension and replace underscores with spaces
$temp = strtr(substr($gal->images[$i]->id, 0, strrpos($gal->images[$i]->id,".")-strlen($gal->images[$i]->id)), "_", " ");
//split string in two on " - " delimiter
if($this->config->enable_iifn && strpos($temp, " - "))
list($gal->images[$i]->artist,$gal->images[$i]->name) = explode(" - ", $temp);
else
$gal->images[$i]->name = $temp;
//get image size and type
list(
$gal->images[$i]->width,
$gal->images[$i]->height,
$gal->images[$i]->type
) = @GetImageSize($this->config->base_path.$this->config->pathto_galleries.$gal->id."/".$gal->images[$i]->id);
//set parent link
$gal->images[$i]->parent =& $gal;
} else
//otherwise just create an empty array of the appropriate length
$gal->images[$i] = $dir->files[$i];
} else {
//selected gallery does not exist
return null;
}
//discover child galleries
if($getChildGalleries)
//but only fetch their info if required too
foreach($dir->dirs as $gallery)
$gal->galleries[] =& $this->getGallery($galleryId."/".$gallery, $gal, $getChildGalleries-1, $language);
else
//otherwise just copy their names in so they can be counted
$gal->galleries = $dir->dirs;
return $gal;
}
/**
* Pseudo-abstract method to be over-ridden in subclasses.
*/
function putGallery($gal) {
return false;
}
/**
* Pseudo-abstract method to be over-ridden in subclasses.
*/
function getHits($gal) {
return false;
}
/**
* Pseudo-abstract method to be over-ridden in subclasses.
*/
function putHits($gal) {
return false;
}
/**
* Pseudo-abstract method to be over-ridden in subclasses.
*/
function getUsers() {
return array();
}
/**
* Pseudo-abstract method to be over-ridden in subclasses.
*/
function putUsers($users) {
return false;
}
}
 
?>
/photogallery/includes/io_csv.class.php
0,0 → 1,325
<?php
 
/**
* IO class.
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003-2005 Tamlyn Rhodes
* @version $Id: io_csv.class.php,v 1.34 2006/06/25 00:13:56 tamlyn Exp $
*/
 
//include the base IO class
require_once dirname(__FILE__)."/io.class.php";
/**
* Class used to read and write data to and from CSV files.
* @see sgIO_iifn
* @package singapore
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @copyright (c)2003, 2004 Tamlyn Rhodes
*/
class sgIO_csv extends sgIO
{
//constructor provided by parent class
/**
* Name of IO backend.
*/
function getName()
{
return "CSV";
}
 
/**
* Version of IO backend.
*/
function getVersion()
{
return "$Revision: 1.34 $";
}
 
/**
* Author of IO backend.
*/
function getAuthor()
{
return "Tamlyn Rhodes";
}
 
/**
* Brief description of IO backend and it's requirements.
*/
function getDescription()
{
return "Uses comma separated value files. Does not require a database.";
}
 
/**
* Fetches gallery info for the specified gallery and immediate children.
* @param string gallery id
* @param string language code spec for this request (optional)
* @param int number of levels of child galleries to fetch (optional)
* @return sgGallery the gallery object created
*/
function &getGallery($galleryId, &$parent, $getChildGalleries = 1, $language = null)
{
$gal =& new sgGallery($galleryId, $parent);
 
if($language == null) {
$translator =& Translator::getInstance();
$language = $translator->language;
}
//try to open language specific metadata
$fp = @fopen($this->config->base_path.$this->config->pathto_galleries.$galleryId."/metadata.$language.csv","r");
//if fail then try to open generic metadata
if(!$fp)
$fp = @fopen($this->config->base_path.$this->config->pathto_galleries.$galleryId."/metadata.csv","r");
if($fp) {
 
while($temp[] = fgetcsv($fp,2048));
fclose($fp);
list(
$gal->filename,
$gal->thumbnail,
$gal->owner,
$gal->groups,
$gal->permissions,
$gal->categories,
$gal->name,
$gal->artist,
$gal->email,
$gal->copyright,
$gal->desc,
$gal->summary,
$gal->date
) = $temp[1];
//only fetch individual images if child galleries are required
if($getChildGalleries) {
for($i=0;$i<count($temp)-3;$i++) {
$gal->images[$i] =& new sgImage($temp[$i+2][0], $gal, $this->config);
list(,
$gal->images[$i]->thumbnail,
$gal->images[$i]->owner,
$gal->images[$i]->groups,
$gal->images[$i]->permissions,
$gal->images[$i]->categories,
$gal->images[$i]->name,
$gal->images[$i]->artist,
$gal->images[$i]->email,
$gal->images[$i]->copyright,
$gal->images[$i]->desc,
$gal->images[$i]->location,
$gal->images[$i]->date,
$gal->images[$i]->camera,
$gal->images[$i]->lens,
$gal->images[$i]->film,
$gal->images[$i]->darkroom,
$gal->images[$i]->digital
) = $temp[$i+2];
//get image size and type
list(
$gal->images[$i]->width,
$gal->images[$i]->height,
$gal->images[$i]->type
) = @GetImageSize($gal->images[$i]->realPath());
}
//otherwise just fill in empty images
} else if(count($temp) > 3) {
for($i=0;$i<count($temp)-3;$i++)
$gal->images[$i] =& new sgImage($temp[$i+2][0], $gal);
}
} else
//no metadata found so use iifn method implemented in superclass
return parent::getGallery($galleryId, $parent, $getChildGalleries, $language);
//discover child galleries
$dir = Singapore::getListing($this->config->base_path.$this->config->pathto_galleries.$galleryId."/");
if($getChildGalleries)
//but only fetch their info if required too
foreach($dir->dirs as $gallery)
$gal->galleries[] = $this->getGallery($galleryId."/".$gallery, $gal, $getChildGalleries-1, $language);
else
//otherwise just copy their names in so they can be counted
$gal->galleries = $dir->dirs;
return $gal;
}
/**
* Stores gallery information.
* @param sgGallery instance of gallery object to be stored
*/
function putGallery($gal) {
$dataFile = $this->config->base_path.$this->config->pathto_galleries.$gal->id."/metadata.csv";
@chmod($dataFile, octdec($this->config->file_mode));
$fp = @fopen($dataFile,"w");
if(!$fp)
return false;
$success = (bool) fwrite($fp,"filename,thumbnail,owner,group(s),permissions,catergories,image name,artist name,artist email,copyright,image description,image location,date taken,camera info,lens info,film info,darkroom manipulation,digital manipulation");
$success &= (bool) fwrite($fp,"\n\"".
$gal->filename.'",,'.
$gal->owner.','.
$gal->groups.','.
$gal->permissions.','.
$gal->categories.',"'.
str_replace('"','""',$gal->name).'","'.
str_replace('"','""',$gal->artist).'","'.
str_replace('"','""',$gal->email).'","'.
str_replace('"','""',$gal->copyright).'","'.
str_replace('"','""',$gal->desc).'","'.
str_replace('"','""',$gal->summary).'","'.
str_replace('"','""',$gal->date).'"'
);
for($i=0;$i<count($gal->images);$i++)
$success &= (bool) fwrite($fp,"\n\"".
$gal->images[$i]->id.'",,'.
//$gal->images[$i]->thumbnail.','.
$gal->images[$i]->owner.','.
$gal->images[$i]->groups.','.
$gal->images[$i]->permissions.','.
$gal->images[$i]->categories.',"'.
str_replace('"','""',$gal->images[$i]->name).'","'.
str_replace('"','""',$gal->images[$i]->artist).'","'.
str_replace('"','""',$gal->images[$i]->email).'","'.
str_replace('"','""',$gal->images[$i]->copyright).'","'.
str_replace('"','""',$gal->images[$i]->desc).'","'.
str_replace('"','""',$gal->images[$i]->location).'","'.
str_replace('"','""',$gal->images[$i]->date).'","'.
str_replace('"','""',$gal->images[$i]->camera).'","'.
str_replace('"','""',$gal->images[$i]->lens).'","'.
str_replace('"','""',$gal->images[$i]->film).'","'.
str_replace('"','""',$gal->images[$i]->darkroom).'","'.
str_replace('"','""',$gal->images[$i]->digital).'"'
);
$success &= (bool) fclose($fp);
return $success;
}
/**
* Fetches hit data from file.
* @param sgGallery gallery object to load hits into
*/
function getHits(&$gal) {
$fp = @fopen($this->config->base_path.$this->config->pathto_galleries.$gal->id."/hits.csv","r");
if($fp) {
flock($fp, LOCK_SH);
while($temp[] = fgetcsv($fp,255));
flock($fp, LOCK_UN);
fclose($fp);
} else $temp = array();
if(isset($temp[0]))
list(
,
$gal->hits,
$gal->lasthit
) = $temp[0];
for($i=0;$i<count($temp)-2;$i++) {
if(isset($gal->images[$i]) && $temp[$i+1][0] == $gal->images[$i]->id)
list(
,
$gal->images[$i]->hits,
$gal->images[$i]->lasthit
) = $temp[$i+1];
else
foreach($gal->images as $key => $img)
if($temp[$i+1][0] == $img->id)
list(
,
$gal->images[$key]->hits,
$gal->images[$key]->lasthit
) = $temp[$i+1];
}
return true;
}
/**
* Stores gallery hits.
* @param sgGallery gallery object to store
*/
function putHits($gal) {
$logfile = $this->config->base_path.$this->config->pathto_galleries.$gal->id."/hits.csv";
if(!file_exists($logfile) && !@touch($logfile)) return false;
@chmod($logfile, octdec($this->config->file_mode));
$fp = @fopen($logfile,"r+");
if(!$fp) return false;
flock($fp, LOCK_EX);
ftruncate($fp, 0);
fwrite($fp, '"'.
$gal->id.'",'.
$gal->hits.','.
$gal->lasthit
);
foreach($gal->images as $img)
fwrite($fp, "\n\"".
$img->id.'",'.
$img->hits.','.
$img->lasthit
);
flock($fp, LOCK_UN);
fclose($fp);
return true;
}
/**
* Fetches all registered users.
*/
function getUsers() {
$fp = fopen($this->config->base_path.$this->config->pathto_data_dir."users.csv.php","r");
//strip off description line
fgetcsv($fp,1024);
for($i=0;$entry = fgetcsv($fp,1000,",");$i++) {
$users[$i] = new sgUser(null,null);
list(
$users[$i]->username,
$users[$i]->userpass,
$users[$i]->permissions,
$users[$i]->groups,
$users[$i]->email,
$users[$i]->fullname,
$users[$i]->description,
$users[$i]->stats
) = $entry;
}
fclose($fp);
return $users;
}
/**
* Stores all registered users.
* @param array an array of sgUser objects representing the users to store
*/
function putUsers($users) {
$fp = fopen($this->config->base_path.$this->config->pathto_data_dir."users.csv.php","w");
if(!$fp) return false;
$success = (bool) fwrite($fp,"<?php die(\"The contents of this file are hidden\"); ?>username,md5(pass),permissions,group(s),email,name,description,stats\n");
for($i=0;$i<count($users);$i++)
$success &= (bool) fwrite($fp,$users[$i]->username.",".$users[$i]->userpass.",".$users[$i]->permissions.",\"".$users[$i]->groups."\",\"".$users[$i]->email."\",\"".$users[$i]->fullname."\",\"".$users[$i]->description."\",\"".$users[$i]->stats."\"\n");
fclose($fp);
return $success;
}
}
 
?>
/photogallery/includes/io_mysql.class.php
0,0 → 1,91
<?php
 
/**
* IO class.
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003, 2004 Tamlyn Rhodes
* @version $Id: io_mysql.class.php,v 1.7 2005/11/30 23:02:18 tamlyn Exp $
*/
 
//include the base IO class and generic SQL class
require_once dirname(__FILE__)."/iosql.class.php";
/**
* Class used to read and write data to and from a MySQL database.
* @package singapore
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @copyright (c)2004 Tamlyn Rhodes
*/
class sgIO_mysql extends sgIOsql
{
/**
* @param sgConfig pointer to a {@link sgConfig} object representing
* the current script configuration
*/
function sgIO_mysql()
{
$this->config =& sgConfig::getInstance();
mysql_connect($this->config->sql_host, $this->config->sql_user, $this->config->sql_pass);
mysql_select_db($this->config->sql_database);
}
 
/**
* Name of IO backend.
*/
function getName()
{
return "MySQL";
}
 
/**
* Version of IO backend.
*/
function getVersion()
{
return "$Revision: 1.7 $";
}
 
/**
* Author of IO backend.
*/
function getAuthor()
{
return "Tamlyn Rhodes";
}
 
/**
* Brief description of IO backend and it's requirements.
*/
function getDescription()
{
return "Uses a MySQL database. Requires a MySQL database server and the MySQL PHP extension.";
}
 
function query($query)
{
return mysql_query($query);
}
function escape_string($query)
{
return mysql_escape_string($query);
}
function fetch_array($res)
{
return mysql_fetch_array($res);
}
function num_rows($res)
{
return mysql_num_rows($res);
}
 
function error()
{
return mysql_error();
}
 
}
 
?>
/photogallery/includes/io_sqlite.class.php
0,0 → 1,95
<?php
 
/**
* IO class.
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003, 2004 Tamlyn Rhodes
* @version $Id: io_sqlite.class.php,v 1.4 2005/11/30 23:02:18 tamlyn Exp $
*/
 
//include the generic SQL class
require_once dirname(__FILE__)."/iosql.class.php";
/**
* Class used to read and write data to and from a SQLite database.
* @package singapore
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @copyright (c)2004 Tamlyn Rhodes
*/
class sgIO_sqlite extends sgIOsql
{
/**
* Database resource pointer
*/
var $db;
/**
* @param sgConfig pointer to a {@link sgConfig} object representing
* the current script configuration
*/
function sgIO_sqlite()
{
$this->config =& sgConfig::getInstance();
$this->db = sqlite_open($this->config->base_path.$this->config->pathto_data_dir."sqlite.dat");
}
 
/**
* Name of IO backend.
*/
function getName()
{
return "SQLite";
}
 
/**
* Version of IO backend.
*/
function getVersion()
{
return "$Revision: 1.4 $";
}
 
/**
* Author of IO backend.
*/
function getAuthor()
{
return "Tamlyn Rhodes";
}
 
/**
* Brief description of IO backend and it's requirements.
*/
function getDescription()
{
return "Uses a SQLite database. Requires only the SQLite PHP extension which incorporates the database server.";
}
 
function query($query)
{
return sqlite_query($this->db, $query);
}
function escape_string($query)
{
return sqlite_escape_string($query);
}
function fetch_array($res)
{
return sqlite_fetch_array($res);
}
function num_rows($res)
{
return sqlite_num_rows($res);
}
 
function error()
{
return sqlite_error_string(sqlite_last_error($this->db));
}
 
}
 
?>
/photogallery/includes/iosql.class.php
0,0 → 1,252
<?php
 
/**
* IO class.
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003, 2004 Tamlyn Rhodes
* @version $Id: iosql.class.php,v 1.5 2006/01/22 03:25:36 tamlyn Exp $
*/
 
//include the base IO class
require_once dirname(__FILE__)."/io.class.php";
/**
* Class used to read and write data to and from a MySQL database.
* @package singapore
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @copyright (c)2004 Tamlyn Rhodes
*/
class sgIOsql extends sgIO
{
/**
* Overridden in subclasses
*/
function query($query) { }
function escape_string($query) { }
function fetch_array($res) { }
function num_rows($res) { }
function error()
{
return "unknown error";
}
/**
* Fetches gallery info for the specified gallery and immediate children.
* @param string gallery id
* @param string language code spec for this request (optional)
* @param int number of levels of child galleries to fetch (optional)
*/
function &getGallery($galleryId, &$parent, $getChildGalleries = 1, $language = null)
{
$gal =& new sgGallery($galleryId, $parent);
if($language == null) $language = $this->config->default_language;
//try to open language specific gallery info
$res = $this->query("SELECT * FROM ".$this->config->sql_prefix."galleries ".
"WHERE id='".$this->escape_string($galleryId)."' ".
"AND lang='".$this->escape_string($language)."'");
//if fail then try to open generic gallery info
if(!$res || !$this->num_rows($res))
$res = $this->query("SELECT * FROM ".$this->config->sql_prefix."galleries ".
"WHERE id='".$this->escape_string($galleryId)."' and lang=''");
//if that succeeds then get galleries from db
if($res && $this->num_rows($res)) {
$galinfo = $this->fetch_array($res);
$gal->filename = $galinfo['filename'];
$gal->owner = $galinfo['owner'];
$gal->groups = $galinfo['groups'];
$gal->permissions = $galinfo['permissions'];
$gal->categories = $galinfo['categories'];
$gal->name = $galinfo['name'];
$gal->artist = $galinfo['artist'];
$gal->email = $galinfo['email'];
$gal->copyright = $galinfo['copyright'];
$gal->desc = $galinfo['description'];
$gal->summary = $galinfo['summary'];
$gal->date = $galinfo['date'];
$gal->hits = $galinfo['hits'];
$gal->lasthit = $galinfo['lasthit'];
//try to open language specific image info
$res = $this->query("SELECT * FROM ".$this->config->sql_prefix."images ".
"WHERE galleryid='".$this->escape_string($galleryId)."' ".
"AND lang='".$this->escape_string($language)."'");
//if fail then try to open generic image info
if(!$res || !$this->num_rows($res))
$res = $this->query("SELECT * FROM ".$this->config->sql_prefix."images ".
"WHERE galleryid='".$this->escape_string($galleryId)."' and lang=''");
for($i=0;$i<$this->num_rows($res);$i++) {
$imginfo = $this->fetch_array($res);
$gal->images[$i] =& new sgImage($imginfo['filename'], $gal);
$gal->images[$i]->thumbnail = $imginfo['thumbnail'];
$gal->images[$i]->owner = $imginfo['owner'];
$gal->images[$i]->groups = $imginfo['groups'];
$gal->images[$i]->permissions = $imginfo['permissions'];
$gal->images[$i]->categories = $imginfo['categories'];
$gal->images[$i]->name = $imginfo['name'];
$gal->images[$i]->artist = $imginfo['artist'];
$gal->images[$i]->email = $imginfo['email'];
$gal->images[$i]->copyright = $imginfo['copyright'];
$gal->images[$i]->desc = $imginfo['description'];
$gal->images[$i]->location = $imginfo['location'];
$gal->images[$i]->date = $imginfo['date'];
$gal->images[$i]->camera = $imginfo['camera'];
$gal->images[$i]->lens = $imginfo['lens'];
$gal->images[$i]->film = $imginfo['film'];
$gal->images[$i]->darkroom = $imginfo['darkroom'];
$gal->images[$i]->digital = $imginfo['digital'];
$gal->images[$i]->width = $imginfo['width'];
$gal->images[$i]->height = $imginfo['height'];
$gal->images[$i]->type = $imginfo['type'];
$gal->images[$i]->hits = $imginfo['hits'];
$gal->images[$i]->lasthit = $imginfo['lasthit'];
}
} else
//no record found so use iifn method implemented in parent class
return parent::getGallery($galleryId, $parent, $getChildGalleries, $language);
//discover child galleries
$dir = Singapore::getListing($this->config->base_path.$this->config->pathto_galleries.$galleryId."/");
if($getChildGalleries)
//but only fetch their info if required too
foreach($dir->dirs as $gallery)
$gal->galleries[] =& $this->getGallery($galleryId."/".$gallery, $gal, $getChildGalleries-1, $language);
else
//otherwise just copy their names in so they can be counted
$gal->galleries = $dir->dirs;
return $gal;
}
/**
* Stores gallery information.
* @param sgGallery instance of gallery object to be stored
*/
function putGallery($gal, $language = "") {
//insert gallery info
$success = (bool) $this->query("REPLACE INTO ".$this->config->sql_prefix."galleries ".
"(id,lang,filename,owner,groups,permissions,categories,name,artist,".
"email,copyright,description,summary,date,hits,lasthit) VALUES ('".
$this->escape_string($gal->id)."','".$language."','".
$this->escape_string($gal->filename)."','".
$gal->owner."','".$gal->groups."',".$gal->permissions.",'".
$this->escape_string($gal->categories)."','".
$this->escape_string($gal->name)."','".
$this->escape_string($gal->artist)."','".
$this->escape_string($gal->email)."','".
$this->escape_string($gal->copyright)."','".
$this->escape_string($gal->desc)."','".
$this->escape_string($gal->summary)."','".
$this->escape_string($gal->date)."',".
$gal->hits.",".$gal->lasthit.")");
//delete all image info
$success &= (bool) $this->query("DELETE FROM ".$this->config->sql_prefix."images ".
"WHERE galleryid='".$this->escape_string($gal->id)."' AND lang='".$language."'");
for($i=0;$i<count($gal->images);$i++) {
$success &= (bool) $this->query("INSERT INTO ".$this->config->sql_prefix."images ".
"(galleryid,lang,filename,owner,groups,permissions,categories,name,artist,".
"email,copyright,description,location,date,camera,lens,film,darkroom,digital,".
"width,height,type,hits,lasthit) VALUES ('".
$this->escape_string($gal->id)."','".$language."','".
$this->escape_string($gal->images[$i]->id)."','".
$gal->images[$i]->owner."','".$gal->images[$i]->groups."',".
$gal->images[$i]->permissions.",'".
$this->escape_string($gal->images[$i]->categories)."','".
$this->escape_string($gal->images[$i]->name)."','".
$this->escape_string($gal->images[$i]->artist)."','".
$this->escape_string($gal->images[$i]->email)."','".
$this->escape_string($gal->images[$i]->copyright)."','".
$this->escape_string($gal->images[$i]->desc)."','".
$this->escape_string($gal->images[$i]->location)."','".
$this->escape_string($gal->images[$i]->date)."','".
$this->escape_string($gal->images[$i]->camera)."','".
$this->escape_string($gal->images[$i]->lens)."','".
$this->escape_string($gal->images[$i]->film)."','".
$this->escape_string($gal->images[$i]->darkroom)."','".
$this->escape_string($gal->images[$i]->digital)."',".
$gal->images[$i]->width.",".$gal->images[$i]->height.",".
$gal->images[$i]->type.",".$gal->images[$i]->hits.",".
$gal->images[$i]->lasthit.")");
}
return $success;
}
/**
* Hits are loaded by getGallery so this method does nothing
* @param sgGallery gallery object to load hits into
*/
function getHits(&$gal) {
return true;
}
/**
* Stores gallery hits.
* @param sgGallery gallery object to store
*/
function putHits($gal) {
//if gallery data doesn't exist in database, add it
$res = $this->query("SELECT id FROM ".$this->config->sql_prefix."galleries ".
"WHERE id='".$this->escape_string($gal->id)."'");
if(!$res || !$this->num_rows($res))
$this->putGallery($gal);
$success = (bool) $this->query("UPDATE ".$this->config->sql_prefix."galleries ".
"SET hits=".$gal->hits.", lasthit=".$gal->lasthit." ".
"WHERE id='".$this->escape_string($gal->id)."'");
foreach($gal->images as $img)
$success &= (bool) $this->query("UPDATE ".$this->config->sql_prefix."images ".
"SET hits=".$img->hits.", lasthit=".$img->lasthit." ".
"WHERE galleryid='".$this->escape_string($gal->id)."' ".
"AND filename='".$this->escape_string($img->id)."'");
return $success;
}
/**
* Fetches all registered users.
*/
function getUsers() {
$res = $this->query("SELECT * FROM ".$this->config->sql_prefix."users");
for($i=0;$i<$this->num_rows($res);$i++) {
$usrinfo = $this->fetch_array($res);
$users[$i] = new sgUser($usrinfo['username'],$usrinfo['userpass']);
$users[$i]->permissions = $usrinfo['permissions'];
$users[$i]->groups = $usrinfo['groups'];
$users[$i]->email = $usrinfo['email'];
$users[$i]->fullname = $usrinfo['fullname'];
$users[$i]->description = $usrinfo['description'];
$users[$i]->stats = $usrinfo['stats'];
}
return $users;
}
/**
* Stores all registered users.
* @param array an array of sgUser objects representing the users to store
*/
function putUsers($users) {
//empty table
$success = (bool) $this->query("DELETE FROM ".$this->config->sql_prefix."users");
for($i=0;$i<count($users);$i++)
$success &= (bool) $this->query("INSERT INTO ".$this->config->sql_prefix."users ".
"(username,userpass,permissions,groups,email,fullname,description,stats) VALUES ('".
$this->escape_string($users[$i]->username)."','".
$users[$i]->userpass."',".$users[$i]->permissions.",'".
$this->escape_string($users[$i]->groups)."','".
$this->escape_string($users[$i]->email)."','".
$this->escape_string($users[$i]->fullname)."','".
$this->escape_string($users[$i]->description)."','".
$this->escape_string($users[$i]->stats)."')");
return $success;
}
}
 
?>
/photogallery/includes/item.class.php
0,0 → 1,297
<?php
 
/**
* Singapore gallery item class.
*
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2005-6 Tamlyn Rhodes
* @version $Id: item.class.php,v 1.10 2006/09/08 15:29:22 tamlyn Exp $
*/
 
//permissions bit flags
define("SG_GRP_READ", 1);
define("SG_GRP_EDIT", 2);
define("SG_GRP_ADD", 4);
define("SG_GRP_DELETE", 8);
define("SG_WLD_READ", 16);
define("SG_WLD_EDIT", 32);
define("SG_WLD_ADD", 64);
define("SG_WLD_DELETE", 128);
define("SG_IHR_READ", 17);
define("SG_IHR_EDIT", 34);
define("SG_IHR_ADD", 68);
define("SG_IHR_DELETE", 136);
 
/**
* Abstract class from which sgImage and sgGallery are derived.
*
* @abstract
* @package singapore
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @copyright (c)2005-6 Tamlyn Rhodes
*/
class sgItem
{
/**
* The id of the item. In the case of galleries this is the path to the
* gallery from root and must be unique. For images it is the image file
* name (or URL for remote images).
* @var string
*/
var $id;
/**
* Username of the user to which the item belongs
* @var string
*/
var $owner = "__nobody__";
/**
* Space-separated list of groups to which the item belongs
* @var string
*/
var $groups = "";
/**
* Bit-field of permissions
* Default is to inherit everything.
* @var int
*/
var $permissions = 255;
/**
* Space-separated list of categories to which the item belongs (not used)
* @var string
*/
var $categories = "";
/**
* The name or title of the item
* @var string
*/
var $name = "";
/**
* The name of the original item creator (or anyone else)
* @var string
*/
var $artist = "";
/**
* Email of the original item creator (or anyone else)
* @var string
*/
var $email = "";
/**
* Optional copyright information
* @var string
*/
var $copyright = "";
/**
* Multiline description of the item
* @var string
*/
var $desc = "";
/**
* Date associated with item
* @var string
*/
var $date = "";
var $location = "";
/**
* Number of times item has been viewed
* @var int
*/
var $hits = 0;
/**
* Unix timestamp of last time item was viewed
* @var int
*/
var $lasthit = 0;
/**
* Pointer to the parent sgItem
* @var sgItem
*/
var $parent;
/**
* Reference to the current config object
* @var sgConfig
*/
var $config;
/**
* Reference to the current translator object
* @var Translator
*/
var $translator;
/**
* Array in which the various sized thumbnails representing this item are stored
* @var array
*/
var $thumbnails = array();
/** Accessor methods */
function name() { return $this->name; }
function artist() { return $this->artist; }
function date() { return $this->date; }
function location() { return $this->location; }
function description() { return $this->desc; }
function canEdit() { return false; }
function idEntities() { return htmlspecialchars($this->id); }
/**
* Removes script-generated HTML (BRs and URLs) but leaves any other HTML
* @return string the description of the item
*/
function descriptionStripped()
{
$ret = str_replace("<br />","\n",$this->description());
if($this->config->enable_clickable_urls) {
//strip off html from autodetected URLs
$ret = preg_replace('{<a href="('.SG_REGEXP_PROTOCOLURL.')\">\1</a>}', '\1', $ret);
$ret = preg_replace('{<a href="http://('.SG_REGEXP_WWWURL.')">\1</a>}', '\1', $ret);
$ret = preg_replace('{<a href="mailto:('.SG_REGEXP_EMAILURL.')">\1</a>}', '\1', $ret);
}
return $ret;
}
/**
* If the current item has an artist specified, returns " by " followed
* by the artist's name. Otherwise returns an empty string.
* @return string
*/
function byArtistText()
{
if(empty($this->artist))
return "";
else
return " ".$this->translator->_g("artist name|by %s",$this->artist);
}
/**
* Obfuscates the given email address by replacing "." with "dot" and "@" with "at"
* @param boolean override the obfuscate_email config setting (optional)
* @return string obfuscated email address or HTML mailto link
*/
function emailLink($forceObfuscate = false)
{
if($this->config->obfuscate_email || $forceObfuscate)
return strtr($this->email,array("@" => ' <b>'.$this->translator->_g("email|at").'</b> ', "." => ' <b>'.$this->translator->_g("email|dot").'</b> '));
else
return "<a href=\"mailto:".$this->email."\">".$this->email."</a>";
}
 
function nameLink($action = null)
{
return '<a href="'.$this->URL(0, $action).'">'.$this->nameForce().'</a>';
}
function parentURL($action = null)
{
$perpage = $this->parent->isAlbum() ? $this->config->thumb_number_album : $this->config->thumb_number_gallery;
return $this->parent->URL(floor($this->index() / $perpage) * $perpage, $action);
}
function parentLink($action = null)
{
return '<a href="'.$this->parentURL($action).'">'.$this->parentText().'</a>';
}
function parentText()
{
return $this->translator->_g("gallery|Up");
}
/**
* @return array associative array of item properties in the form "name" => "value"
*/
function detailsArray()
{
$ret = array();
//generic properties
if(!empty($this->date)) $ret[$this->translator->_g("Date")] = $this->date;
if(!empty($this->location)) $ret[$this->translator->_g("Location")] = $this->location;
if(!empty($this->desc)) $ret[$this->translator->_g("Description")] = $this->desc;
if(!empty($this->email)) $ret[$this->translator->_g("Email")] = $this->emailLink();
//image properties
if(!empty($this->camera)) $ret[$this->translator->_g("Camera")] = $this->camera;
if(!empty($this->lens)) $ret[$this->translator->_g("Lens")] = $this->lens;
if(!empty($this->film)) $ret[$this->translator->_g("Film")] = $this->film;
if(!empty($this->darkroom)) $ret[$this->translator->_g("Darkroom manipulation")] = $this->darkroom;
if(!empty($this->digital)) $ret[$this->translator->_g("Digital manipulation")] = $this->digital;
//special properties
if(!empty($this->copyright)) $ret[$this->translator->_g("Copyright")] = $this->copyright;
elseif(!empty($this->artist))$ret[$this->translator->_g("Copyright")] = $this->artist;
if($this->config->show_views)
$ret[$this->translator->_g("Viewed")] = $this->translator->_ng("viewed|%s time", "viewed|%s times",$this->hits);
return $ret;
}
function isAlbum() { return false; }
function isGallery() { return false; }
function isImage() { return false; }
 
/**
* Returns a link to the image or gallery with the correct formatting and path
*
* @param int page offset (optional)
* @param string action to perform (optional)
* @return string formatted URL
*/
function URL($startat = null, $action = null)
{
$query = array();
if($this->config->use_mod_rewrite) { //format url for use with mod_rewrite
$ret = $this->config->base_url;
$ret .= $this->isImage() ? $this->parent->idEncoded() : $this->idEncoded();
if($startat) $ret .= ','.$startat;
$ret .= '/';
if($this->isImage()) $ret .= $this->idEncoded();
if($action) $query[] = $this->config->url_action."=".$action;
if($this->translator->language != $this->config->default_language) $query[] = $this->config->url_lang.'='.$this->translator->language;
if($GLOBALS["sg"]->template != $this->config->default_template) $query[] = $this->config->url_template.'='.$GLOBALS["sg"]->template;
if(!empty($query))
$ret .= '?'.implode(ini_get('arg_separator.output'), $query);
} else { //format plain url
$query[] = $this->config->url_gallery."=".($this->isImage() ? $this->parent->idEncoded() : $this->idEncoded());
if($this->isImage()) $query[] = $this->config->url_image."=".$this->idEncoded();
if($startat) $query[] = $this->config->url_startat."=".$startat;
if($action) $query[] = $this->config->url_action."=".$action;
if($this->translator->language != $this->config->default_language)
$query[] = $this->config->url_lang.'='.$this->translator->language;
if(isset($GLOBALS["sg"]->template) && $GLOBALS["sg"]->template != $this->config->default_template)
$query[] = $this->config->url_template.'='.$GLOBALS["sg"]->template;
$ret = $this->config->index_file_url.implode(ini_get('arg_separator.output'), $query);
}
return $ret;
}
}
 
 
?>
/photogallery/includes/singapore.class.php
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()." &lt; ";
$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()." &gt;\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));
}
}
 
 
?>
/photogallery/includes/thumbnail.class.php
0,0 → 1,228
<?php
 
/**
* Thumbnail class.
*
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003-2005 Tamlyn Rhodes
* @version $Id: thumbnail.class.php,v 1.13 2006/06/24 20:33:00 tamlyn Exp $
*/
 
 
/**
* Creates and manages image thumbnails
* @package singapore
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @copyright (c)2003-2005 Tamlyn Rhodes
*/
class sgThumbnail
{
var $config;
var $maxWidth = 0;
var $maxHeight = 0;
var $thumbWidth = 0;
var $thumbHeight = 0;
var $cropWidth = 0;
var $cropHeight = 0;
var $forceSize = false;
var $imagePath = "";
var $thumbPath = "";
function sgThumbnail(&$img, $type)
{
$this->config =& sgConfig::getInstance();
$this->image =& $img;
$widthVar = "thumb_width_".$type;
$heightVar = "thumb_height_".$type;
$cropVar = "thumb_crop_".$type;
$this->maxWidth = $this->config->$widthVar;
$this->maxHeight = $this->config->$heightVar;
if(isset($this->config->$cropVar))
$this->forceSize = $this->config->$cropVar;
if($this->image == null) return;
$this->imagePath = $this->image->realPath();
$this->thumbPath = $this->config->base_path.Singapore::thumbnailPath($this->image->parent->id, $this->image->id, $this->maxWidth, $this->maxHeight, $this->forceSize);
$this->thumbURL = $this->config->base_url .Singapore::thumbnailPath($this->image->parent->id, $this->image->id, $this->maxWidth, $this->maxHeight, $this->forceSize);
 
//security check: make sure requested file is in galleries directory
if(!Singapore::isSubPath($this->config->base_path.$this->config->pathto_galleries, $this->imagePath) && !$this->image->isRemote())
return;
//security check: make sure $image has a valid extension
if(!$this->image->isRemote() && !preg_match("/.+\.(".$this->config->recognised_extensions.")$/i",$this->image->id))
return;
$this->calculateDimensions();
//link straight to image if it smaller than required size
if($this->image->width <= $this->thumbWidth && $this->image->height <= $this->thumbHeight) {
$this->thumbURL = $this->image->realURL();
return;
}
$imageModified = @filemtime($this->imagePath);
$thumbModified = @filemtime($this->thumbPath);
if($imageModified > $thumbModified || !$thumbModified)
$this->buildThumbnail();
}
/** Accessor methods */
function width() { return $this->thumbWidth; }
function height() { return $this->thumbHeight; }
function URL() { return $this->thumbURL; }
/** Private methods */
/**
* Calculates thumbnail dimensions.
*/
function calculateDimensions()
{
//if aspect ratio is to be constrained set crop size
if($this->forceSize) {
$newAspect = $this->maxWidth/$this->maxHeight;
$oldAspect = $this->image->realWidth()/$this->image->realHeight();
if($newAspect > $oldAspect) {
$this->cropWidth = $this->image->realWidth();
$this->cropHeight = round($this->image->realHeight()*($oldAspect/$newAspect));
} else {
$this->cropWidth = round($this->image->realWidth()*($newAspect/$oldAspect));
$this->cropHeight = $this->image->realHeight();
}
//else crop size is image size
} else {
$this->cropWidth = $this->image->realWidth();
$this->cropHeight = $this->image->realHeight();
}
if($this->cropHeight > $this->maxHeight && ($this->cropWidth <= $this->maxWidth
|| ($this->cropWidth > $this->maxWidth && round($this->cropHeight/$this->cropWidth * $this->maxWidth) > $this->maxHeight))) {
$this->thumbWidth = round($this->cropWidth/$this->cropHeight * $this->maxHeight);
$this->thumbHeight = $this->maxHeight;
} elseif($this->cropWidth > $this->maxWidth) {
$this->thumbWidth = $this->maxWidth;
$this->thumbHeight = round($this->cropHeight/$this->cropWidth * $this->maxWidth);
} else {
$this->thumbWidth = $this->image->realWidth();
$this->thumbHeight = $this->image->realHeight();
}
}
function buildThumbnail() {
//set cropping offset
$cropX = floor(($this->image->width-$this->cropWidth)/2);
$cropY = floor(($this->image->height-$this->cropHeight)/2);
//check thumbs directory exists and create it if not
if(!file_exists(dirname($this->thumbPath)))
Singapore::mkdir(dirname($this->thumbPath));
//if file is remote then copy locally first
if($this->image->isRemote()) {
$ip = @fopen($this->imagePath, "rb");
$tp = @fopen($this->thumbPath, "wb");
if($ip && $tp) {
while(fwrite($tp,fread($ip, 4095)));
fclose($tp);
fclose($ip);
$this->imagePath = $this->thumbPath;
}
}
switch($this->config->thumbnail_software) {
case "im" : //use ImageMagick v5.x
$cmd = '"'.$this->config->pathto_convert.'"';
if($this->forceSize) $cmd .= " -crop {$this->cropWidth}x{$this->cropHeight}+{$this->cropX}+{$this->cropY}";
$cmd .= " -geometry {$this->thumbWidth}x{$this->thumbHeight}";
if($this->image->type == 2) $cmd .= " -quality ".$this->config->thumbnail_quality;
if($this->config->progressive_thumbs) $cmd .= " -interlace Plane";
if($this->config->remove_jpeg_profile) $cmd .= ' +profile "*"';
$cmd .= ' '.escapeshellarg($this->imagePath).' '.escapeshellarg($this->thumbPath);
exec($cmd);
break;
case "im6" : //use ImageMagick v6.x
$cmd = '"'.$this->config->pathto_convert.'"';
$cmd .= ' '.escapeshellarg($this->imagePath);
if($this->config->progressive_thumbs) $cmd .= " -interlace Plane";
if($this->image->type == 2) $cmd .= " -quality ".$this->config->thumbnail_quality;
if($this->forceSize) $cmd .= " -crop {$this->cropWidth}x{$this->cropHeight}+{$this->cropX}+{$this->cropY}";
$cmd .= " -resize {$this->thumbWidth}x{$this->thumbHeight}";
if($this->config->remove_jpeg_profile) $cmd .= ' +profile "*"';
$cmd .= ' '.escapeshellarg($this->thumbPath);
exec($cmd);
break;
case "gd2" :
case "gd1" :
default : //use GD by default
//read in image as appropriate type
switch($this->image->type) {
case 1 : $image = ImageCreateFromGIF($this->imagePath); break;
case 3 : $image = ImageCreateFromPNG($this->imagePath); break;
case 2 :
default: $image = ImageCreateFromJPEG($this->imagePath); break;
}
if($image) {
switch($this->config->thumbnail_software) {
case "gd2" :
//create blank truecolor image
$thumb = ImageCreateTrueColor($this->thumbWidth,$this->thumbHeight);
//resize image with resampling
ImageCopyResampled(
$thumb, $image,
0, 0, $cropX, $cropY,
$this->thumbWidth, $this->thumbHeight, $this->cropWidth, $this->cropHeight);
break;
case "gd1" :
default :
//create blank 256 color image
$thumb = ImageCreate($this->thumbWidth,$this->thumbHeight);
//resize image
ImageCopyResized(
$thumb, $image,
0, 0, $cropX, $cropY,
$this->thumbWidth, $this->thumbHeight, $this->cropWidth, $this->cropHeight);
break;
}
} /*else {
$thumb = ImageCreate($this->thumbWidth, $this->thumbHeight);
$bg = ImageColorAllocate($thumb, 255, 255, 255);
$text = ImageColorAllocate($thumb, 255, 0, 0);
ImageString($thumb, 1, 0, 0, "Cannot load source image", $text);
}*/
//set image interlacing
@ImageInterlace($thumb, $this->config->progressive_thumbs);
//output image of appropriate type
switch($this->image->type) {
case 1 :
//GIF images are saved as PNG
case 3 :
ImagePNG($thumb, $this->thumbPath);
break;
case 2 :
default:
ImageJPEG($thumb, $this->thumbPath, $this->config->thumbnail_quality);
break;
}
@ImageDestroy($image);
@ImageDestroy($thumb);
}
//set file permissions on newly created thumbnail
@chmod($this->thumbPath, octdec($this->config->file_mode));
}
 
}
 
?>
/photogallery/includes/translator.class.php
0,0 → 1,160
<?php
 
/**
* Translation class.
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003-2005 Tamlyn Rhodes
* @version $Id: translator.class.php,v 1.5 2006/02/06 18:47:57 tamlyn Exp $
*/
/**
* Provides functions for translating strings using GNU Gettext PO files
* @package singapore
* @author Joel Sjögren <joel dot sjogren at nonea dot se>
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @copyright (c)2003, 2004 Tamlyn Rhodes
*/
class Translator
{
/**
* Array of language strings in the form
* "english string" => "foreign string"
* @private
* @var array
*/
var $languageStrings = array();
var $language = "en";
/**
* Constructor
* @param string language code
* @private
*/
function Translator($language)
{
$this->language = $language;
}
/**
* Implements a version of the Singleton design pattern by always returning
* a reference to the same Translator object for each language. If no
* language is specified then the first loaded Translator is returned.
* @param string language code (optional)
* @static
*/
function &getInstance($language = 0)
{
static $instances = array();
$key = empty($instances) ? 0 : $language;
if(!isset($instances[$key]))
//note that the new object is NOT assigned by reference as
//references are not stored in static variables (don't ask me...)
$instances[$key] = new Translator($language);
return $instances[$key];
}
/**
* Reads a language file and saves the strings in an array.
* Note that the language code is used in the filename for the
* datafile, and is case sensitive.
*
* @author Joel Sjögren <joel dot sjogren at nonea dot se>
* @param string file to load
* @return bool success
*/
function readLanguageFile($languageFile)
{
// Look for the language file
if(!file_exists($languageFile))
return false;
// Open the file
$fp = @fopen($languageFile, "r");
if (!$fp) return false;
// Read contents
$str = '';
while (!feof($fp)) $str .= fread($fp, 1024);
// Unserialize
$newStrings = @unserialize($str);
//Append new strings to current languageStrings array
$this->languageStrings = array_merge($this->languageStrings, $newStrings);
// Return successful
return (bool) $newStrings;
}
/**
* Returns a translated string, or the same if no language is chosen.
* You can pass more arguments to use for replacement within the
* string - just like sprintf(). It also removes anything before
* the first | in the text to translate. This is used to distinguish
* strings with different meanings, but with the same spelling.
* Examples:
* _g("Text");
* _g("Use a %s to drink %s", _g("glass"), "water");
*
* @author Joel Sjögren <joel dot sjogren at nonea dot se>
* @param string text to translate
* @return string translated string
*/
function _g ($text)
{
// String exists and is not empty?
if(!empty($this->languageStrings[$text])) {
$text = $this->languageStrings[$text];
} else {
$text = preg_replace("/^[^\|]*\|/", "", $text);
}
// More arguments were passed? sprintf() them...
if (func_num_args() > 1) {
$args = func_get_args();
array_shift($args);
//preg_match_all("/%((\d+\\\$)|.)/", str_replace("%%", "", $text), $m);
//while (count($args) < count($m[0])) $args[] = '';
$text = vsprintf($text, $args);
}
return $text;
}
/**
* Plural form of _g().
*
* @param string singular form of text to translate
* @param string plural form of text to translate
* @param string number
* @return string translated string
*/
function _ng ($msgid1, $msgid2, $n)
{
//calculate which plural to use
if(!empty($this->languageStrings[0]["plural"]))
eval($this->languageStrings[0]["plural"]);
else
$plural = $n==1?0:1;
// String exists and is not empty?
if (!empty($this->languageStrings[$msgid1][$plural])) {
$text = $this->languageStrings[$msgid1][$plural];
} else {
$text = preg_replace("/^[^\|]*\|/", "", ($n == 1 ? $msgid1 : $msgid2));
}
if (func_num_args() > 3) {
$args = func_get_args();
array_shift($args);
array_shift($args);
return vsprintf($text, $args);
}
return sprintf($text, $n);
}
}
 
?>
/photogallery/includes/user.class.php
0,0 → 1,121
<?php
 
/**
* User class.
*
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003, 2004 Tamlyn Rhodes
* @version $Id: user.class.php,v 1.5 2006/03/14 19:38:54 tamlyn Exp $
*/
 
/**
* Class used to represent a user.
* @package singapore
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @copyright (c)2003, 2004 Tamlyn Rhodes
*/
class sgUser
{
/**
* Username of user. Special cases are 'guest' and 'admin'.
* @var string
*/
var $username = "";
 
/**
* MD5 hash of password
* @var string
*/
var $userpass = "5f4dcc3b5aa765d61d8327deb882cf99";
/**
* Bit-field of permissions
* @var int
*/
var $permissions = 0;
/**
* Space-separated list of groups of which the user is a member
* @var string
*/
var $groups = "";
/**
* Email address of user
* @var string
*/
var $email = "";
/**
* The name or title of the user
* @var string
*/
var $fullname = "";
/**
*Description of user account
* @var string
*/
var $description = "";
/**
* Statistics (what's this? I don't know!)
* @var string
*/
var $stats = "";
/**
* Constructor ensures username and userpass have values
*/
function sgUser($username, $userpass)
{
$this->username = $username;
$this->userpass = $userpass;
}
/**
* Checks if currently logged in user is an administrator.
*
* @return bool true on success; false otherwise
*/
function isAdmin()
{
return $this->permissions & SG_ADMIN;
}
/**
* Checks if currently logged in user is a guest.
*
* @return bool true on success; false otherwise
*/
function isGuest()
{
return $this->username == "guest";
}
/**
* Checks if this user is the owner of the specified item.
*
* @param sgItem the item to check
* @return bool true if this user is the owner; false otherwise
*/
function isOwner($item)
{
return $item->owner == $this->username;
}
/**
* Checks if this user is a member of the group(s) supplied
*
* @return bool true on success; false otherwise
*/
function isInGroup($groups)
{
return (bool) array_intersect(explode(" ",$groups),explode(" ",$this->groups));
}
}
 
?>
/photogallery/docs/Advanced.html
0,0 → 1,200
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>singapore - Advanced features</title>
<link rel="stylesheet" type="text/css" href="docstyle.css" />
</head>
 
<body>
 
 
<h1>singapore - Advanced features</h1>
 
<ul>
<li><a href="#iifn">Info in filename</a></li>
<li><a href="#override">Overriding settings</a></li>
<li><a href="#hiding">Hiding galleries</a></li>
<li><a href="#modrewrite">Using Apache mod_rewrite</a></li>
<li><a href="#including">Including singapore into another page</a></li>
<li><a href="#popup">Opening images in a popup</a></li>
<li><a href="Readme.html">General readme</a></li>
<li><a href="Development.html">Developer documentation</a></li>
<li><a href="Translation.html">Translating singapore</a></li>
</ul>
 
<h2><a name="iifn">Info in file name</a></h2>
 
<p>If singapore doesn't find a metadata file in a gallery it will try to
extract some sensible information from the image file and directory names as
follows:</p>
 
<p>Underscores (_) are converted to spaces and the file extension is discarded
by removing all characters after the last . (dot) in the filename. If a filename or
directory name contains the sequence '<code>_-_</code>' (underscore hyphen underscore)
or '<code> - </code>' (space hyphen space) then the name will be split on this
separator. The first half will be interpreted as the artist name and the second
half will be interpreted as the gallery or image name depending on context. If
a separator is not found then the file or directory name is interpreted as the
image or gallery name, respectively.</p>
 
<p>For example <code>Holiday_Snaps/Bob_Fenderson_-_Pretty_picture_of_Sunset.jpg</code>
will be translated into an image called "Pretty picture of Sunset" by "Bob
Fenderson" in a gallery called "Holiday Snaps".</p>
 
 
<h2><a name="override">Overriding settings</a></h2>
 
<p>All configuration options may be overridden on a per-gallery and/or
per-template basis. This means that a particular gallery may use, for example,
a different template or language to the rest of the site. Also, templates may
introduce their own configuration settings if they so wish.</p>
 
<p>Gallery config options are stored in files named <code>gallery.ini</code> in
the chosen gallery directory. Settings are not inherited by subgalleries; they
affect only the current gallery and its images.</p>
 
<p>Template config options are stored in files named <code>template.ini</code>
in the chosen template directory. Some of these settings are not present in the
default config file; they are only found in the template config file.</p>
 
<p>Settings are loaded in this order: default settings (<code>singapore.ini</code>)
&gt; gallery settings (<code>gallery.ini</code>) &gt; template settings
(<code>template.ini</code>). This may be changed in the future to allow gallery
settings to override template settings.</p>
 
<p>Note that there is no restriction on which options may be overridden.
Overriding some settings may lead to unpredictable operation (e.g. changing
<code>pathto_galleries</code> in <code>gallery.ini</code>).</p>
 
 
<h2><a name="hiding">Hiding galleries</a></h2>
 
<p>Any gallery (except the root gallery) may be hidden from the listing view
by prefixing the directory name with a dot (<code>.</code>). However it is still
accessible by using its exact URL. For example consider the following directory
structure:</p>
 
<pre>
galleries/
|- my_pretty_pictures/
| |- trees/
| `- flowers/
|- .a_hidden_gallery/
| |- some_embarrassing_pictures/
| `- .this_is_also_hidden/
`- some_other_things/
</pre>
 
<p>A user browsing the root gallery (e.g. <code>www.example.com/?gallery=.</code>)
will see <code>my_pretty_pictures</code> and <code>some_other_things</code>;
<code>.a_hidden_gallery</code> and all its contents will be hidden from view. If,
however, the user is supplied with the exact URL (e.g. <code>www.example.com/?gallery=./.a_hidden_gallery</code>)
they will be able to see the contents as usual (in this case only
<code>some_embarrassing_pictures</code> because <code>.this_is_also_hidden</code>
is hidden as above).</p>
 
<p>Since a user could guess the exact URL or discover it by some other means,
this feature is not to be used for concealing sensitive information.</p>
 
<p>NOTE: see the <a href="#modrewrite">mod_rewrite</a> section for instructions
on renaming files starting with a . on Windows.</a></p>
 
 
<h2><a name="modrewrite">Using Apache mod_rewrite</a></h2>
 
<p>Firstly you need to ensure that mod_rewrite is available. You must be running
<a href="http://httpd.apache.org/">Apache</a>, have mod-rewrite installed and
enabled and furthermore be allowed to override Apache configuration directives
on a per-directory basis with the use of .htaccess files.</p>
 
<p>If you don't know the answer to the above then probably the easiest way to
find out is to try the following instructions.</p>
 
<p>First copy <code>tools/mod_rewrite.htaccess</code> to the singapore base
directory and rename it to simply <code>.htaccess</code>. Note: Windows shines
here as a Totally Idiotic Operating System&reg; as it will not let you type
filenames starting with a . kindly saying "You must type a filename". The only
way that I know of to get around this totally pointless message is to drop into
the command line and use <code>ren</code> to rename it. Aaaaaaaarrrrgggghhhh!</p>
 
<p>Moving swiftly on...</p>
 
<p>You now need to edit singapore.ini and turn on <code>use_mod_rerwite</code>.
You also need to specify the <code>base_url</code> option. Set this to the full
web absolute path to your installation (e.g. the bit after the .com, .org or
whatever). For example if your gallery is accessed by typing
www.example.com/singapore/ then the <code>base_url</code> is
<code>/singapore/</code>.</p>
 
<p>Lastly you need to edit the .htaccess file. On each of the two lines starting
<code>RewriteRule</code>, about half way along the line there is a
<code>/singapore/</code>. Change this to whatever you put as the <code>base_url</code>
above.</p>
 
<h3>If it doesn't work</h3>
 
<p>If you get <em>404 File Not Found</em> errors then either mod_rewrite or .htaccess
files are not enabled. If you get singapore <em>Gallery not found</em> errors
then there might be a problem with the rewrite rules. If you get unstyled
singapore pages with no images then then your base_path is probably wrong. If do
get images but the pages are still unstyled then your template probably needs
adapting to use the base_url config option. See the default template for an
example. If you still can't work out what's wrong then just give up :P</p>
 
<h2><a name="including">Including singapore into another page</a></h2>
 
<p>Since v0.9.10 it has been possible to include singapore into your web design
using external.php. Just place this code where you want singapore to appear:
<code>&lt;?php include("path/to/singapore/external.php");?&gt;</code> (supplying
the correct relative or absolute path to singapore instead of
'/path/to/singapore'). There are, however, a few things that need to be noted:</p>
 
<ul>
<li>You will almost certainly need to edit your chosen template in order that
the HTML generated is still valid. For example you do not want two &lt;html&gt;
start tags, two &lt;head&gt; sections etc. Alternatively you can use the
<em>external</em> template (available to download from the website) which is
the default template with the unnecessary (X)HTML removed.</li>
<li>If the file into which you are including singapore is named something
other than index.php or it requires additional GET variables (such as page etc.)
then you will need to change index_file_url to reflect this. For example if
the page you are including singapore into is <code>site.php?page=gallery</code>
you will need to change index_file_url to <code>site.php?page=gallery&amp;amp;</code></li>
<li>If you want to keep both the included singapore installation and the
original simultaneously functional then you can place a file named
<code>singapore.local.ini</code> in the same directory as the including file.
If found, this file will be loaded after singapore.ini but before gallery.ini
and template.ini. It can thus be used to provide local settings such as index_file_url
mentioned above. Note that base_file and base_url are automatically calculated
and should not need to be specified.</li>
<li>If there is any content on the including page <em>before</em> external.php is
included then singapore will not be able to send any headers which will
prevent you from using languages with non-default character sets. The
recommended solution is to turn on output buffering before any content is
output and do not flush it until after external.php is included. Essentially
a call to <code>ob_start()</code> at the beginning of the including file is
all that is needed. <a href="http://uk.php.net/manual/en/ref.outcontrol.php">About
output control</a>.</li>
<li>Currently mod_rewrite doesn't work with such included installations of singapore.</li>
</ul>
 
<h2><a name="popup">Opening images in a popup</a></h2>
 
<p>Firstly I must say how much I disapprove of popups. If someone wants to open
something in a new window THEY WILL DO IT THEMSELVES! Why do you think so many
people have popup blockers? POPUPS ARE BAD! However I have been asked how to
make singapore open images in popup windows so often that I finally yielded and
wrote a little bit of JavaScript to do it neatly.</p>
 
<p>Open album.tpl.php in the directory of your current template (e.g.
templates/default/album.tpl.php) and replace <code>$sg-&gt;gallery-&gt;images[$index]-&gt;thumbnailLink()</code>
with <code>$sg-&gt;gallery-&gt;images[$index]-&gt;thumbnailPopupLink()</code>. But don't do it. It's bad.<p>
 
<p>Evil I tell you...</p>
 
<p><em>$Date: 2006/08/06 13:50:20 $</em></p>
 
</body>
</html>
/photogallery/docs/Development.html
0,0 → 1,114
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>singapore - Development</title>
<link rel="stylesheet" type="text/css" href="docstyle.css" />
</head>
 
<body>
 
<h1>singapore - Development</h1>
 
<p>The information in this file is for people who wish to contribute to
singapore, modify it or understand how it works.</p>
 
<ul>
<li><a href="#csvformat">CSV database format</a></li>
<li><a href="Readme.html">General readme</a></li>
<li><a href="Advanced.html">Advanced features</a></li>
<li><a href="Translation.html">Translating singapore</a></li>
</ul>
 
<h2><a name="csvformat">CSV database format</a></h2>
 
<p>If you choose to use metadata files then each gallery must
contain a CSV (comma separated values) file called metadata.csv
containing the information about images in the gallery and the gallery itself.
CSV files can be edited manually (in a text editor such as Notepad)
or using a spreadsheet application (such as MS Excel). Care must be taken when using
Excel to save using commas as the separator character and not tabs or semi-colons.</p>
 
<p>The first line of each file stores human-readable descriptions of the fields
and is ignored by singapore. The second line stores information about this
gallery:</p>
 
<pre>
field 0
the filename of the image used to represent the gallery in the gallery list
field 1
(not used)
field 2
the owner of the gallery
field 3
space-separated list of usergroups
field 4
gallery permission flags
field 5
space-separated list of categories the gallery belongs in (not used)
field 6
gallery name/title
field 7
artist name (optional)
field 8
artist email (optional)
field 9
copyright holder (optional)
field 10
description of the gallery (optional)
field 11
short summary of the gallery (optional)
field 12
human-readable date (optional)
field 13 onwards
(not used)
</pre>
 
<p>Each of the following lines (3 - ...) represents an image in the gallery.
The format is as follows:</p>
 
<pre>
field 0
the filename of the image
field 1
the filename of the thumbnail image
field 2
the owner of the image
field 3
space-separated list of usergroups
field 4
image permission flags
field 5
space-separated list of categories the image belongs in (not used)
field 6
image name/title
field 7
artist name (optional)
field 8
artist email (optional)
field 9
copyright holder (optional)
field 10
description of the image (optional)
field 11
location that the image was taken/made/represents (optional)
field 12
date taken/made (optional)
field 13
make and model of camera used (optional)
field 14
make and model of lens used (optional)
field 15
make and type of film used (optional)
field 16
darkroom manipulation (optional)
field 17
digital manipulation (optional)
</pre>
 
<p><em>$Date: 2004/10/15 18:53:36 $</em></p>
 
</body>
</html>
/photogallery/docs/License.txt
0,0 → 1,340
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
 
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
 
Preamble
 
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
 
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
 
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
 
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
 
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
 
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
 
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
 
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
 
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
 
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
 
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
 
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
 
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
 
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
 
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
 
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
 
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
 
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
 
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
 
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
 
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
 
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
 
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
 
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
 
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
 
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
 
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
 
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
 
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
 
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
 
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
 
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
 
NO WARRANTY
 
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
 
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
 
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
 
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
 
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
 
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
 
Also add information on how to contact you by electronic and paper mail.
 
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
 
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
 
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
 
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
 
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
 
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
 
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
/photogallery/docs/Readme.html
0,0 → 1,599
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>singapore - Readme</title>
<link rel="stylesheet" type="text/css" href="docstyle.css" />
</head>
 
<body>
 
 
<h1>singapore v0.10.1 - Readme</h1>
 
<ul>
<li><a href="#release">Release notes</a></li>
<li><a href="#history">Version history</a></li>
<li><a href="#license">License information</a></li>
<li><a href="#install">Installation</a></li>
<li><a href="#upgrade">Upgrading</a></li>
<li><a href="#managing">Gallery management</a></li>
<li><a href="#permissions">Help with file permissions</a></li>
<li><a href="#adminpermissions">The deal with admin permissions</a></li>
<li><a href="#users">Managing users</a></li>
<li><a href="#nomenclature">Naming of parts (glossary)</a></li>
<li><a href="Advanced.html">Advanced features</a></li>
<li><a href="Development.html">Developer documentation</a></li>
<li><a href="Translation.html">Translating singapore</a></li>
</ul>
 
 
<h2><a name="license">Licensing information</a></h2>
 
<pre>
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* <a href="http://www.sgal.org/">singapore</a> - Copyright 2002-6 Tamlyn Rhodes &lt;tam@zenology.co.uk&gt; *
* *
* singapore is free software; you can redistribute it and/or modify *
* it under the terms of the <a href="License.txt">GNU General Public License</a> as published *
* by the Free Software Foundation; either version 2 of the License, *
* or (at your option) any later version. *
* *
* singapore is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty *
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this; if not, write to the Free Software Foundation, *
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
</pre>
 
<p>You are kindly requested to display a link such as the following on all
pages generated by singapore. However in cases where this is not desirable,
a project donation of 20USD is considered a suitable alternative.</p>
 
<p class="boxed">Powered by <a href="http://www.sgal.org/">singapore</a></p>
 
 
<h2><a name="release">Release notes</a></h2>
 
<p>This is a recommended update as it addresses a critical bug in the
template handling that could allow an attacker to view the contents of system
files on the web server. Several other less severe bugs have been fixed
including acces control settings inheritance in the admin which should now
work correctly. The latest version of the 'modern' template is also included.</p>
 
 
<h2><a name="install">Installation</a></h2>
 
<ol>
<li>Extract all the files in the archive, conserving the directory hierarchy.</li>
<li>If you wish to change any path settings or use one of the SQL backends,
make the necessary changes to <code>singapore.ini</code>. If you don't know
why you might want to do this then you don't need to do it.</li>
 
<li>Upload everything to your web server.</li>
<li>Set file permissions. The directories that need to be made writable are:
<ul>
<li><code>data/</code> and all subdirectories and files</li>
<li><code>galleries/</code> and all subdirectories and files</li>
</ul>
<a href="#permissions">Help with file permissions</a>.
</li>
<li>Point your browser to the <code>install/</code> directory and follow the instructions.</li>
<li>Delete the <code>install/</code> directory to prevent unauthorised access.</li>
<li>Log into the admin section and change the password. The username is
<code>admin</code> and the default password is <code>password</code>.</li>
<li>You're ready to roll! <a href="#managing">More info on how to roll...</a></li>
</ol>
 
<p>Optional but recommended:</p>
<ul>
<li>Have a browse through <code>singapore.ini</code> and look at the
available options. Each option has comments explaining its function. For most
purposes the default values will be fine but you may be able to tweak them
to your benefit. See also <a href="Advanced.html#override">overriding default
settings</a>.</li>
<li>Make your own header image (<code>templates/default/images/header.gif</code>)
with the name of your site.<br />
-or-<br />
Edit the default style sheet (<code>templates/default/main.css</code>)
to integrate it with your site.<br />
-or-<br />
Browse the pre-existing templates available for singapore on the
<a href="http://www.sgal.org/wiki/files/templates">templates</a> page.
-or-<br />
Create your own template by editing an existing one. There is currently no
documentation on this topic but anyone with a basic grasp of PHP should be
able to work it out. Visit the
<a href="http://www.sgal.org/forum/viewforum.php?id=2">templates forum</a>
for help and advice.</li>
</ul>
 
 
<h2><a name="upgrade">Upgrading</a></h2>
 
<p>Always back-up first!</p>
 
<p>A patch is also available for people wishing only to fix the security problem.</p>
 
<p>Upgrading is usually just a matter of unzipping the new version over the old.
Your galleries, images, metadata will not be affected but the
admin password will be reset and the root ini file (singapore.ini) will be
overwritten. The location of log files and thumbnail cache has changed in this
version. See the forum for
<a href="http://www.sgal.org/forum/viewtopic.php?id=1267">instructions on
copying your old logs over to their new location</a>.
You can keep your old users.csv.php file.
When new configuration options are added you will need to either add these
to your old singapore.ini or re-edit the new singapore.ini in order to keep your
personal settings. You may want to use a file difference utility such as
<a href="http://winmerge.sourceforge.net">WinMerge</a> to merge the differences.</p>
 
<p>The default templates will also be overwritten in an upgrade. For this reason
it is advisable to copy the default template to a new directory when making
customisations.</p>
 
 
<h2><a name="uninstall">Uninstallation</a></h2>
 
<p>Server generated content may be owned by the web server and it may therefore
not be possible to delete these files via ftp. Use the
<a href="../tools/cleanup.php">cleanup script</a> to make all server-generated
files world writable. This should allow you to delete them like any other file.</p>
 
 
<h2><a name="managing">Managing your galleries</a></h2>
 
<p>If using the <a href="Advanced.html#iifn">info in file name</a> system then
all management can be done
directly on the files using, for example, an ftp client. To create new galleries
simply create a new subdirectory of <code>galleries/</code>. To add, move or delete
images in a gallery simply add, move or delete the image files in the
appropriate directory.</p>
 
<p>If you use the admin mode to edit your galleries or images it will
automatically create the relevant metadata files. If these files are deleted
singapore will revert to using <em>info in file name</em>. The username is
<code>admin</code> and the default password is <code>password</code>.</p>
 
<p>Galleries may contain <em>either</em> images or further galleries. This
means that if you create one or more child galleries in a gallery that already
contains images, these images will be 'hidden'. Removing these child galleries
will make the images visible again. Galleries containing only images are called
albums.</p>
 
 
<h3>Bulk image uploading</h3>
 
<p class="note">NOTE: this feature is experimental. It works on some servers but
does not on others (including the sf.net servers) and I don't know why. It may
or may not work for you.</p>
 
<p>You may upload several images at the same time by first storing them in a
PKWARE compatible ZIP file. Most archiving utilities are able to produce such
files also sometimes referred to as <em>compressed folders</em> on Windows. You
need an unzipping utility on your server to use this feature. Most Linux/Unix
machines come with the free <em>unzip</em> utility by Info-Zip preinstalled but
precompiled binaries for nearly all operating systems ever conceived can be
found on the <a href="http://www.info-zip.org/">Info-Zip website</a>. <!--A Win32
version is also available here:
<a href="http://singapore.sourceforge.net/binaries/singapore-unzip-Win32.zip">http://singapore.sourceforge.net/binaries/singapore-unzip-Win32.zip</a>.-->
Simply place the executable in your PATH or in the singapore root directory.</p>
 
<p>Upload the archive using the 'new image' option in the singapore admin and
select 'Upload multiple files'</p>
 
<p>If the archive contains only images, these will be added to the current
gallery just as if they had been uploaded individually. If an archive contains
subdirectories, these will be copied into the current gallery. Any images in
the archive root directory will be imported as above. This mechanism
may be used to upload complete directory structures including metadata.csv
and gallery.ini files. If the archive root directory contains no images and a
single directory, singapore will navigate into this directory and proceed to
import the contents into the current gallery as though they were in the root
directory.</p>
 
<p>NOTE: There is a maximum size of file that PHP will allow you to upload.
This defaults to 2MB and cannot be changed by singapore. Consult the PHP manual
or you server's administrator for more information.</p>
 
<h2><a name="permissions">Help with file permissions</a></h2>
 
<p>How to make a file writable is dependent on your operating system and
web server setup and can seem quite daunting for a beginner. One option that
will work on nearly all Unix/Linux servers is to chmod the relevant
files/directories to 777 (consult your FTP software documentation for help on
using the chmod command). However this option is not considered very secure as
anyone who has write access the web server (such as the owners of other web
sites hosted on the same computer) can potentially write to or delete these
directories. There may be a better way to make your files writable by your
server but this is something you must take up with your server administrator.</p>
 
 
<h2><a name="adminpermissions">The deal with admin permissions</a></h2>
 
<p>First thing to point out is that singapore admin permissions are not related
to unix/windows filesystem permissions. If you get a "permission denied" message
from php about a certain file, that's the filesystem permissions discussed in a
<a href="#permissions">separate section</a>. For the purposes of this section an
'object' is anything that can have admin permissions associated with it; i.e. an
image or a gallery.</p>
 
<p>There are two types of users: administrators and users. Administrators can do
everything and are not bound by permission settings. Only administrators may
create and edit users and change ownership of objects. Ownership is set at the
time of creation of the object to the user creating the object. The owner of an
object may do anything to it except change the owner. Only the owner or an
administrator may alter the permissions of an object, including changing its
group(s).</p>
 
<p>There are four kinds of action that may be either allowed or disallowed:
read, edit, add and delete. Read permissions allow an object to be viewed. Edit
permissions allow a user to edit (i.e. change) aspects of the object. Add
permissions allow a user to add sub objects (i.e. images and subgalleries). This
is obviously meaningless when applied to images but it may be used later to
allow image comments. Finally Delete permissions allow a user to delete the
object concerned (and any sub objects).</p>
 
<p>These four permissions come in two flavours: group and world. World
permissions apply to all users so if, for example, a gallery has the world add
permission set then any user can add objects to it. The groups system is
slightly less intuitive but very powerful. A user may belong to any number of
groups. These groups are simply alphanumeric names separated by spaces. An
object may also belong to any number of groups. If a user belongs to at least
one group to which the object concerned also belongs then the group permissions
are considered. For example a user has this for their groups field "team23
photographers friends" and an image belongs to the following groups "friends
family" and has the group delete permission set then that user may delete the
object since both belong to the group 'friends'.</p>
 
<p>Permissions are NOT inherited from parent objects.</p>
 
<p class="note">NOTE: read permissions are not currently enforced, a future
version will prevent anyone from seeing objects that do not have sufficient read
permissions. Note also that there is no mechanism to set image permissions this
will be amended in a later release. Finally, since there is no database
concurrency handling, odd things might happen if two users are making changes
to the same gallery or image simultaneously.</p>
 
 
<h2><a name="users">Managing users</a></h2>
 
<p>As mentioned above there are two types of users: administrators and users.
Administrators can do everything and are not bound by permission settings. Only
administrators may create and edit users. Administrators may also edit existing
users' details including changing their passwords though, of course, they cannot
view their existing passwords.</p>
 
<p>Users may also be suspended. This preserves all the user's details but
prevents them from loggin in until their account is unsuspended by an
administrator.</p>
 
<p>There are two built-in accounts that cannot be deleted. The "admin" account
is an administrator. The "guest" account is special. It is like a user account
except that guests have no password, cannot change their details and cannot own
objects. This means guests can only affect objects with the appropriate world
permissions set. Any object created by a guest is owned by the special user
"__nobody__" and has full read, edit, add and delete permissions for both world
and group. You may disable guest access to your gallery by suspending the guest
user.</p>
 
 
<h2><a name="nomenclature">Naming of parts</a></h2>
 
<dl>
 
<dt>Installation</dt>
<dd>an installation of singapore is contained within a website. It is usually
in its own separate directory and contains one gallery: the root gallery.</dd>
<dt>Root gallery</dt>
<dd>There is only one root gallery and it is not contained within any other
galleries. It is located directly in the directory specified by the
<code>pathto_galleries</code> option. It is usually referred to in URLs with a
single dot (as in <code>?gallery=.</code>).</dd>
<dt>Gallery</dt>
<dd>a gallery is contained within another gallery (except the root gallery
which is contained in an installation). Galleries may contain more galleries
and also images.</dd>
 
<dt>Album</dt>
<dd>an album is a special case of gallery that contains exactly zero
galleries and zero or more images. In other words a gallery is called an
album when it does not have any child galleries. So an album is a gallery
but a gallery is not an album in much the same way that a kitchen is a room
but a room is not a kitchen.</dd>
 
<dt>Image</dt>
<dd>an image is contained within an album or a gallery. Due to the way
singapore operates, images will only be displayed if they are in albums since
any images in non-album galleries will be hidden.</dd>
 
<dt>Child gallery (also known as subgallery)</dt>
<dd>this is a relative term. A child gallery is one contained within the
gallery currently being viewed or edited. There may be zero or more.</dd>
<dt>Parent gallery</dt>
<dd>this is a relative term. The parent gallery is the one which contains the
gallery currently being viewed or edited. There is always exactly one (except
in the case of the root gallery which has no parent).</dd>
</dl>
 
<h2><a name="history">Version history</a></h2>
 
<pre>Key to symbols:
+ added
- removed
* fixed
o changed
</pre>
 
<p>A complete and up-to-date CVS changelog is
<a href="http://www.sgal.org/cvsdemo/ChangeLog">available online</a>.</p>
 
<h3>0.10.1 - 2006-09-20</h3>
 
<pre>
* fixed template security issue
+ access control settings are inherited by child galleries
* fixed image hits total
o updated modern template (see separate changelog)
</pre>
 
<h3>0.10.0 - 2006-05-17</h3>
 
<pre>
o code is now more object oriented and easier to understand
+ added safe_mode hack using FTP
+ can move &amp; copy galleries in admin
+ can batch delete images and galleries in admin
o thumbnails and logs stored in each gallery
+ thumbnails created on page load and statically linked
+ ancestor metadata is parsed for crumb line
o removed leading ./ from gallery id in urls
+ next and previous gallery links
+ 'up' links to correct page of parent gallery
* base_path and base_url are no longer overwritten by external.php
* fixed eastern european characters in data fields
* fixed new lines in summary field
* fixed image resizing bug when image size equals maxsize
* fixed imagemagick v6.x support
* fixed session.auto_start bug (aka login loop)
* fixed XSS vulnerability in template &amp; language flippers
+ added sort by date field to galleries
o rewritten hit logging code
o added explicit chmod's instead of relying on umask
o new admin error handling in preparetion for our new admin backend
</pre>
 
<h3>0.9.11 - 2004-12-15</h3>
 
<pre>
+ added SQL abstraction backend with support for MySQL and SQLite
o changed IO class hierarchy
o streamlined install process
+ separated editprofile from edituser
* fixed multiple vulnerabilities (thanks to SIG^2)
+ added allow_dir_upload config option
</pre>
 
<h3>0.9.10 - 2004-10-20</h3>
 
<pre>
+ implemented full multi-user support with permissions
+ reindex metadata feature in admin for importing ftp'd images
+ language and template are now user-selectable on-the-fly
+ language may be auto-detected from user agent headers
+ summary field now used instead of description field
o introduced new streamlined admin template with quicklinks
o tidied up css classes and annotated the default stylesheet
* fixed md5 dictionary attack vulnerability by hiding user account details
* fixed security issue with back-references in arguments to thumb.php
o made thumb.php reject files with extensions not in recognised_extensions
o changed base_file config option to index_file_url
o changed language config option to default_language
o changed template_name config option to default_template
+ new external.php file for integrating singapore into existing layouts
</pre>
 
<h3>0.9.9b - 2004-08-08</h3>
 
<pre>
* fixed image size calculation (again)
</pre>
 
<h3>0.9.9a - 2004-06-11</h3>
 
<pre>
* fixed multi-page galleries bug in templates
* fixed XHTML compliance
* fixed image size calculation
* possibly other things
</pre>
 
<h3>0.9.9 - 2004-05-15</h3>
 
<pre>
+ added multi-image upload using ZIP files
+ added fixed size and aspect ratio thumbnail creation
* fixed umask functionality (thanks to afuhrmann)
+ added navigation by clickable image map
+ added upload_overwrite config option
o moved url generation into separate function(s) (acsissman)
+ enabled use of mod_rewrite with appropriate .htaccess (acsissman)
+ added progressive jpeg option (thanks to joeforker)
o moved i18n functions into separate class
* made site navigation links xhtml compatible
* fixed special characters in filenames under ImageMagick *again*?
o introduced consistent 'gallery>album>image' naming scheme
o GD2 used as default thumbnail_software (GD1 support unaffected)
</pre>
 
<h3>0.9.8 - 2004-01-06</h3>
 
<pre>
+ automatic recognition of most URLs in 'description' field
+ do not process directories starting with dot (.)
+ enabled navigation bar in supporting browsers (e.g. mozilla, opera)
o made 'artist - name' iifn parsing optional
* fixed bizarre sort order in admin mode
* use htmlspecialchars instead of htmlentities
* fixed using special chars in filenames when magic_quotes_gpc is on (again)
* fixed code that produced 'Notice' level errors with PHP 5
</pre>
 
<h3>0.9.7 - 2003-11-17</h3>
 
<pre>
+ added forced image resizing to fixed size
+ added rudimentary image and gallery sort ordering
* fixed multi-page galleries listings
* fixed zero-width thumbnails for failed uploads
+ added a few functions useful for templates
+ added .jpe extension
o changed details array format
+ added basePath parameter to allow removed instantiation of singapore class
o fixed some untranslated strings in admin mode
* maybe fixed using special chars in filenames when magic_quotes_gpc is on
+ added back-reference check to prevent file-system walking
o merged __g functionality into _g and _ng
</pre>
 
<h3>0.9.6 - 2003-08-15</h3>
 
<pre>
o code entirely reorganised and largely re-written into classes
+ multilanguage (i18n) support
o interface is template driven
+ per-gallery and per-template configuration files
+ nested gallery support (unlimited depth)
+ crumb line for easier navigation
* all image and gallery names are now urlencoded
+ many new config options
</pre>
 
<h3>0.9.5 - 2003-05-31</h3>
 
<pre>
* fixed GD2 support in thumb.php (0.9.4a always used GD1)
- removed secret string option
+ added config options for admin session name (allows multiple installs on same server),
path to convert (ImageMagick), remove jpeg profile (ImageMagick),
character encoding &amp; site name (page title)
o execution_timer off by default and default galleries per page set to 10
+ thumb.php always uses fopen on remote files (now works on windows)
+ more checks in test.php including ImageMagick support and bugfix #743954 (upload_tmp_dir)
</pre>
 
<h3>0.9.4a - 2003-05-16</h3>
 
<pre>
+ added PNG and GIF support under GD (GIF only with compatible versions of GD)
+ added PNG, GIF, TIFF, BMP, and support from pretty much every
other file type under ImageMagick
+ more checks in test.php
* fixed image counting in iifn mode
* fixed show_image_name_in_thumbnail_view
+ images link back to correct page of gallery (second link)
</pre>
 
<h3>0.9.4 - 2003-05-13</h3>
 
<pre>
o changed config to ini file + global config object
o changed directory structure (moved documentation into docs/, moved writable files into data/)
+ gallery (thumbnail) view shows more information
+ gallery (thumbnail) view can show image name under thumbnail (off by default)
+ gallery (list) view shows number of images in gallery
+ implemented random thumbnail image in gallery (list) view
+ added test.php and setup.php (not very useful yet)
* fixed handling of gallery_thumb_number config option
* password change bug
* remote file thumbnail generation with ImageMagick
</pre>
 
<h3>0.9.3 - 2003-05-10</h3>
 
<pre>
+ web admin can add and delete images and galleries
+ added GD 2 and ImageMagic thumbnail generation support
* does not generate any E_NOTICE errors anymore
+ added config option for generated thumbnail JPEG quality
* handles extended characters in gallery and image names (Piotr)
* fixed 'images link back to correct page of gallery'
+ added directory_mode and file_mode options
* track_views and show_views now work independently
o admin bar now visible everywhere when logged in
</pre>
 
<h3>0.9.2 - 2003-04-27</h3>
 
<pre>
* fixed non-expiration of admin sessions in some cases
+ added purge cached thumbnails option
+ new 'XP' theme
* fixed hit logging functions
+ added image hit log viewing in admin mode
+ images link back to correct page of gallery
o optimised config.php
* fixed some css issues
</pre>
 
<h3>0.9.1 - 2003-04-23</h3>
 
<pre>
o changed database format
+ added visible database fields for artist email, darkroom manipulation and
digital manipulation
+ added invisible (control) database fields for thumbnail, owner, groups and categories
o put header and footer code into separate files
+ implemented limited themeing support
+ added config options for custom paths to cache, galleries, logs, themes,
header, footer and custom css
o improved navigation in admin mode
+ added optional script execution timer
* fixed proliferation of newlines in 'desc' field
* fixed wrongly escaped characters when saving info
</pre>
 
<h3>0.9a - 2003-04-13</h3>
 
<pre>
+ added much better documentation
</pre>
 
<h3>0.9 - 2003-03-30</h3>
 
<pre>
+ admin section (allows editing image and gallery info)
+ nicer gallery list layout
+ filename parser for if no metadata file found
o split into separate include files for io operations, ui generation etc
* fixed some css issues
+ lots of other little things
</pre>
 
<h3>0.0 (unnumbered version) - 2003-03-29</h3>
 
<pre>
o first release under GPL
+ everything
</pre>
 
<p><em>$Date: 2006/05/18 16:14:20 $</em></p>
 
</body>
</html>
/photogallery/docs/Translation.html
0,0 → 1,526
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>singapore - Translation</title>
<link rel="stylesheet" type="text/css" href="docstyle.css" />
</head>
 
<body>
 
<h1>singapore - Translation</h1>
 
<ul>
<li><a href="#intro">Introduction</a></li>
<li><a href="#requirements">Requirements</a></li>
<li><a href="#update">Updating a translation</a></li>
<li><a href="#new">Starting a new translation</a></li>
<li><a href="#header">Filling in the header section</a></li>
<li><a href="#plurals">Plural forms</a></li>
<li><a href="#links">Useful links</a></li>
<li><a href="Readme.html">General readme</a></li>
<li><a href="Advanced.html">Advanced features</a></li>
<li><a href="Development.html">Developer documentation</a></li>
</ul>
 
 
<h2><a name="intro">Introduction</a></h2>
 
<p>Thank you for taking an interest in open source development!
Translating singapore is a matter of editing a single file and
then running a script on it. What could be simpler?</p>
 
<p>Language strings are stored in standard GNU Gettext PO (portable object)
files which means you can (at least in theory <a href="#foot1" name="note1"><sup>1</sup></a>)
use all currently available PO editors such as
<a href="http://poedit.sourceforge.net/">poEdit</a> to make your
translations.</p>
 
<p>For added convenience strings for each language are split into two sections:
one for normal gallery operation and another for strings that are only used in
admin mode. This means that admin strings are not needlessly loaded for every
page and also that translators have the choice of only translating the standard
strings or going the whole way and translating the admin strings too.</p>
 
<p>It is a good idea for all translators and potential translators to join the
<a href="http://lists.sourceforge.net/lists/listinfo/singapore-devel">development
mailing list</a>. Use this, the
<a href="http://singapore.sourceforge.net/forum/viewforum.php?f=6">internationalisation forum</a>
and the
<a href="http://sourceforge.net/tracker/?atid=611769&group_id=77687">translations tracker</a>
to interact with other translators and developers.</p>
 
<p class="boxed"><a href="#note1" name="foot1">1</a>The reason for the "in theory"
is that many PO editors do not support the plural forms that singapore makes use
of - even though they are defined and supported by GNU Gettext. poEdit does
support plural forms since v1.3 and is highly recommended. Alternatively it is
just as easy to use a standard text editor to make your translations.</p>
 
<h2><a name="requirements">Requirements</a></h2>
 
<p>No further software is required for using the multilanguage capabilities of
singapore. However the extract and merge tools use xgettext and msgmerge
respectively. Both these programs are part of GNU Gettext which is already
installed on most Linux distributions. A package of the relevant gettext
binaries for Windows is available here:
<a href="http://singapore.sourceforge.net/binaries/singapore-gettext-Win32.zip">http://singapore.sourceforge.net/binaries/singapore-gettext-Win32.zip</a>.
The path to xgettext is stored in <code>tools/extract.php</code> and the path to
msgmerge is stored in <code>tools/merge.php</code>. However if the gettext programs
are in your PATH or in the <code>tools/</code> directory itself then you do not
need to edit anything.</p>
 
 
<h2><a name="update">Updating a translation</a></h2>
 
<p>Each singapore release requires the language files to be updated slightly.
First make sure you have the latest available translation (the
<a href="http://sourceforge.net/tracker/?atid=611769&group_id=77687">translations tracker</a>
is a good place to check for this). Now you need to merge in the new untranslated
strings and remove the obsolete ones (this may have already been done
but there's no harm in doing it again). Place the old PO file in the locale
directory of an installation of the latest version of singapore and use the
<a href="../tools/merge.php">merge</a> script provided.</p>
 
<p>Now proceed translating the strings as described below. Finally, attach the
updated PO file to the appropriate tracker item making sure to state which
version of singapore it is for.</p>
 
 
<h2><a name="new">Starting a new translation</a></h2>
 
<p>The very first thing to do is submit a tracker item on the
<a href="http://sourceforge.net/tracker/?atid=611769&group_id=77687">translations tracker</a>
to inform people of your intentions so that two or more people do not needlessly
spend time translating the same files for the same language. Once you have
completed your translations you can attach the files to the tracker item.</p>
 
<p>All language files are kept in a single directory (<code>locale/</code> by
default). They are named as follows:</p>
 
<ul>
<li><code>singapore.pot</code> -
untranslated standard language strings template in PO format</li>
<li><code>singapore.admin.pot</code> -
untranslated admin language strings template in PO format</li>
<li><code>singapore.<em>LANG</em>.po</code> -
translated standard language strings in PO format</li>
<li><code>singapore.admin.<em>LANG</em>.po</code> -
translated admin language strings in PO format</li>
<li><code>singapore.<em>LANG</em>.pmo</code> -
translated standard strings as compiled PHP serialized object</li>
<li><code>singapore.admin.<em>LANG</em>.pmo</code> -
translated admin strings as compiled PHP serialized object</li>
</ul>
 
<p>where <code><em>LANG</em></code> represents the ISO639 language code of the chosen
language (e.g. <code>de</code> for German, <code>en</code> for English,
<code>en-gb</code> for English (United Kingdom)). A more comprehensive list of
language codes may be found here:
<a href="http://www.rickbull.co.uk/tutorials/HTML/Useful%20Information/language_codes.php">http://www.rickbull.co.uk/tutorials/HTML/Useful%20Information/language_codes.php</a></p>
 
<p>Start by copying a PO template file (<code>singapore.pot</code> if you
are translating the standard strings or <code>singapore.admin.pot</code> if you
are translating the admin strings) and naming it appropriately for your language
as described above. Now open the file in your chosen PO editor or a plain text
editor and set about translating the strings.</p>
 
<p>You also need to fill in certain parts of the <a href="#header">PO file
header</a>. You may do this at any stage of the translation.</p>
 
<p>NOTES:</p>
 
<ol>
<li>Strings in the form "crumb line|You are here:"<br />
In these cases the text up to and including the vertical bar, |, should NOT
be included in the translation. They are simply hints for the translator.</li>
<li>Strings in the form "Showing %s-%s of %s"<br />
In these cases each %s will be replaced at runtime by a number or string in
order from left to right according to the rules of <code>printf()</code>.
Essentially each %s is a placeholder and so needs to be present at the
appropriate place in the translated string.<br />
However some languages may require the order of the arguments to be changed.
For example if instead of "Showing 1-10 of 15" you want to say
"Out of 15 objects 1-10 are shown" then you must use the argument swapping
syntax of <code>printf()</code>. More details on this may be found here:
<a href="http://www.php.net/sprintf">http://www.php.net/sprintf</a></li>
<li>Strings with plurals<br />
You must correctly specify the <a href="#plurals">Plural-forms</a> header field
in order to make use of plural forms. Put each plural in its own
<code>msgstr[<em>x</em>]</code> where x is a number between 0 (inclusive) and
the nplurals number you specified in the header (see examples below).</li>
 
<li>Using a text-editor<br />
When translating an entry you must leave the English language strings
(those on lines starting <code>msgid</code>) untouched and insert the
translated strings between the double-quotes on the following lines (those
starting <code>msgstr</code> or <code>msgstr[<em>x</em>]</code> in the case of
plurals).</li>
<li>Obsolete entries<br />
When updating a PO file, obsolete entries (i.e. those strings which appeared
in the previous version but do not in the current version) are placed at the
end of the PO file and prepended by <code>#~</code>. There is no need to
translate these entries as they are ignored by the compiler.</li>
</ol>
 
<p>Once you have translated all the strings and filled in the header, you need
to compile the PO file into a PHP serialized object file for use with
singapore. Do this using the <a href="../tools/compile.php">compile</a> script
provided in the <code>tools/</code> directory of the singapore distribution.</p>
 
<p>And that's it!</p>
 
<p>Now go and attach your translated PO file(s) to the tracker item you created
before starting the translation so that everyone else can make use of it.</p>
 
<h2>Examples</h2>
 
<p>The following string
<pre class="boxed">
# File: ../includes/singapore.class.php, line: 247
#, c-format
msgid "Page created in %s seconds"
msgstr ""
</pre>
when translated into French becomes
<pre class="boxed">
# File: ../includes/singapore.class.php, line: 247
#, c-format
msgid "Page created in %s seconds"
msgstr "Page créée en %s secondes"
</pre>
 
and the following string
<pre class="boxed">
# File: ../includes/admin.class.php, line: 173
msgid "admin bar|Edit image"
msgstr ""
</pre>
when translated into Italian becomes
<pre class="boxed">
# File: ../includes/admin.class.php, line: 173
msgid "admin bar|Edit image"
msgstr "Modifica l'immagine"
</pre>
 
and the following string
<pre class="boxed">
# File: ../includes/singapore.class.php, line: 530
#, c-format
msgid "%s gallery"
msgid_plural "%s galleries"
msgstr[0] ""
</pre>
when translated into Spanish becomes
<pre class="boxed">
# File: ../includes/singapore.class.php, line: 530
#, c-format
msgid "%s gallery"
msgid_plural "%s galleries"
msgstr[0] "%s galería"
msgstr[1] "%s galerías"
</pre>
 
</p>
 
<h2><a name="header">Filling in the header section</a></h2>
 
<p class="note">NOTE: This section is mainly copied from the
<a href="http://www.gnu.org/manual/gettext/html_chapter/gettext_5.html#SEC35">section 5.2</a>
of the GNU Gettext manual.</p>
 
<p>The initial comments "SOME DESCRIPTIVE TITLE", "YEAR" and
"FIRST AUTHOR &lt;EMAIL@ADDRESS&gt;, YEAR" ought to be replaced by
sensible information.</p>
 
<h3>The following fields must be filled in correctly:</h3>
 
<dl>
<dt>Content-Type</dt>
<dd>Replace <samp>ISO-8859-1</samp> with the
character encoding used for your language, in your locale, or
UTF-8. This field is needed for correct operation of the
<code>msgmerge</code> program, as well
as for users whose locale's character encoding differs from yours.
<p>The following encodings are frequently used for the corresponding
languages.</p>
<ul>
<li><code>ISO-8859-1</code> for Afrikaans, Albanian, Basque,
Catalan, Dutch, English, Estonian, Faroese, Finnish, French,
Galician, German, Greenlandic, Icelandic, Indonesian, Irish,
Italian, Malay, Norwegian, Portuguese, Spanish, Swedish,</li>
<li><code>ISO-8859-2</code> for Croatian, Czech, Hungarian,
Polish, Romanian, Serbian, Slovak, Slovenian,</li>
<li><code>ISO-8859-3</code> for Maltese,</li>
<li><code>ISO-8859-5</code> for Macedonian, Serbian,</li>
<li><code>ISO-8859-6</code> for Arabic,</li>
<li><code>ISO-8859-7</code> for Greek,</li>
<li><code>ISO-8859-8</code> for Hebrew,</li>
<li><code>ISO-8859-9</code> for Turkish,</li>
<li><code>ISO-8859-13</code> for Latvian, Lithuanian,</li>
<li><code>ISO-8859-15</code> for Basque, Catalan, Dutch, English,
Finnish, French, Galician, German, Irish, Italian, Portuguese,
Spanish, Swedish,</li>
<li><code>KOI8-R</code> for Russian,</li>
<li><code>KOI8-U</code> for Ukrainian,</li>
<li><code>CP1251</code> for Bulgarian, Byelorussian,</li>
<li><code>GB2312</code>, <code>GBK</code>, <code>GB18030</code>
for simplified writing of Chinese,</li>
<li><code>BIG5</code>, <code>BIG5-HKSCS</code> for traditional
writing of Chinese,</li>
<li><code>EUC-JP</code> for Japanese,</li>
<li><code>EUC-KR</code> for Korean,</li>
<li><code>TIS-620</code> for Thai,</li>
<li><code>UTF-8</code> for any language, including those listed
above.</li>
</ul>
<p>The character encoding name can be written in either upper or
lower case. Usually upper case is preferred.</p>
</dd>
<dt>Plural-Forms</dt>
<dd>See the <a href="#plurals">plural forms</a> section.</dd>
 
</dl>
 
<h3>The following fields should be filled in:</h3>
 
<dl>
<dt>Project-Id-Version</dt>
<dd>This is the name and version of the package.</dd>
<dt>Last-Translator</dt>
<dd>Fill in your name and email address (without double
quotes).</dd>
<dt>Language-Team</dt>
<dd>Fill in the English name of the language followed by the native name
of the language in brackets. E.g. <i>"Language-Team: German (Deutsch)\n"</i><br />
Note this is different from the GNU specification but is required in order
for the language flipper function to work.
</dd>
</dl>
 
<h3>The following fields may be left alone:</h3>
 
<dl>
<dt>POT-Creation-Date</dt>
<dd>This has already been filled in by <code>xgettext</code>.</dd>
<dt>PO-Revision-Date</dt>
<dd>You don't need to fill this in. It should be filled by the editor when
you save the file.</dd>
<dt>Content-Transfer-Encoding</dt>
<dd>Set this to <code>8bit</code>.</dd>
</dl>
 
<h2><a name="plurals">Plural forms</a></h2>
 
<p class="note">NOTE: This section is mainly copied from the
<a href="http://www.gnu.org/manual/gettext/html_chapter/gettext_10.html#SEC150">section 10.2.5</a>
of the GNU Gettext manual.</p>
 
 
<p>The Plural-forms field in the PO header is used to calculate which plural
form of a word to use. In English there are only two plural forms but other
languages have only one or as many as four.</p>
 
<p>Please check the list below to see if your language is listed. If it is
then use the corresponding string. If not then you can either write it yourself
(details below and in the gettext manual) or email a member of the team
describing how your langauge works (e.g. (not real) 0 car, 1-2 cars, 3 caren, 5+ carii)
and we will write one for you.
 
<dl>
<dt>Only one form:</dt>
<dd>Some languages only require one single form. There is no
distinction between the singular and plural form. An appropriate
header entry would look like this:
<pre>Plural-Forms: nplurals=1; plural=0;</pre>
<p>Languages with this property include:</p>
<dl>
<dt>Finno-Ugric family</dt>
<dd>Hungarian</dd>
<dt>Asian family</dt>
<dd>Japanese, Korean</dd>
<dt>Turkic/Altaic family</dt>
<dd>Turkish</dd>
</dl>
</dd>
<dt>Two forms, singular used for one only</dt>
<dd>This is the form used in most existing programs since it is
what English is using. A header entry would look like this:
<pre>Plural-Forms: nplurals=2; plural=n==1 ? 0 : 1;</pre>
<p>Languages with this property include:</p>
<dl>
<dt>Germanic family</dt>
<dd>Danish, Dutch, English, German, Norwegian, Swedish</dd>
<dt>Finno-Ugric family</dt>
<dd>Estonian, Finnish</dd>
<dt>Latin/Greek family</dt>
<dd>Greek</dd>
<dt>Semitic family</dt>
<dd>Hebrew</dd>
<dt>Romanic family</dt>
<dd>Italian, Portuguese, Spanish</dd>
<dt>Artificial</dt>
<dd>Esperanto</dd>
</dl>
</dd>
<dt>Two forms, singular used for zero and one</dt>
<dd>Exceptional case in the language family. The header entry would be:
<pre>Plural-Forms: nplurals=2; plural=n&gt;1;</pre>
<p>Languages with this property include:</p>
<dl>
<dt>Romanic family</dt>
<dd>French, Brazilian Portuguese</dd>
</dl>
</dd>
<dt>Three forms, special case for zero</dt>
<dd>The header entry would be:
<pre>Plural-Forms: nplurals=3; plural=n%10==1 &amp;&amp; n%100!=11 ? 0 : n != 0 ? 1 : 2;</pre>
<p>Languages with this property include:</p>
<dl>
<dt>Baltic family</dt>
<dd>Latvian</dd>
</dl>
</dd>
<dt>Three forms, special cases for one and two</dt>
<dd>The header entry would be:
<pre>Plural-Forms: nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;</pre>
<p>Languages with this property include:</p>
<dl>
<dt>Celtic</dt>
<dd>Gaeilge (Irish)</dd>
</dl>
</dd>
<dt>Three forms, special case for numbers ending in 1[2-9]</dt>
<dd>The header entry would look like this:
<pre>Plural-Forms: nplurals=3; plural=n%10==1 &amp;&amp; n%100!=11 ? 0 : n%10&gt;=2 &amp;&amp; (n%100&lt;10 || n%100&gt;=20) ? 1 : 2;</pre>
<p>Languages with this property include:</p>
<dl>
<dt>Baltic family</dt>
<dd>Lithuanian</dd>
</dl>
</dd>
<dt>Three forms, special cases for numbers ending in 1 and 2, 3,
4, except those ending in 1[1-4]</dt>
<dd>The header entry would look like this:
<pre>Plural-Forms: nplurals=3; plural=n%10==1 &amp;&amp; n%100!=11 ? 0 : n%10&gt;=2 &amp;&amp; n%10&lt;=4 &amp;&amp; (n%100&lt;10 || n%100&gt;=20) ? 1 : 2;</pre>
<p>Languages with this property include:</p>
<dl>
<dt>Slavic family</dt>
<dd>Croatian, Czech, Russian, Slovak, Ukrainian</dd>
</dl>
</dd>
<dt>Three forms, special case for one and some numbers ending in
2, 3, or 4</dt>
<dd>The header entry would look like this:
<pre>Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10&gt;=2 &amp;&amp; n%10&lt;=4 &amp;&amp; (n%100&lt;10 || n%100&gt;=20) ? 1 : 2;</pre>
<p>Languages with this property include:</p>
<dl>
<dt>Slavic family</dt>
<dd>Polish</dd>
</dl>
</dd>
<dt>Four forms, special case for one and all numbers ending in
02, 03, or 04</dt>
<dd>The header entry would look like this:
<pre>Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;</pre>
<p>Languages with this property include:</p>
<dl>
<dt>Slavic family</dt>
<dd>Slovenian</dd>
</dl>
</dd>
</dl>
 
<h3>How the Plural-forms header works:</h3>
 
<p>The <code>nplurals</code> value must be a decimal number which
specifies how many different plural forms exist for this
language. The string following <code>plural</code> is an
expression which is using the C language syntax. Exceptions are
that no negative numbers are allowed, numbers must be decimal,
and the only variable allowed is <code>n</code>. This expression
will be evaluated whenever one of the plural functions is called.
The numeric value passed to
these functions is then substituted for all uses of the variable
<code>n</code> in the expression. The resulting value then must
be greater or equal to zero and smaller than the value given as
the value of <code>nplurals</code>.</p>
 
<h2><a name="links">Useful links</a></h2>
 
<ul>
<li><a href="http://singapore.sourceforge.net/forum/viewforum.php?f=6">singapore i18n forum</a></li>
<li><a href="http://www.gnu.org/software/gettext/">GNU Gettext homepage</a></li>
<li><a href="http://www.gnu.org/manual/gettext/">GNU Gettext manual</a> - lots
of technical information about the PO format</li>
<li><a href="http://poedit.sourceforge.net/">poEdit</a> - an open source cross-platform PO editor</li>
<li><a href="http://www.gtranslator.org/">gTranslator</a> - a PO editor for GNOME</li>
<li><a href="http://i18n.kde.org/tools/kbabel/">KBabel</a> - a PO editor for KDE</li>
</ul>
 
 
<p><em>$Date: 2004/11/01 08:17:33 $</em></p>
 
</body>
</html>
/photogallery/docs/docstyle.css
0,0 → 1,106
body {
margin: 1em;
font: small sans-serif;
color: #000;
background-color: #fff;
}
 
p, td, th, li, dd, dt {
font: small sans-serif;
}
 
h1, h2, h3, h4{
color: #f60;
}
 
h1, h2 {
font-size: medium;
border-bottom: 1px solid #ccc;
letter-spacing: 0.3em;
text-transform: uppercase;
}
 
code, pre {
color: #444;
}
 
p, td, th, li, dt, h3, h4, pre {
margin-left: 2em;
}
 
dd {
margin-left: 3em;
}
 
dt {
margin-top: 0.5em;
}
 
a:link {
color: #09f;
text-decoration: underline;
}
 
a:visited {
color: #05a;
text-decoration: underline;
}
 
a:hover {
text-decoration: none;
}
 
input, textarea, select, .inputbox {
border: 1px solid #f60;
color: #000;
background-color: #fff;
}
 
input.radio {
border: none;
background-color: #fff;
}
 
input.button {
font-weight: bold;
border: 1px outset #fff;
color: #fff;
background-color: #f60;
}
 
ul.things > li {
margin-top: 0.75em;
}
 
.note {
color: #d00;
}
 
.error {
color: #f00;
}
 
.boxed, .note, #progressBox {
border: 1px dashed #ccc;
padding: 0.5em;
}
 
#progressBox {
float: right;
background-color: inherit;
}
 
#progressBox li.currentStep {
color: #f60;
font-size: medium;
}
 
#progressBox p, #progressBox li, #progressBox ol {
font-weight: bold;
margin: 0em;
}
 
a.button {
margin-top: 2em;
display: block;
}
/photogallery/docs/index.html
0,0 → 1,27
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>singapore documentation</title>
<link rel="stylesheet" type="text/css" href="docstyle.css" />
</head>
 
<body>
 
<h1>singapore documentation</h1>
 
<ul>
<li><a href="Readme.html">General readme including installation instructions</a></li>
<li><a href="Advanced.html">Advanced features and how to use them</a></li>
<li><a href="Translation.html">Translating singapore</a></li>
<li><a href="Development.html">Developer documentation</a></li>
<li><a href="http://singapore.sourceforge.net/">Home page</a></li>
<li><a href="http://singapore.sourceforge.net/forum/">Support forum</a></li>
<li><a href="http://sourceforge.net/project/showfiles.php?group_id=77687&package_id=78646">Download latest version</a></li>
</ul>
 
<p><a href="../">Return</a> to singapore.</p>
 
</body>
</html>