228 |
kaklik |
1 |
<?php |
|
|
2 |
|
|
|
3 |
/** |
|
|
4 |
* Main class. |
|
|
5 |
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License |
|
|
6 |
* @copyright (c)2003-2006 Tamlyn Rhodes |
|
|
7 |
* @version $Id: singapore.class.php,v 1.75 2006/09/12 11:56:11 thepavian Exp $ |
|
|
8 |
*/ |
|
|
9 |
|
|
|
10 |
//define constants for regular expressions |
|
|
11 |
define('SG_REGEXP_PROTOCOLURL', '(?:http://|https://|ftp://|mailto:)(?:[a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,4}(?::[0-9]+)?(?:/[^ \n\r\"\'<]+)?'); |
|
|
12 |
define('SG_REGEXP_WWWURL', 'www\.(?:[a-zA-Z0-9\-]+\.)*[a-zA-Z]{2,4}(?:/[^ \n\r\"\'<]+)?'); |
|
|
13 |
define('SG_REGEXP_EMAILURL', '(?:[\w][\w\.\-]+)+@(?:[\w\-]+\.)+[a-zA-Z]{2,4}'); |
|
|
14 |
|
|
|
15 |
/** |
|
|
16 |
* Provides functions for handling galleries and images |
|
|
17 |
* @package singapore |
|
|
18 |
* @author Tamlyn Rhodes <tam at zenology dot co dot uk> |
|
|
19 |
*/ |
|
|
20 |
class Singapore |
|
|
21 |
{ |
|
|
22 |
/** |
|
|
23 |
* current script version |
|
|
24 |
* @var string |
|
|
25 |
*/ |
|
|
26 |
var $version = "0.10.1"; |
|
|
27 |
|
|
|
28 |
/** |
|
|
29 |
* instance of a {@link sgConfig} object representing the current |
|
|
30 |
* script configuration |
|
|
31 |
* @var sgConfig |
|
|
32 |
*/ |
|
|
33 |
var $config; |
|
|
34 |
|
|
|
35 |
/** |
|
|
36 |
* instance of the currently selected IO handler object |
|
|
37 |
* @var sgIO_csv |
|
|
38 |
*/ |
|
|
39 |
var $io; |
|
|
40 |
|
|
|
41 |
/** |
|
|
42 |
* instance of a {@link Translator} |
|
|
43 |
* @var Translator |
|
|
44 |
*/ |
|
|
45 |
var $translator; |
|
|
46 |
|
|
|
47 |
/** |
|
|
48 |
* instance of a {@link sgGallery} representing the current gallery |
|
|
49 |
* @var sgGallery |
|
|
50 |
*/ |
|
|
51 |
var $gallery; |
|
|
52 |
|
|
|
53 |
/** |
|
|
54 |
* reference to the currently selected {@link sgImage} object in the |
|
|
55 |
* $images array of {@link $gallery} |
|
|
56 |
* @var sgImage |
|
|
57 |
*/ |
|
|
58 |
var $image; |
|
|
59 |
|
|
|
60 |
/** |
|
|
61 |
* two character code of language currently in use |
|
|
62 |
* @var string |
|
|
63 |
*/ |
|
|
64 |
var $language = null; |
|
|
65 |
|
|
|
66 |
/** |
|
|
67 |
* name of template currently in use |
|
|
68 |
* @var string |
|
|
69 |
*/ |
|
|
70 |
var $template = null; |
|
|
71 |
|
|
|
72 |
/** |
|
|
73 |
* details of current user |
|
|
74 |
* @var sgUser |
|
|
75 |
*/ |
|
|
76 |
var $user = null; |
|
|
77 |
|
|
|
78 |
/** |
|
|
79 |
* name of action requested |
|
|
80 |
* @var string |
|
|
81 |
*/ |
|
|
82 |
var $action = null; |
|
|
83 |
|
|
|
84 |
/** |
|
|
85 |
* Constructor, does all init type stuff. This code is a total mess. |
|
|
86 |
* @param string the path to the base singapore directory |
|
|
87 |
*/ |
|
|
88 |
function Singapore($basePath = "") |
|
|
89 |
{ |
|
|
90 |
//import class definitions |
|
|
91 |
//io handler class included once config is loaded |
|
|
92 |
require_once $basePath."includes/translator.class.php"; |
|
|
93 |
require_once $basePath."includes/thumbnail.class.php"; |
|
|
94 |
require_once $basePath."includes/gallery.class.php"; |
|
|
95 |
require_once $basePath."includes/config.class.php"; |
|
|
96 |
require_once $basePath."includes/image.class.php"; |
|
|
97 |
require_once $basePath."includes/user.class.php"; |
|
|
98 |
|
|
|
99 |
//start execution timer |
|
|
100 |
$this->scriptStartTime = microtime(); |
|
|
101 |
|
|
|
102 |
//remove slashes |
|
|
103 |
if(get_magic_quotes_gpc()) |
|
|
104 |
$_REQUEST = array_map(array("Singapore","arraystripslashes"), $_REQUEST); |
|
|
105 |
|
|
|
106 |
//desanitize request |
|
|
107 |
$_REQUEST = array_map("htmlentities", $_REQUEST); |
|
|
108 |
|
|
|
109 |
//load config from singapore root directory |
|
|
110 |
$this->config =& sgConfig::getInstance(); |
|
|
111 |
$this->config->loadConfig($basePath."singapore.ini"); |
|
|
112 |
$this->config->loadConfig($basePath."secret.ini.php"); |
|
|
113 |
|
|
|
114 |
//if instantiated remotely... |
|
|
115 |
if(!empty($basePath)) { |
|
|
116 |
//...try to guess base path and relative url |
|
|
117 |
if(empty($this->config->base_path)) |
|
|
118 |
$this->config->base_path = $basePath; |
|
|
119 |
if(empty($this->config->base_url)) |
|
|
120 |
$this->config->base_url = $basePath; |
|
|
121 |
//...load local config if present |
|
|
122 |
//may over-ride guessed values above |
|
|
123 |
$this->config->loadConfig("singapore.local.ini"); |
|
|
124 |
} |
|
|
125 |
|
|
|
126 |
//set current gallery to root if not specified in url |
|
|
127 |
$galleryId = isset($_REQUEST[$this->config->url_gallery]) ? $_REQUEST[$this->config->url_gallery] : "."; |
|
|
128 |
|
|
|
129 |
//load config from gallery ini file (gallery.ini) if present |
|
|
130 |
$this->config->loadConfig($basePath.$this->config->pathto_galleries.$galleryId."/gallery.ini"); |
|
|
131 |
|
|
|
132 |
//set current template from request vars or config |
|
|
133 |
//first, preset template to default one |
|
|
134 |
$this->template = $this->config->default_template; |
|
|
135 |
//then check if requested template exists |
|
|
136 |
if(!empty($_REQUEST[$this->config->url_template])) { |
|
|
137 |
$templates = Singapore::getListing($this->config->base_path.$this->config->pathto_templates); |
|
|
138 |
foreach($templates->dirs as $single) { |
|
|
139 |
if($single == $_REQUEST[$this->config->url_template]) { |
|
|
140 |
$this->template = $single; |
|
|
141 |
break; |
|
|
142 |
} |
|
|
143 |
} |
|
|
144 |
} |
|
|
145 |
|
|
|
146 |
$this->config->pathto_current_template = $this->config->pathto_templates.$this->template.'/'; |
|
|
147 |
//load config from template ini file (template.ini) if present |
|
|
148 |
$this->config->loadConfig($basePath.$this->config->pathto_current_template."template.ini"); |
|
|
149 |
|
|
|
150 |
//set runtime values |
|
|
151 |
$this->config->pathto_logs = $this->config->pathto_data_dir."logs/"; |
|
|
152 |
$this->config->pathto_cache = $this->config->pathto_data_dir."cache/"; |
|
|
153 |
$this->config->pathto_admin_template = $this->config->pathto_templates.$this->config->admin_template_name."/"; |
|
|
154 |
|
|
|
155 |
//set current language from request vars or config |
|
|
156 |
if(!empty($_REQUEST[$this->config->url_lang])) |
|
|
157 |
$this->language = $_REQUEST[$this->config->url_lang]; |
|
|
158 |
else { |
|
|
159 |
$this->language = $this->config->default_language; |
|
|
160 |
if($this->config->detect_language) |
|
|
161 |
foreach($this->getBrowserLanguages() as $lang) |
|
|
162 |
if($lang=="en" || file_exists($basePath.$this->config->pathto_locale."singapore.".$lang.".pmo")) { |
|
|
163 |
$this->language = $lang; |
|
|
164 |
break; |
|
|
165 |
} |
|
|
166 |
} |
|
|
167 |
|
|
|
168 |
//read the language file |
|
|
169 |
$this->translator =& Translator::getInstance($this->language); |
|
|
170 |
$this->translator->readLanguageFile($this->config->base_path.$this->config->pathto_locale."singapore.".$this->language.".pmo"); |
|
|
171 |
|
|
|
172 |
//clear the UMASK |
|
|
173 |
umask(0); |
|
|
174 |
|
|
|
175 |
//include IO handler class and create instance |
|
|
176 |
require_once $basePath."includes/io_".$this->config->io_handler.".class.php"; |
|
|
177 |
$ioClassName = "sgIO_".$this->config->io_handler; |
|
|
178 |
$this->io = new $ioClassName($this->config); |
|
|
179 |
|
|
|
180 |
//load gallery and image info |
|
|
181 |
$this->selectGallery($galleryId); |
|
|
182 |
|
|
|
183 |
//set character set |
|
|
184 |
if(!empty($this->translator->languageStrings[0]["charset"])) |
|
|
185 |
$this->character_set = $this->translator->languageStrings[0]["charset"]; |
|
|
186 |
else |
|
|
187 |
$this->character_set = $this->config->default_charset; |
|
|
188 |
|
|
|
189 |
//set action to perform |
|
|
190 |
if(empty($_REQUEST["action"])) $this->action = "view"; |
|
|
191 |
else $this->action = $_REQUEST["action"]; |
|
|
192 |
|
|
|
193 |
|
|
|
194 |
} |
|
|
195 |
|
|
|
196 |
/** |
|
|
197 |
* Load gallery and image info |
|
|
198 |
* @param string the id of the gallery to load (optional) |
|
|
199 |
*/ |
|
|
200 |
function selectGallery($galleryId = "") |
|
|
201 |
{ |
|
|
202 |
if(empty($galleryId)) $galleryId = isset($_REQUEST[$this->config->url_gallery]) ? $_REQUEST[$this->config->url_gallery] : "."; |
|
|
203 |
|
|
|
204 |
//try to validate gallery id |
|
|
205 |
if(strlen($galleryId)>1 && $galleryId{1} != '/') $galleryId = './'.$galleryId; |
|
|
206 |
|
|
|
207 |
//detect back-references to avoid file-system walking |
|
|
208 |
if(strpos($galleryId,"../")!==false) $galleryId = "."; |
|
|
209 |
|
|
|
210 |
//find all ancestors to current gallery |
|
|
211 |
$this->ancestors = array(); |
|
|
212 |
$ancestorNames = explode("/", $galleryId); |
|
|
213 |
$numberOfAncestors = count($ancestorNames); |
|
|
214 |
|
|
|
215 |
//construct fully qualified gallery ids |
|
|
216 |
$ancestorIds[0] = "."; |
|
|
217 |
for($i=1; $i<$numberOfAncestors; $i++) |
|
|
218 |
$ancestorIds[$i] = $ancestorIds[$i-1]."/".$ancestorNames[$i]; |
|
|
219 |
|
|
|
220 |
//fetch galleries passing previous gallery as parent pointer |
|
|
221 |
for($i=0; $i<$numberOfAncestors; $i++) |
|
|
222 |
if(!$this->ancestors[$i] =& $this->io->getGallery( |
|
|
223 |
$ancestorIds[$i], $this->ancestors[$i-1], |
|
|
224 |
//only fetch children of bottom level gallery |
|
|
225 |
($i==$numberOfAncestors-1) ? 1 : 0 |
|
|
226 |
) |
|
|
227 |
) |
|
|
228 |
break; |
|
|
229 |
|
|
|
230 |
//need to remove bogus parent of root gallery created by previous step |
|
|
231 |
unset($this->ancestors[-1]); |
|
|
232 |
|
|
|
233 |
//set reference to current gallery |
|
|
234 |
$this->gallery = &$this->ancestors[count($this->ancestors)-1]; |
|
|
235 |
|
|
|
236 |
//check if gallery was successfully fetched |
|
|
237 |
if($this->gallery == null) { |
|
|
238 |
$this->gallery = new sgGallery($galleryId, $this->ancestors[0]); |
|
|
239 |
$this->gallery->name = $this->translator->_g("Gallery not found '%s'",htmlspecialchars($galleryId)); |
|
|
240 |
} |
|
|
241 |
|
|
|
242 |
//sort galleries and images |
|
|
243 |
$GLOBALS["sgSortOrder"] = $this->config->gallery_sort_order; |
|
|
244 |
if($this->config->gallery_sort_order!="x") usort($this->gallery->galleries, array("Singapore","multiSort")); |
|
|
245 |
$GLOBALS["sgSortOrder"] = $this->config->image_sort_order; |
|
|
246 |
if($this->config->image_sort_order!="x") usort($this->gallery->images, array("Singapore","multiSort")); |
|
|
247 |
unset($GLOBALS["sgSortOrder"]); |
|
|
248 |
|
|
|
249 |
//if startat is set then cast to int otherwise startat 0 |
|
|
250 |
$this->gallery->startat = isset($_REQUEST[$this->config->url_startat]) ? (int)$_REQUEST[$this->config->url_startat] : 0; |
|
|
251 |
$this->startat = $this->gallery->startat; //depreciated |
|
|
252 |
|
|
|
253 |
//select the image (if any) |
|
|
254 |
if(!empty($_REQUEST[$this->config->url_image])) |
|
|
255 |
$this->selectImage($_REQUEST[$this->config->url_image]); |
|
|
256 |
|
|
|
257 |
//load hit data |
|
|
258 |
if($this->config->track_views || $this->config->show_views) |
|
|
259 |
$this->io->getHits($this->gallery); |
|
|
260 |
|
|
|
261 |
//update and save hit data |
|
|
262 |
if($this->config->track_views) { |
|
|
263 |
if($this->isImagePage()) { |
|
|
264 |
$this->image->hits++; |
|
|
265 |
$this->image->lasthit = time(); |
|
|
266 |
} elseif($this->gallery->startat == 0) { |
|
|
267 |
$this->gallery->hits++; |
|
|
268 |
$this->gallery->lasthit = time(); |
|
|
269 |
} |
|
|
270 |
$this->io->putHits($this->gallery); |
|
|
271 |
} |
|
|
272 |
} |
|
|
273 |
|
|
|
274 |
/** |
|
|
275 |
* Selects an image from the current gallery |
|
|
276 |
* @param mixed either the filename of the image to select or the integer |
|
|
277 |
* index of its position in the images array |
|
|
278 |
* @return boolean true on success; false otherwise |
|
|
279 |
*/ |
|
|
280 |
function selectImage($image) |
|
|
281 |
{ |
|
|
282 |
if(is_string($image)) { |
|
|
283 |
foreach($this->gallery->images as $index => $img) |
|
|
284 |
if($img->id == $image) { |
|
|
285 |
$this->image =& $this->gallery->images[$index]; |
|
|
286 |
return true; |
|
|
287 |
} |
|
|
288 |
} elseif(is_int($image) && $image >= 0 && $image < count($this->gallery->images)) { |
|
|
289 |
$this->image =& $this->gallery->images[$image]; |
|
|
290 |
return true; |
|
|
291 |
} |
|
|
292 |
$this->image =& new sgImage("", $this->gallery); |
|
|
293 |
$this->image->name = $this->translator->_g("Image not found '%s'",htmlspecialchars($image)); |
|
|
294 |
return false; |
|
|
295 |
} |
|
|
296 |
|
|
|
297 |
|
|
|
298 |
/** |
|
|
299 |
* Obfuscates the given email address by replacing "." with "dot" and "@" with "at" |
|
|
300 |
* @param string email address to obfuscate |
|
|
301 |
* @param boolean override the obfuscate_email config setting (optional) |
|
|
302 |
* @return string obfuscated email address or HTML mailto link |
|
|
303 |
*/ |
|
|
304 |
function formatEmail($email, $forceObfuscate = false) |
|
|
305 |
{ |
|
|
306 |
if($this->config->obfuscate_email || $forceObfuscate) |
|
|
307 |
return strtr($email,array("@" => ' <b>'.$this->translator->_g("email|at").'</b> ', "." => ' <b>'.$this->translator->_g("email|dot").'</b> ')); |
|
|
308 |
else |
|
|
309 |
return "<a href=\"mailto:".$email."\">".$email."</a>"; |
|
|
310 |
} |
|
|
311 |
|
|
|
312 |
|
|
|
313 |
/** |
|
|
314 |
* Returns image name for image pages and gallery name for gallery pages. |
|
|
315 |
* If either of these is empty, returns gallery_name config option. |
|
|
316 |
* |
|
|
317 |
* @return string Title of current page |
|
|
318 |
*/ |
|
|
319 |
function pageTitle() |
|
|
320 |
{ |
|
|
321 |
$crumbArray = $this->crumbLineArray(); |
|
|
322 |
|
|
|
323 |
$ret = ""; |
|
|
324 |
for($i=count($crumbArray)-1;$i>0;$i--) |
|
|
325 |
$ret .= $crumbArray[$i]->nameForce()." < "; |
|
|
326 |
$ret .= $crumbArray[$i]->nameForce(); |
|
|
327 |
|
|
|
328 |
return $ret; |
|
|
329 |
} |
|
|
330 |
|
|
|
331 |
/** |
|
|
332 |
* @return bool true if this is an image page; false otherwise |
|
|
333 |
*/ |
|
|
334 |
function isImagePage() |
|
|
335 |
{ |
|
|
336 |
return !empty($this->image); |
|
|
337 |
} |
|
|
338 |
|
|
|
339 |
/** |
|
|
340 |
* @return bool true if this is a non-album gallery page; false otherwise |
|
|
341 |
*/ |
|
|
342 |
function isGalleryPage() |
|
|
343 |
{ |
|
|
344 |
return !empty($this->gallery) && $this->gallery->galleryCount()>0;; |
|
|
345 |
} |
|
|
346 |
|
|
|
347 |
/** |
|
|
348 |
* @return bool true if this is an album page; false otherwise |
|
|
349 |
*/ |
|
|
350 |
function isAlbumPage() |
|
|
351 |
{ |
|
|
352 |
return !$this->isGalleryPage() && !$this->isImagePage() && !empty($this->gallery); |
|
|
353 |
} |
|
|
354 |
|
|
|
355 |
|
|
|
356 |
/** |
|
|
357 |
* @return int the script execution time in seconds rounded to two decimal places |
|
|
358 |
*/ |
|
|
359 |
function scriptExecTime() |
|
|
360 |
{ |
|
|
361 |
$scriptStartTime = $this->scriptStartTime; |
|
|
362 |
$scriptEndTime = microtime(); |
|
|
363 |
|
|
|
364 |
list($usec, $sec) = explode(" ",$scriptStartTime); |
|
|
365 |
$scriptStartTime = (float)$usec + (float)$sec; |
|
|
366 |
list($usec, $sec) = explode(" ",$scriptEndTime); |
|
|
367 |
$scriptEndTime = (float)$usec + (float)$sec; |
|
|
368 |
|
|
|
369 |
$scriptExecTime = floor(($scriptEndTime - $scriptStartTime)*100)/100; |
|
|
370 |
return $scriptExecTime; |
|
|
371 |
} |
|
|
372 |
|
|
|
373 |
/** |
|
|
374 |
* Displays the script execution time if configured to do so |
|
|
375 |
* @returns string the script execution time |
|
|
376 |
*/ |
|
|
377 |
function scriptExecTimeText() |
|
|
378 |
{ |
|
|
379 |
if($this->config->show_execution_time) |
|
|
380 |
return $this->translator->_g("Page created in %s seconds",$this->scriptExecTime()); |
|
|
381 |
else |
|
|
382 |
return ""; |
|
|
383 |
} |
|
|
384 |
|
|
|
385 |
function poweredByText() |
|
|
386 |
{ |
|
|
387 |
return $this->translator->_g("Powered by").' <a href="http://www.sgal.org/">singapore</a>'; |
|
|
388 |
} |
|
|
389 |
|
|
|
390 |
function allRightsReserved() |
|
|
391 |
{ |
|
|
392 |
return $this->translator->_g("All rights reserved."); |
|
|
393 |
} |
|
|
394 |
|
|
|
395 |
function licenseText() |
|
|
396 |
{ |
|
|
397 |
return $this->translator->_g("Images may not be reproduced in any form without the express written permission of the copyright holder."); |
|
|
398 |
} |
|
|
399 |
|
|
|
400 |
function adminURL() |
|
|
401 |
{ |
|
|
402 |
return '<a href="'.$this->config->base_url.'admin.php">'; |
|
|
403 |
} |
|
|
404 |
|
|
|
405 |
function adminLink() |
|
|
406 |
{ |
|
|
407 |
return $this->adminURL().$this->translator->_g("Log in")."</a>"; |
|
|
408 |
} |
|
|
409 |
|
|
|
410 |
|
|
|
411 |
/** |
|
|
412 |
* Checks to see if the user is currently logged in to admin mode. Also resets |
|
|
413 |
* the login timeout to the current time. |
|
|
414 |
* @returns boolean true if the user is logged in; false otherwise |
|
|
415 |
* @static |
|
|
416 |
*/ |
|
|
417 |
function isLoggedIn() |
|
|
418 |
{ |
|
|
419 |
if( |
|
|
420 |
isset($this->user) && |
|
|
421 |
$_SESSION["sgUser"]["ip"] == $_SERVER["REMOTE_ADDR"] && |
|
|
422 |
(time() - $_SESSION["sgUser"]["loginTime"] < 600) |
|
|
423 |
) { |
|
|
424 |
//reset loginTime to current time |
|
|
425 |
$_SESSION["sgUser"]["loginTime"] = time(); |
|
|
426 |
return true; |
|
|
427 |
} |
|
|
428 |
return false; |
|
|
429 |
} |
|
|
430 |
|
|
|
431 |
function loadUser($username = null) |
|
|
432 |
{ |
|
|
433 |
if($username == null) |
|
|
434 |
if(isset($_SESSION["sgUser"])) |
|
|
435 |
$username = $_SESSION["sgUser"]["username"]; |
|
|
436 |
else |
|
|
437 |
return false; |
|
|
438 |
|
|
|
439 |
$users = $this->io->getUsers(); |
|
|
440 |
foreach($users as $user) |
|
|
441 |
if($user->username == $username) { |
|
|
442 |
$this->user = $user; |
|
|
443 |
return $user; |
|
|
444 |
} |
|
|
445 |
return false; |
|
|
446 |
} |
|
|
447 |
|
|
|
448 |
/** |
|
|
449 |
* Creates an array of objects each representing an item in the crumb line. |
|
|
450 |
* @return array the items of the crumb line |
|
|
451 |
*/ |
|
|
452 |
function crumbLineArray() |
|
|
453 |
{ |
|
|
454 |
$crumb = $this->ancestors; |
|
|
455 |
|
|
|
456 |
if($this->isImagePage()) $crumb[] = $this->image; |
|
|
457 |
|
|
|
458 |
return $crumb; |
|
|
459 |
} |
|
|
460 |
|
|
|
461 |
/** |
|
|
462 |
* @return string the complete crumb line with links |
|
|
463 |
*/ |
|
|
464 |
function crumbLineText() |
|
|
465 |
{ |
|
|
466 |
$crumbArray = $this->crumbLineArray(); |
|
|
467 |
|
|
|
468 |
$ret = ""; |
|
|
469 |
for($i=0;$i<count($crumbArray)-1;$i++) |
|
|
470 |
$ret .= $crumbArray[$i]->nameLink()." >\n"; |
|
|
471 |
$ret .= $crumbArray[$i]->nameForce(); |
|
|
472 |
|
|
|
473 |
return $ret; |
|
|
474 |
} |
|
|
475 |
|
|
|
476 |
function crumbLine() |
|
|
477 |
{ |
|
|
478 |
return $this->translator->_g("crumb line|You are here:")." ".$this->crumbLineText(); |
|
|
479 |
} |
|
|
480 |
|
|
|
481 |
/** |
|
|
482 |
* Generates the HTML code for imagemap_navigation |
|
|
483 |
* @return string imagemap HTML code |
|
|
484 |
*/ |
|
|
485 |
function imageMap() |
|
|
486 |
{ |
|
|
487 |
if(!$this->config->imagemap_navigation) return ""; |
|
|
488 |
|
|
|
489 |
$imageWidth = $this->image->width(); |
|
|
490 |
$imageHeight = $this->image->height(); |
|
|
491 |
$middleX = round($imageWidth/2); |
|
|
492 |
$middleY = round($imageHeight/2); |
|
|
493 |
|
|
|
494 |
$ret = "<map name=\"sgNavMap\" id=\"sgNavMap\">\n"; |
|
|
495 |
if($this->image->hasNext()) $ret .= '<area href="'.$this->image->nextURL().'" alt="'.$this->image->nextText().'" title="'.$this->image->nextText().'" shape="poly" '; |
|
|
496 |
else $ret .= '<area href="'.$this->image->parentURL().'" alt="'.$this->image->parentText().'" title="'.$this->image->parentText().'" shape="poly" '; |
|
|
497 |
$ret .= "coords=\"$middleX,$middleY,$imageWidth,$imageHeight,$imageWidth,0,$middleX,$middleY\" />\n"; |
|
|
498 |
if($this->image->hasPrev()) $ret .= '<area href="'.$this->image->prevURL().'" alt="'.$this->image->prevText().'" title="'.$this->image->prevText().'" shape="poly" '; |
|
|
499 |
else $ret .= '<area href="'.$this->image->parentURL().'" alt="'.$this->image->parentText().'" title="'.$this->image->parentText().'" shape="poly" '; |
|
|
500 |
$ret .= "coords=\"$middleX,$middleY,0,0,0,$imageHeight,$middleX,$middleY\" />\n"; |
|
|
501 |
$ret .= '<area href="'.$this->image->parentURL().'" alt="'.$this->image->parentText().'" title="'.$this->image->parentText().'" shape="poly" '; |
|
|
502 |
$ret .= "coords=\"$middleX,$middleY,0,0,$imageWidth,0,$middleX,$middleY\" />\n"; |
|
|
503 |
$ret .= '</map>'; |
|
|
504 |
|
|
|
505 |
return $ret; |
|
|
506 |
} |
|
|
507 |
|
|
|
508 |
/** |
|
|
509 |
* Generates the HTML code for the language select box |
|
|
510 |
* @return string select box HTML code |
|
|
511 |
*/ |
|
|
512 |
function languageFlipper() |
|
|
513 |
{ |
|
|
514 |
if(!$this->config->language_flipper) return ""; |
|
|
515 |
|
|
|
516 |
$languageCache = $this->config->base_path.$this->config->pathto_data_dir."languages.cache"; |
|
|
517 |
// Look for the language file |
|
|
518 |
if(!file_exists($languageCache)) |
|
|
519 |
return ""; |
|
|
520 |
|
|
|
521 |
// Open the file |
|
|
522 |
$fp = @fopen($languageCache, "r"); |
|
|
523 |
if (!$fp) return ""; |
|
|
524 |
|
|
|
525 |
// Read contents |
|
|
526 |
$str = ''; |
|
|
527 |
while (!feof($fp)) $str .= fread($fp, 1024); |
|
|
528 |
// Unserialize |
|
|
529 |
$availableLanguages = @unserialize($str); |
|
|
530 |
|
|
|
531 |
$ret = '<div class="sgLanguageFlipper">'; |
|
|
532 |
$ret .= '<form method="get" action="'.$_SERVER["PHP_SELF"]."\">\n"; |
|
|
533 |
//carry over current get vars |
|
|
534 |
foreach($_GET as $var => $val) |
|
|
535 |
$ret .= '<input type="hidden" name="'.$var.'" value="'.htmlspecialchars($val)."\" />\n"; |
|
|
536 |
$ret .= '<select name="'.$this->config->url_lang."\">\n"; |
|
|
537 |
$ret .= ' <option value="'.$this->config->default_language.'">'.$this->translator->_g("Select language...")."</option>\n"; |
|
|
538 |
foreach($availableLanguages as $code => $name) { |
|
|
539 |
$ret .= ' <option value="'.$code.'"'; |
|
|
540 |
if($code == $this->language && $this->language != $this->config->default_language) |
|
|
541 |
$ret .= 'selected="true" '; |
|
|
542 |
$ret .= '>'.htmlentities($name)."</option>\n"; |
|
|
543 |
} |
|
|
544 |
$ret .= "</select>\n"; |
|
|
545 |
$ret .= '<input type="submit" class="button" value="'.$this->translator->_g("Go")."\" />\n"; |
|
|
546 |
$ret .= "</form></div>\n"; |
|
|
547 |
return $ret; |
|
|
548 |
} |
|
|
549 |
|
|
|
550 |
/** |
|
|
551 |
* Generates the HTML code for the template select box |
|
|
552 |
* @return string select box HTML code |
|
|
553 |
*/ |
|
|
554 |
function templateFlipper() |
|
|
555 |
{ |
|
|
556 |
if(!$this->config->template_flipper) return ""; |
|
|
557 |
|
|
|
558 |
//get list of installed templates |
|
|
559 |
$templates = Singapore::getListing($this->config->base_path.$this->config->pathto_templates, "dirs"); |
|
|
560 |
|
|
|
561 |
$ret = '<div class="sgTemplateFlipper">'; |
|
|
562 |
$ret .= '<form method="get" action="'.$_SERVER["PHP_SELF"]."\">\n"; |
|
|
563 |
//carry over current get vars |
|
|
564 |
foreach($_GET as $var => $val) |
|
|
565 |
$ret .= '<input type="hidden" name="'.$var.'" value="'.htmlspecialchars($val)."\" />\n"; |
|
|
566 |
$ret .= '<select name="'.$this->config->url_template."\">\n"; |
|
|
567 |
$ret .= ' <option value="'.$this->config->default_template.'">'.$this->translator->_g("Select template...")."</option>\n"; |
|
|
568 |
foreach($templates->dirs as $name) |
|
|
569 |
//do not list admin template(s) |
|
|
570 |
if(strpos($name, "admin_")===false) { |
|
|
571 |
$ret .= ' <option value="'.$name.'"'; |
|
|
572 |
if($name == $this->template && $this->template != $this->config->default_template) |
|
|
573 |
$ret .= 'selected="true" '; |
|
|
574 |
$ret .= '>'.$name."</option>\n"; |
|
|
575 |
} |
|
|
576 |
$ret .= "</select>\n"; |
|
|
577 |
$ret .= '<input type="submit" class="button" value="'.$this->translator->_g("Go")."\" />\n"; |
|
|
578 |
$ret .= "</form></div>\n"; |
|
|
579 |
return $ret; |
|
|
580 |
} |
|
|
581 |
|
|
|
582 |
|
|
|
583 |
/** |
|
|
584 |
* @param string $seperator optional string to seperate the Gallery Tab Links |
|
|
585 |
* @return string |
|
|
586 |
*/ |
|
|
587 |
function galleryTab($seperator = " | ") |
|
|
588 |
{ |
|
|
589 |
$showing = $this->galleryTabShowing(); |
|
|
590 |
return Singapore::conditional($this->galleryTabLinks(), $showing.$seperator."%s", $showing); |
|
|
591 |
} |
|
|
592 |
|
|
|
593 |
/** |
|
|
594 |
* @return string |
|
|
595 |
*/ |
|
|
596 |
function galleryTabShowing() |
|
|
597 |
{ |
|
|
598 |
if($this->isAlbumPage()) { |
|
|
599 |
$total = $this->gallery->imageCount(); |
|
|
600 |
$perPage = $this->config->thumb_number_album; |
|
|
601 |
} else { |
|
|
602 |
$total = $this->gallery->galleryCount(); |
|
|
603 |
$perPage = $this->config->thumb_number_gallery; |
|
|
604 |
} |
|
|
605 |
|
|
|
606 |
if($this->gallery->startat+$perPage > $total) |
|
|
607 |
$last = $total; |
|
|
608 |
else |
|
|
609 |
$last = $this->gallery->startat+$perPage; |
|
|
610 |
|
|
|
611 |
return $this->translator->_g("Showing %s-%s of %s",($this->gallery->startat+1),$last,$total); |
|
|
612 |
} |
|
|
613 |
|
|
|
614 |
/** |
|
|
615 |
* @return string |
|
|
616 |
*/ |
|
|
617 |
function galleryTabLinks() |
|
|
618 |
{ |
|
|
619 |
$ret = ""; |
|
|
620 |
if($this->hasPrevPage()) |
|
|
621 |
$ret .= $this->prevPageLink()." "; |
|
|
622 |
|
|
|
623 |
//This is for compatibility with old templates |
|
|
624 |
//it detects if compatibility mode is on using method_exists() |
|
|
625 |
if(!$this->gallery->isRoot() && method_exists($this, 'galleryName')) |
|
|
626 |
$ret .= $this->gallery->parentLink(); |
|
|
627 |
|
|
|
628 |
if($this->hasNextPage()) |
|
|
629 |
$ret .= " ".$this->nextPageLink(); |
|
|
630 |
|
|
|
631 |
return $ret; |
|
|
632 |
} |
|
|
633 |
|
|
|
634 |
function navigationLinks() { |
|
|
635 |
$ret = "<link rel=\"Top\" title=\"".$this->config->gallery_name."\" href=\"".$this->ancestors[0]->URL()."\" />\n"; |
|
|
636 |
|
|
|
637 |
if($this->isImagePage()) { |
|
|
638 |
$ret .= "<link rel=\"Up\" title=\"".$this->image->parent->name()."\" href=\"".$this->image->parent->URL()."\" />\n"; |
|
|
639 |
if ($this->image->hasPrev()) { |
|
|
640 |
$first= $this->image->firstImage(); |
|
|
641 |
$prev = $this->image->prevImage(); |
|
|
642 |
$ret .= "<link rel=\"First\" title=\"".$first->name()."\" href=\"".$first->URL()."\" />\n"; |
|
|
643 |
$ret .= "<link rel=\"Prev\" title=\"".$prev->name()."\" href=\"".$prev->URL()."\" />\n"; |
|
|
644 |
} |
|
|
645 |
if ($this->image->hasNext()) { |
|
|
646 |
$next = $this->image->nextImage(); |
|
|
647 |
$last = $this->image->lastImage(); |
|
|
648 |
$ret .= "<link rel=\"Next\" title=\"".$next->name()."\" href=\"".$next->URL()."\" />\n"; |
|
|
649 |
$ret .= "<link rel=\"Last\" title=\"".$last->name()."\" href=\"".$last->URL()."\" />\n"; |
|
|
650 |
//prefetch next image |
|
|
651 |
$ret .= "<link rel=\"Prefetch\" href=\"".$next->imageURL()."\" />\n"; |
|
|
652 |
} |
|
|
653 |
} else { |
|
|
654 |
if(!$this->gallery->isRoot()) |
|
|
655 |
$ret .= "<link rel=\"Up\" title=\"".$this->gallery->parent->name()."\" href=\"".$this->gallery->parent->URL()."\" />\n"; |
|
|
656 |
if($this->hasPrevPage()) { |
|
|
657 |
$ret .= "<link rel=\"Prev\" title=\"".$this->translator->_g("gallery|Previous")."\" href=\"".$this->prevPageURL()."\" />\n"; |
|
|
658 |
$ret .= "<link rel=\"First\" title=\"".$this->translator->_g("gallery|First")."\" href=\"".$this->firstPageURL()."\" />\n"; |
|
|
659 |
} |
|
|
660 |
if($this->hasNextPage()) { |
|
|
661 |
$ret .= "<link rel=\"Next\" title=\"".$this->translator->_g("gallery|Next")."\" href=\"".$this->nextPageURL()."\" />\n"; |
|
|
662 |
$ret .= "<link rel=\"Last\" title=\"".$this->translator->_g("gallery|Last")."\" href=\"".$this->lastPageURL()."\" />\n"; |
|
|
663 |
} |
|
|
664 |
} |
|
|
665 |
return $ret; |
|
|
666 |
} |
|
|
667 |
|
|
|
668 |
|
|
|
669 |
/** |
|
|
670 |
* @return int the number of 'pages' or 'screen-fulls' |
|
|
671 |
*/ |
|
|
672 |
function galleryPageCount() { |
|
|
673 |
if($this->isAlbumPage()) |
|
|
674 |
return intval($this->gallery->imageCount()/$this->config->thumb_number_album)+1; |
|
|
675 |
else |
|
|
676 |
return intval($this->gallery->galleryCount()/$this->config->thumb_number_gallery)+1; |
|
|
677 |
} |
|
|
678 |
|
|
|
679 |
/** |
|
|
680 |
* @return int |
|
|
681 |
*/ |
|
|
682 |
function lastPageIndex() { |
|
|
683 |
if($this->isAlbumPage()) |
|
|
684 |
return ($this->galleryPageCount()-1)* |
|
|
685 |
($this->isAlbumPage()?$this->config->thumb_number_album:$this->config->thumb_number_gallery); |
|
|
686 |
} |
|
|
687 |
|
|
|
688 |
/** |
|
|
689 |
* @return bool true if there is at least one more page |
|
|
690 |
*/ |
|
|
691 |
function hasNextPage() { |
|
|
692 |
if($this->isAlbumPage()) |
|
|
693 |
return count($this->gallery->images)>$this->startat+$this->config->thumb_number_album; |
|
|
694 |
elseif($this->isGalleryPage()) |
|
|
695 |
return count($this->gallery->galleries)>$this->startat+$this->config->thumb_number_gallery; |
|
|
696 |
elseif($this->isImagePage()) |
|
|
697 |
return isset($this->gallery->images[$this->image->index+1]); |
|
|
698 |
} |
|
|
699 |
|
|
|
700 |
/** |
|
|
701 |
* @return bool true if there is at least one previous page |
|
|
702 |
*/ |
|
|
703 |
function hasPrevPage() { |
|
|
704 |
if($this->isAlbumPage() || $this->isGalleryPage()) |
|
|
705 |
return $this->startat > 0; |
|
|
706 |
elseif($this->isImagePage()) |
|
|
707 |
return isset($this->gallery->images[$this->image->index-1]); |
|
|
708 |
} |
|
|
709 |
|
|
|
710 |
function firstPageURL() { |
|
|
711 |
return $this->gallery->URL(0); |
|
|
712 |
} |
|
|
713 |
|
|
|
714 |
function firstPageLink() { |
|
|
715 |
return "<a href=\"".$this->firstPageURL()."\">".$this->translator->_g("First %s", $this->itemsPerPage())."</a>"; |
|
|
716 |
} |
|
|
717 |
|
|
|
718 |
/** |
|
|
719 |
* @return string the URL of the previous page |
|
|
720 |
*/ |
|
|
721 |
function prevPageURL() { |
|
|
722 |
return $this->gallery->URL($this->startat - $this->itemsPerPage()); |
|
|
723 |
} |
|
|
724 |
|
|
|
725 |
function prevPageLink() { |
|
|
726 |
return "<a href=\"".$this->prevPageURL()."\">".$this->translator->_g("Previous %s", $this->itemsPerPage())."</a>"; |
|
|
727 |
} |
|
|
728 |
|
|
|
729 |
/** |
|
|
730 |
* @return string the URL of the next page |
|
|
731 |
*/ |
|
|
732 |
function nextPageURL() { |
|
|
733 |
return $this->gallery->URL($this->startat + $this->itemsPerPage()); |
|
|
734 |
} |
|
|
735 |
|
|
|
736 |
function nextPageLink() { |
|
|
737 |
return "<a href=\"".$this->nextPageURL()."\">".$this->translator->_g("Next %s", $this->itemsPerPage())."</a>"; |
|
|
738 |
} |
|
|
739 |
|
|
|
740 |
function lastPageURL() { |
|
|
741 |
$perpage = $this->isAlbumPage() ? $this->config->thumb_number_album : $this->config->thumb_number_gallery; |
|
|
742 |
return $this->gallery->URL(floor($this->gallery->itemCount() / $perpage) * $perpage); |
|
|
743 |
} |
|
|
744 |
|
|
|
745 |
function lastPageLink() { |
|
|
746 |
return "<a href=\"".$this->lastPageURL()."\">".$this->translator->_g("Last %s", $this->itemsPerPage())."</a>"; |
|
|
747 |
} |
|
|
748 |
|
|
|
749 |
function itemsPerPage() |
|
|
750 |
{ |
|
|
751 |
return $this->isAlbumPage() ? $this->config->thumb_number_album : $this->config->thumb_number_gallery; |
|
|
752 |
} |
|
|
753 |
|
|
|
754 |
/** |
|
|
755 |
* @return string link for adding a comment to image |
|
|
756 |
*/ |
|
|
757 |
function imageCommentLink() |
|
|
758 |
{ |
|
|
759 |
return "<a href=\"". |
|
|
760 |
$this->formatURL($this->gallery->idEncoded(), $this->image->id, null, "addcomment"). |
|
|
761 |
"\">".$this->translator->_g("Add a comment")."</a>"; |
|
|
762 |
} |
|
|
763 |
|
|
|
764 |
/** |
|
|
765 |
* @return array array of sgImage objects |
|
|
766 |
*/ |
|
|
767 |
function &previewThumbnailsArray() |
|
|
768 |
{ |
|
|
769 |
$ret = array(); |
|
|
770 |
$index = $this->image->index(); |
|
|
771 |
$start = ceil($index - $this->config->thumb_number_preview/2); |
|
|
772 |
|
|
|
773 |
for($i = $start; $i < $start + $this->config->thumb_number_preview; $i++) |
|
|
774 |
if(isset($this->image->parent->images[$i])) |
|
|
775 |
$ret[$i] =& $this->image->parent->images[$i]; |
|
|
776 |
|
|
|
777 |
return $ret; |
|
|
778 |
} |
|
|
779 |
|
|
|
780 |
function previewThumbnails() |
|
|
781 |
{ |
|
|
782 |
$thumbs =& $this->previewThumbnailsArray(); |
|
|
783 |
$index = $this->image->index(); |
|
|
784 |
$ret = ""; |
|
|
785 |
foreach($thumbs as $key => $thumb) { |
|
|
786 |
$thumbClass = "sgThumbnailPreview"; |
|
|
787 |
if($key==$index-1) $thumbClass .= " sgThumbnailPreviewPrev"; |
|
|
788 |
elseif($key==$index) $thumbClass .= " sgThumbnailPreviewCurrent"; |
|
|
789 |
elseif($key==$index+1) $thumbClass .= " sgThumbnailPreviewNext"; |
|
|
790 |
$ret .= $thumb->thumbnailLink($thumbClass, "preview")."\n"; |
|
|
791 |
} |
|
|
792 |
|
|
|
793 |
return $ret; |
|
|
794 |
} |
|
|
795 |
|
|
|
796 |
////////////////////////////// |
|
|
797 |
//////ex-sgUtils methods////// |
|
|
798 |
////////////////////////////// |
|
|
799 |
|
|
|
800 |
/** |
|
|
801 |
* Callback function for sorting things |
|
|
802 |
* @static |
|
|
803 |
*/ |
|
|
804 |
function multiSort($a, $b) { |
|
|
805 |
switch($GLOBALS["sgSortOrder"]) { |
|
|
806 |
case "f" : |
|
|
807 |
case "p" : return strcmp($a->id, $b->id); //path |
|
|
808 |
case "F" : |
|
|
809 |
case "P" : return strcmp($b->id, $a->id); //path (reverse) |
|
|
810 |
case "n" : return strcmp($a->name, $b->name); //name |
|
|
811 |
case "N" : return strcmp($b->name, $a->name); //name (reverse) |
|
|
812 |
case "i" : return strcasecmp($a->name, $b->name); //case-insensitive name |
|
|
813 |
case "I" : return strcasecmp($b->name, $a->name); //case-insensitive name (reverse) |
|
|
814 |
case "a" : return strcmp($a->artist, $b->artist); //artist |
|
|
815 |
case "A" : return strcmp($b->artist, $a->artist); //artist (reverse) |
|
|
816 |
case "d" : return strcmp($a->date, $b->date); //date |
|
|
817 |
case "D" : return strcmp($b->date, $a->date); //date (reverse) |
|
|
818 |
case "l" : return strcmp($a->location, $b->location); //location |
|
|
819 |
case "L" : return strcmp($b->location, $a->location); //location (reverse) |
|
|
820 |
} |
|
|
821 |
} |
|
|
822 |
|
|
|
823 |
/** |
|
|
824 |
* Slightly pointless method |
|
|
825 |
*/ |
|
|
826 |
function conditional($conditional, $iftrue, $iffalse = null) |
|
|
827 |
{ |
|
|
828 |
if($conditional) return sprintf($iftrue, $conditional); |
|
|
829 |
elseif($iffalse != null) return sprintf($iffalse, $conditional); |
|
|
830 |
else return ""; |
|
|
831 |
} |
|
|
832 |
|
|
|
833 |
/** |
|
|
834 |
* Callback function for recursively stripping slashes |
|
|
835 |
* @static |
|
|
836 |
*/ |
|
|
837 |
function arraystripslashes($toStrip) |
|
|
838 |
{ |
|
|
839 |
if(is_array($toStrip)) |
|
|
840 |
return array_map(array("Singapore","arraystripslashes"), $toStrip); |
|
|
841 |
else |
|
|
842 |
return stripslashes($toStrip); |
|
|
843 |
} |
|
|
844 |
|
|
|
845 |
function thumbnailPath($gallery, $image, $width, $height, $forceSize, $mode = 1) |
|
|
846 |
{ |
|
|
847 |
$config =& sgConfig::getInstance(); |
|
|
848 |
switch($mode) { |
|
|
849 |
case 0 : |
|
|
850 |
return $config->pathto_data_dir."cache/".$width."x".$height.($forceSize?"f":"").strtr("-$gallery-$image",":/?\\","----"); |
|
|
851 |
case 1 : |
|
|
852 |
return $config->pathto_galleries.$gallery."/_thumbs/".$width."x".$height.($forceSize?"f":"").strtr("-$image",":/?\\","----"); |
|
|
853 |
} |
|
|
854 |
} |
|
|
855 |
|
|
|
856 |
/** |
|
|
857 |
* @param string relative or absolute path to directory |
|
|
858 |
* @param string regular expression of files to return (optional) |
|
|
859 |
* @param bool true to get hidden directories too |
|
|
860 |
* @returns stdClass|false a data object representing the directory and its contents |
|
|
861 |
* @static |
|
|
862 |
*/ |
|
|
863 |
function getListing($wd, $mask = null, $getHidden = false) |
|
|
864 |
{ |
|
|
865 |
$dir = new stdClass; |
|
|
866 |
$dir->path = realpath($wd)."/"; |
|
|
867 |
$dir->files = array(); |
|
|
868 |
$dir->dirs = array(); |
|
|
869 |
|
|
|
870 |
$dp = opendir($dir->path); |
|
|
871 |
if(!$dp) return false; |
|
|
872 |
|
|
|
873 |
while(false !== ($entry = readdir($dp))) |
|
|
874 |
if(is_dir($dir->path.$entry)) { |
|
|
875 |
if(($entry{0} != '.' && $entry{0} != '_') || $getHidden) |
|
|
876 |
$dir->dirs[] = $entry; |
|
|
877 |
} else { |
|
|
878 |
if($mask == null || preg_match("/\.($mask)$/i",$entry)) |
|
|
879 |
$dir->files[] = $entry; |
|
|
880 |
} |
|
|
881 |
|
|
|
882 |
sort($dir->files); |
|
|
883 |
sort($dir->dirs); |
|
|
884 |
closedir($dp); |
|
|
885 |
return $dir; |
|
|
886 |
} |
|
|
887 |
|
|
|
888 |
/** |
|
|
889 |
* Recursively deletes all directories and files in the specified directory. |
|
|
890 |
* USE WITH EXTREME CAUTION!! |
|
|
891 |
* @returns boolean true on success; false otherwise |
|
|
892 |
* @static |
|
|
893 |
*/ |
|
|
894 |
function rmdir_all($wd) |
|
|
895 |
{ |
|
|
896 |
if(!$dp = opendir($wd)) return false; |
|
|
897 |
$success = true; |
|
|
898 |
while(false !== ($entry = readdir($dp))) { |
|
|
899 |
if($entry == "." || $entry == "..") continue; |
|
|
900 |
if(is_dir("$wd/$entry")) $success &= Singapore::rmdir_all("$wd/$entry"); |
|
|
901 |
else $success &= unlink("$wd/$entry"); |
|
|
902 |
} |
|
|
903 |
closedir($dp); |
|
|
904 |
$success &= rmdir($wd); |
|
|
905 |
return $success; |
|
|
906 |
} |
|
|
907 |
|
|
|
908 |
/** |
|
|
909 |
* Returns an array of language codes specified in the Accept-Language HHTP |
|
|
910 |
* header field of the user's browser. q= components are ignored and removed. |
|
|
911 |
* hyphens (-) are converted to underscores (_). |
|
|
912 |
* @return array accepted language codes |
|
|
913 |
* @static |
|
|
914 |
*/ |
|
|
915 |
function getBrowserLanguages() |
|
|
916 |
{ |
|
|
917 |
$langs = array(); |
|
|
918 |
foreach(explode(",",$_SERVER["HTTP_ACCEPT_LANGUAGE"]) as $bit) |
|
|
919 |
if($pos = strpos($bit,";")) |
|
|
920 |
$langs[] = strtr(substr($bit,0,$pos),"-","_"); |
|
|
921 |
else |
|
|
922 |
$langs[] = strtr($bit,"-","_"); |
|
|
923 |
return $langs; |
|
|
924 |
} |
|
|
925 |
|
|
|
926 |
/** |
|
|
927 |
* Wrapper for mkdir() implementing the safe-mode hack |
|
|
928 |
*/ |
|
|
929 |
function mkdir($path) |
|
|
930 |
{ |
|
|
931 |
$config =& sgConfig::getInstance(); |
|
|
932 |
if($config->safe_mode_hack) { |
|
|
933 |
$connection = ftp_connect($config->ftp_server); |
|
|
934 |
// login to ftp server |
|
|
935 |
$result = ftp_login($connection, $config->ftp_user, $config->ftp_pass); |
|
|
936 |
|
|
|
937 |
// check if connection was made |
|
|
938 |
if ((!$connection) || (!$result)) |
|
|
939 |
return false; |
|
|
940 |
|
|
|
941 |
ftp_chdir($connection, $config->ftp_base_path); // go to destination dir |
|
|
942 |
if(!ftp_mkdir($connection, $path)) // create directory |
|
|
943 |
return false; |
|
|
944 |
|
|
|
945 |
ftp_site($connection, "CHMOD ".$config->directory_mode." ".$path); |
|
|
946 |
ftp_close($connection); // close connection |
|
|
947 |
return true; |
|
|
948 |
} else |
|
|
949 |
return mkdir($path, octdec($config->directory_mode)); |
|
|
950 |
} |
|
|
951 |
|
|
|
952 |
/** |
|
|
953 |
* Tests if $child is within or is the same path as $parent. |
|
|
954 |
* |
|
|
955 |
* @param string path to parent directory |
|
|
956 |
* @param string path to child directory or file |
|
|
957 |
* @param bool set false to prevent canonicalisation of paths (optional) |
|
|
958 |
* @return bool true if $child is contained within or is $parent |
|
|
959 |
*/ |
|
|
960 |
function isSubPath($parent, $child, $canonicalise = true) |
|
|
961 |
{ |
|
|
962 |
$parentPath = $canonicalise ? realpath($parent) : $parent; |
|
|
963 |
$childPath = $canonicalise ? realpath($child) : $child; |
|
|
964 |
return $parentPath && $childPath && substr($childPath,0,strlen($parentPath)) == $parentPath; |
|
|
965 |
} |
|
|
966 |
|
|
|
967 |
|
|
|
968 |
function isInGroup($groups1,$groups2) |
|
|
969 |
{ |
|
|
970 |
return (bool) array_intersect(explode(" ",$groups1),explode(" ",$groups2)); |
|
|
971 |
} |
|
|
972 |
|
|
|
973 |
} |
|
|
974 |
|
|
|
975 |
|
|
|
976 |
?> |