1: <?php
   2:    3:    4:    5:    6:    7: 
   8: 
   9: 
  10: global $_zp_current_context_stack, $_zp_HTML_cache;
  11: 
  12: if (!function_exists("json_encode")) {
  13:     
  14:     require_once(dirname(__FILE__) . '/lib-json.php');
  15: }
  16: 
  17: require_once(dirname(__FILE__) . '/functions-basic.php');
  18: require_once(dirname(__FILE__) . '/functions-filter.php');
  19: require_once(SERVERPATH . '/' . ZENFOLDER . '/lib-kses.php');
  20: 
  21: $_zp_captcha = new _zp_captcha(); 
  22: $_zp_HTML_cache = new _zp_HTML_cache(); 
  23: 
  24: require_once(dirname(__FILE__) . '/functions-i18n.php');
  25: 
  26: if (GALLERY_SESSION) {
  27:     zp_session_start();
  28: }
  29: 
  30: define('ZENPHOTO_LOCALE', setMainDomain());
  31: define('SITE_LOCALE', getOptionFromDB('locale'));
  32: 
  33: require_once(dirname(__FILE__) . '/load_objectClasses.php');
  34: 
  35: $_zp_current_context_stack = array();
  36: 
  37: $_zp_albumthumb_selector = array(array('field' => '', 'direction' => '', 'desc' => 'random'),
  38:                 array('field' => 'id', 'direction' => 'DESC', 'desc' => gettext('most recent')),
  39:                 array('field' => 'mtime', 'direction' => '', 'desc' => gettext('oldest')),
  40:                 array('field' => 'title', 'direction' => '', 'desc' => gettext('first alphabetically')),
  41:                 array('field' => 'hitcounter', 'direction' => 'DESC', 'desc' => gettext('most viewed'))
  42: );
  43: 
  44: $_zp_missing_album = new AlbumBase(gettext('missing'), false);
  45: $_zp_missing_image = new Transientimage($_zp_missing_album, SERVERPATH . '/' . ZENFOLDER . '/images/err-imagenotfound.png');
  46: 
  47:   48:   49:   50:   51:   52:   53: 
  54: function parseAllowedTags(&$source) {
  55:     $source = trim($source);
  56:     if (substr($source, 0, 1) != "(") {
  57:         return false;
  58:     }
  59:     $source = substr($source, 1); 
  60:     $a = array();
  61:     while ((strlen($source) > 1) && (substr($source, 0, 1) != ")")) {
  62:         $i = strpos($source, '=>');
  63:         if ($i === false) {
  64:             return false;
  65:         }
  66:         $tag = trim(substr($source, 0, $i));
  67:         
  68:         if ($tag == 'script') {
  69:             return 0;
  70:         }
  71:         $source = trim(substr($source, $i + 2));
  72:         if (substr($source, 0, 1) != "(") {
  73:             return false;
  74:         }
  75:         $x = parseAllowedTags($source);
  76:         if ($x === false) {
  77:             return false;
  78:         }
  79:         $a[$tag] = $x;
  80:     }
  81:     if (substr($source, 0, 1) != ')') {
  82:         return false;
  83:     }
  84:     $source = trim(substr($source, 1)); 
  85:     return $a;
  86: }
  87: 
  88:   89:   90:   91:   92:   93: 
  94: function checkObjectsThumb($localpath) {
  95:     global $_zp_supported_images;
  96:     $image = stripSuffix($localpath);
  97:     $candidates = safe_glob($image . '.*');
  98:     foreach ($candidates as $file) {
  99:         $ext = substr($file, strrpos($file, '.') + 1);
 100:         if (in_array(strtolower($ext), $_zp_supported_images)) {
 101:             return basename($image . '.' . $ext);
 102:         }
 103:     }
 104:     return NULL;
 105: }
 106: 
 107:  108:  109:  110:  111:  112:  113:  114: 
 115: function truncate_string($string, $length, $elipsis = '...') {
 116:     if (mb_strlen($string) > $length) {
 117:         $string = mb_substr($string, 0, $length);
 118:         $pos = mb_strrpos(strtr($string, array('~' => ' ', '!' => ' ', '@' => ' ', '#' => ' ', '$' => ' ', '%' => ' ', '^' => ' ', '&' => ' ', '*' => ' ', '(' => ' ', ')' => ' ', '+' => ' ', '=' => ' ', '-' => ' ', '{' => ' ', '}' => ' ', '[' => ' ', ']' => ' ', '|' => ' ', ':' => ' ', ';' => ' ', '<' => ' ', '>' => ' ', '.' => ' ', '?' => ' ', '/' => ' ', '\\', '\\' => ' ', "'" => ' ', "`" => ' ', '"' => ' ')), ' ');
 119:         if ($pos === FALSE) {
 120:             $string .= $elipsis;
 121:         } else {
 122:             $string = mb_substr($string, 0, $pos) . $elipsis;
 123:         }
 124:     }
 125:     return $string;
 126: }
 127: 
 128:  129:  130:  131:  132:  133: 
 134: function cleanHTML($html) {
 135: 
 136:     preg_match_all('#<(?!meta|img|br|hr|input\b)\b([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result);
 137:     $openedtags = $result[1];
 138: 
 139:     preg_match_all('#</([a-z]+)>#iU', $html, $result);
 140:     $closedtags = $result[1];
 141: 
 142:     $len_opened = count($openedtags);
 143: 
 144:     if (count($closedtags) == $len_opened) {
 145:         return $html;
 146:     }
 147: 
 148:     $openedtags = array_reverse($openedtags);
 149:     for ($i = 0; $i < $len_opened; $i++) {
 150:         if (!in_array($openedtags[$i], $closedtags)) {
 151:             $html .= '</' . $openedtags[$i] . '>';
 152:         } else {
 153:             unset($closedtags[array_search($openedtags[$i], $closedtags)]);
 154:         }
 155:     }
 156: 
 157:     return $html;
 158: }
 159: 
 160:  161:  162:  163:  164:  165:  166:  167:  168: 
 169: function shortenContent($articlecontent, $shorten, $shortenindicator, $forceindicator = false) {
 170:     global $_user_tags;
 171:     if ($shorten && ($forceindicator || (mb_strlen($articlecontent) > $shorten))) {
 172:         $allowed_tags = getAllowedTags('allowed_tags');
 173:         
 174:         $articlecontent = preg_replace('~<script.*?/script>~is', '', $articlecontent);
 175:         
 176:         $articlecontent = preg_replace('~<!--.*?-->~is', '', $articlecontent);
 177:         $short = mb_substr($articlecontent, 0, $shorten);
 178:         $short2 = kses($short . '</p>', $allowed_tags);
 179: 
 180:         if (($l2 = mb_strlen($short2)) < $shorten) {
 181:             $c = 0;
 182:             $l1 = $shorten;
 183:             $delta = $shorten - $l2;
 184:             while ($l2 < $shorten && $c++ < 5) {
 185:                 $open = mb_strrpos($short, '<');
 186:                 if ($open > mb_strrpos($short, '>')) {
 187:                     $l1 = mb_strpos($articlecontent, '>', $l1 + 1) + $delta;
 188:                 } else {
 189:                     $l1 = $l1 + $delta;
 190:                 }
 191:                 $short = mb_substr($articlecontent, 0, $l1);
 192:                 preg_match_all('/(<p>)/', $short, $open);
 193:                 preg_match_all('/(<\/p>)/', $short, $close);
 194:                 if (count($open) > count($close))
 195:                     $short .= '</p>';
 196:                 $short2 = kses($short, $allowed_tags);
 197:                 $l2 = mb_strlen($short2);
 198:             }
 199:             $shorten = $l1;
 200:         }
 201:         $short = truncate_string($articlecontent, $shorten, '');
 202:         if ($short != $articlecontent) { 
 203:             
 204:             $open = mb_strrpos($short, '<');
 205:             if ($open > mb_strrpos($short, '>')) {
 206:                 $short = mb_substr($short, 0, $open);
 207:             }
 208:             if (class_exists('tidy')) {
 209:                 $short = zpFunctions::tidyHTML($short . $shortenindicator);
 210:             } else {
 211:                 $short = trim(cleanHTML($short . $shortenindicator));
 212:             }
 213:         }
 214:         $articlecontent = $short;
 215:     }
 216:     if (isset($matches)) {
 217:         
 218:         foreach ($matches[0] as $script) {
 219:             $articlecontent = $script . $articlecontent;
 220:         }
 221:     }
 222:     return $articlecontent;
 223: }
 224: 
 225:  226:  227:  228:  229:  230: 
 231: function getUrAlbum($album) {
 232:     if (!is_object($album))
 233:         return NULL;
 234:     while (true) {
 235:         $parent = $album->getParent();
 236:         if (is_null($parent)) {
 237:             return $album;
 238:         }
 239:         $album = $parent;
 240:     }
 241: }
 242: 
 243:  244:  245:  246:  247:  248:  249:  250:  251:  252: 
 253: function lookupSortKey($sorttype, $default, $table) {
 254:     global $_zp_fieldLists;
 255:     switch (strtolower($sorttype)) {
 256:         case 'random':
 257:             return 'RAND()';
 258:         case "manual":
 259:             return '`sort_order`';
 260:         case "filename":
 261:             switch ($table) {
 262:                 case 'images':
 263:                     return '`filename`';
 264:                 case 'albums':
 265:                     return '`folder`';
 266:             }
 267:         default:
 268:             if (empty($sorttype)) {
 269:                 return '`' . $default . '`';
 270:             }
 271:             if (substr($sorttype, 0) == '(') {
 272:                 return $sorttype;
 273:             }
 274:             if (is_array($_zp_fieldLists) && isset($_zp_fieldLists[$table])) {
 275:                 $dbfields = $_zp_fieldLists[$table];
 276:             } else {
 277:                 $result = db_list_fields($table);
 278:                 $dbfields = array();
 279:                 if ($result) {
 280:                     foreach ($result as $row) {
 281:                         $dbfields[strtolower($row['Field'])] = $row['Field'];
 282:                     }
 283:                 }
 284:                 $_zp_fieldLists[$table] = $dbfields;
 285:             }
 286:             $sorttype = strtolower($sorttype);
 287:             $list = explode(',', $sorttype);
 288:             foreach ($list as $key => $field) {
 289:                 if (array_key_exists($field, $dbfields)) {
 290:                     $list[$key] = '`' . trim($dbfields[$field]) . '`';
 291:                 }
 292:             }
 293:             return implode(',', $list);
 294:     }
 295: }
 296: 
 297:  298:  299:  300:  301:  302:  303: 
 304: function zpFormattedDate($format, $dt) {
 305:     global $_zp_UTF8;
 306:     $fdate = strftime($format, $dt);
 307:     $charset = 'ISO-8859-1';
 308:     $outputset = LOCAL_CHARSET;
 309:     if (function_exists('mb_internal_encoding')) {
 310:         if (($charset = mb_internal_encoding()) == $outputset) {
 311:             return $fdate;
 312:         }
 313:     }
 314:     return $_zp_UTF8->convert($fdate, $charset, $outputset);
 315: }
 316: 
 317:  318:  319:  320:  321:  322:  323: 
 324: function myts_date($format, $mytimestamp) {
 325:     $timezoneadjust = getOption('time_offset');
 326: 
 327:     $month = substr($mytimestamp, 4, 2);
 328:     $day = substr($mytimestamp, 6, 2);
 329:     $year = substr($mytimestamp, 0, 4);
 330: 
 331:     $hour = substr($mytimestamp, 8, 2);
 332:     $min = substr($mytimestamp, 10, 2);
 333:     $sec = substr($mytimestamp, 12, 2);
 334: 
 335:     $epoch = mktime($hour + $timezoneadjust, $min, $sec, $month, $day, $year);
 336:     $date = zpFormattedDate($format, $epoch);
 337:     return $date;
 338: }
 339: 
 340:  341:  342:  343:  344:  345:  346: 
 347: function is_valid_email_zp($input_email) {
 348:     $chars = "/^([a-z0-9+_]|\\-|\\.)+@(([a-z0-9_]|\\-)+\\.)+[a-z]{2,6}\$/i";
 349:     if (strstr($input_email, '@') && strstr($input_email, '.')) {
 350:         if (preg_match($chars, $input_email)) {
 351:             return true;
 352:         }
 353:     }
 354:     return false;
 355: }
 356: 
 357:  358:  359:  360:  361:  362:  363:  364:  365:  366:  367:  368:  369:  370:  371:  372: 
 373: function zp_mail($subject, $message, $email_list = NULL, $cc_addresses = NULL, $bcc_addresses = NULL, $replyTo = NULL) {
 374:     global $_zp_authority, $_zp_gallery, $_zp_UTF8;
 375:     $result = '';
 376:     if ($replyTo) {
 377:         $t = $replyTo;
 378:         if (!is_valid_email_zp($m = array_shift($t))) {
 379:             if (empty($result)) {
 380:                 $result = gettext('Mail send failed.');
 381:             }
 382:             $result .= sprintf(gettext('Invalid “reply-to” mail address %s.'), $m);
 383:         }
 384:     }
 385:     if (is_null($email_list)) {
 386:         $email_list = $_zp_authority->getAdminEmail();
 387:     } else {
 388:         foreach ($email_list as $key => $email) {
 389:             if (!is_valid_email_zp($email)) {
 390:                 unset($email_list[$key]);
 391:                 if (empty($result)) {
 392:                     $result = gettext('Mail send failed.');
 393:                 }
 394:                 $result .= ' ' . sprintf(gettext('Invalid “to” mail address %s.'), $email);
 395:             }
 396:         }
 397:     }
 398:     if (is_null($cc_addresses)) {
 399:         $cc_addresses = array();
 400:     } else {
 401:         if (empty($email_list) && !empty($cc_addresses)) {
 402:             if (empty($result)) {
 403:                 $result = gettext('Mail send failed.');
 404:             }
 405:             $result .= ' ' . gettext('“cc” list provided without “to” address list.');
 406:             return $result;
 407:         }
 408:         foreach ($cc_addresses as $key => $email) {
 409:             if (!is_valid_email_zp($email)) {
 410:                 unset($cc_addresses[$key]);
 411:                 if (empty($result)) {
 412:                     $result = gettext('Mail send failed.');
 413:                 }
 414:                 $result = ' ' . sprintf(gettext('Invalid “cc” mail address %s.'), $email);
 415:             }
 416:         }
 417:     }
 418:     if (is_null($bcc_addresses)) {
 419:         $bcc_addresses = array();
 420:     } else {
 421:         foreach ($bcc_addresses as $key => $email) {
 422:             if (!is_valid_email_zp($email)) {
 423:                 unset($bcc_addresses[$key]);
 424:                 if (empty($result)) {
 425:                     $result = gettext('Mail send failed.');
 426:                 }
 427:                 $result = ' ' . sprintf(gettext('Invalid “bcc” mail address %s.'), $email);
 428:             }
 429:         }
 430:     }
 431:     if (count($email_list) + count($bcc_addresses) > 0) {
 432:         if (zp_has_filter('sendmail')) {
 433: 
 434:             $from_mail = getOption('site_email');
 435:             $from_name = get_language_string(getOption('site_email_name'));
 436: 
 437:             
 438:             if (LOCAL_CHARSET != 'UTF-8') {
 439:                 $subject = $_zp_UTF8->convert($subject, LOCAL_CHARSET);
 440:                 $message = $_zp_UTF8->convert($message, LOCAL_CHARSET);
 441:             }
 442: 
 443:             
 444:             $message = preg_replace('~<p[^>]*>~', "\n", $message); 
 445:             $message = preg_replace('~</p>~', "\n", $message); 
 446:             $message = preg_replace('~<br[^>]*>~', "\n", $message); 
 447:             $message = preg_replace('~<ol[^>]*>~', "", $message); 
 448:             $message = preg_replace('~</ol>~', "", $message); 
 449:             $message = preg_replace('~<ul[^>]*>~', "", $message); 
 450:             $message = preg_replace('~</ul>~', "", $message); 
 451:             $message = preg_replace('~<li[^>]*>~', ".\t", $message); 
 452:             $message = preg_replace('~</li>~', "", $message); 
 453:             $message = getBare($message);
 454:             $message = preg_replace('~\n\n\n+~', "\n\n", $message);
 455: 
 456:             
 457:             if (count($email_list) > 0) {
 458:                 $result = zp_apply_filter('sendmail', '', $email_list, $subject, $message, $from_mail, $from_name, $cc_addresses, $replyTo); 
 459:             }
 460:             if (count($bcc_addresses) > 0) {
 461:                 foreach ($bcc_addresses as $bcc) {
 462:                     $result = zp_apply_filter('sendmail', '', array($bcc), $subject, $message, $from_mail, $from_name, array(), $replyTo); 
 463:                 }
 464:             }
 465:         } else {
 466:             $result = gettext('Mail send failed. There is no mail handler configured.');
 467:         }
 468:     } else {
 469:         if (empty($result)) {
 470:             $result = gettext('Mail send failed.');
 471:         }
 472:         $result .= ' ' . gettext('No “to” address list provided.');
 473:     }
 474:     return $result;
 475: }
 476: 
 477:  478:  479:  480:  481:  482:  483:  484: 
 485: function sortByMultilingual($dbresult, $field, $descending) {
 486:     $temp = array();
 487:     foreach ($dbresult as $key => $row) {
 488:         $temp[$key] = get_language_string($row[$field]);
 489:     }
 490:     natcasesort($temp);
 491:     if ($descending) {
 492:         $temp = array_reverse($temp, true);
 493:     }
 494:     $result = array();
 495:     foreach ($temp as $key => $v) {
 496:         $result[] = $dbresult[$key];
 497:     }
 498:     return $result;
 499: }
 500: 
 501:  502:  503:  504:  505:  506:  507:  508:  509: 
 510: function checkAlbumPassword($album, &$hint = NULL) {
 511:     global $_zp_pre_authorization, $_zp_gallery;
 512:     if (is_object($album)) {
 513:         $albumname = $album->name;
 514:     } else {
 515:         $album = newAlbum($albumname = $album, true, true);
 516:     }
 517:     if (isset($_zp_pre_authorization[$albumname])) {
 518:         return $_zp_pre_authorization[$albumname];
 519:     }
 520:     $hash = $album->getPassword();
 521:     if (empty($hash)) {
 522:         $album = $album->getParent();
 523:         while (!is_null($album)) {
 524:             $hash = $album->getPassword();
 525:             $authType = "zp_album_auth_" . $album->getID();
 526:             $saved_auth = zp_getCookie($authType);
 527: 
 528:             if (!empty($hash)) {
 529:                 if ($saved_auth == $hash) {
 530:                     $_zp_pre_authorization[$albumname] = $authType;
 531:                     return $authType;
 532:                 } else {
 533:                     $hint = $album->getPasswordHint();
 534:                     return false;
 535:                 }
 536:             }
 537:             $album = $album->getParent();
 538:         }
 539:         
 540:         $hash = $_zp_gallery->getPassword();
 541:         $authType = 'zp_gallery_auth';
 542:         $saved_auth = zp_getCookie($authType);
 543:         if (empty($hash)) {
 544:             $authType = 'zp_public_access';
 545:         } else {
 546:             if ($saved_auth != $hash) {
 547:                 $hint = $_zp_gallery->getPasswordHint();
 548:                 return false;
 549:             }
 550:         }
 551:     } else {
 552:         $authType = "zp_album_auth_" . $album->getID();
 553:         $saved_auth = zp_getCookie($authType);
 554:         if ($saved_auth != $hash) {
 555:             $hint = $album->getPasswordHint();
 556:             return false;
 557:         }
 558:     }
 559:     $_zp_pre_authorization[$albumname] = $authType;
 560:     return $authType;
 561: }
 562: 
 563:  564:  565:  566:  567:  568:  569:  570:  571: 
 572: function getPluginFiles($pattern, $folder = '', $stripsuffix = true) {
 573:     if (!empty($folder) && substr($folder, -1) != '/')
 574:         $folder .= '/';
 575:     $list = array();
 576:     $curdir = getcwd();
 577:     $basepath = SERVERPATH . "/" . USER_PLUGIN_FOLDER . '/' . $folder;
 578:     if (is_dir($basepath)) {
 579:         chdir($basepath);
 580:         $filelist = safe_glob($pattern);
 581:         foreach ($filelist as $file) {
 582:             $key = filesystemToInternal($file);
 583:             if ($stripsuffix) {
 584:                 $key = stripSuffix($key);
 585:             }
 586:             $list[$key] = $basepath . $file;
 587:         }
 588:     }
 589:     $basepath = SERVERPATH . "/" . ZENFOLDER . '/' . PLUGIN_FOLDER . '/' . $folder;
 590:     if (file_exists($basepath)) {
 591:         chdir($basepath);
 592:         $filelist = safe_glob($pattern);
 593:         foreach ($filelist as $file) {
 594:             $key = filesystemToInternal($file);
 595:             if ($stripsuffix) {
 596:                 $key = stripSuffix($key);
 597:             }
 598:             $list[$key] = $basepath . $file;
 599:         }
 600:     }
 601:     chdir($curdir);
 602:     return $list;
 603: }
 604: 
 605:  606:  607:  608:  609:  610:  611:  612:  613:  614:  615:  616:  617:  618:  619:  620:  621: 
 622: function getPlugin($plugin, $inTheme = false, $webpath = false) {
 623:     global $_zp_gallery;
 624:     $pluginFile = NULL;
 625:     if ($inTheme === true) {
 626:         $inTheme = $_zp_gallery->getCurrentTheme();
 627:     }
 628:     if ($inTheme) {
 629:         $pluginFile = '/' . THEMEFOLDER . '/' . internalToFilesystem($inTheme . '/' . $plugin);
 630:         if (!file_exists(SERVERPATH . $pluginFile)) {
 631:             $pluginFile = false;
 632:         }
 633:     }
 634:     if (!$pluginFile) {
 635:         $pluginFile = '/' . USER_PLUGIN_FOLDER . '/' . internalToFilesystem($plugin);
 636:         if (!file_exists(SERVERPATH . $pluginFile)) {
 637:             $pluginFile = '/' . ZENFOLDER . '/' . PLUGIN_FOLDER . '/' . internalToFilesystem($plugin);
 638:             if (!file_exists(SERVERPATH . $pluginFile)) {
 639:                 $pluginFile = false;
 640:             }
 641:         }
 642:     }
 643:     if ($pluginFile) {
 644:         if ($webpath) {
 645:             if (is_string($webpath)) {
 646:                 return $webpath . filesystemToInternal($pluginFile);
 647:             } else {
 648:                 return WEBPATH . filesystemToInternal($pluginFile);
 649:             }
 650:         } else {
 651:             return SERVERPATH . $pluginFile;
 652:         }
 653:     }
 654:     return false;
 655: }
 656: 
 657:  658:  659:  660:  661: 
 662: function getEnabledPlugins() {
 663:     global $_EnabledPlugins;
 664:     if (is_array($_EnabledPlugins)) {
 665:         return $_EnabledPlugins;
 666:     }
 667:     $_EnabledPlugins = array();
 668:     $sortlist = getPluginFiles('*.php');
 669:     foreach ($sortlist as $extension => $path) {
 670:         $opt = 'zp_plugin_' . $extension;
 671:         if ($option = getOption($opt)) {
 672:             $_EnabledPlugins[$extension] = array('priority' => $option, 'path' => $path);
 673:         }
 674:     }
 675:     $_EnabledPlugins = sortMultiArray($_EnabledPlugins, 'priority', true);
 676:     return $_EnabledPlugins;
 677: }
 678: 
 679:  680:  681:  682:  683: 
 684: function extensionEnabled($extension) {
 685:     return getOption('zp_plugin_' . $extension);
 686: }
 687: 
 688:  689:  690:  691:  692:  693: 
 694: function enableExtension($extension, $priority, $persistent = true) {
 695:     setOption('zp_plugin_' . $extension, $priority, $persistent);
 696: }
 697: 
 698:  699:  700:  701:  702:  703: 
 704: function fetchComments($number) {
 705:     if ($number) {
 706:         $limit = " LIMIT $number";
 707:     } else {
 708:         $limit = '';
 709:     }
 710: 
 711:     $comments = array();
 712:     if (zp_loggedin(ADMIN_RIGHTS | COMMENT_RIGHTS)) {
 713:         if (zp_loggedin(ADMIN_RIGHTS | MANAGE_ALL_ALBUM_RIGHTS)) {
 714:             $sql = "SELECT *, (date + 0) AS date FROM " . prefix('comments') . " ORDER BY id DESC$limit";
 715:             $comments = query_full_array($sql);
 716:         } else {
 717:             $albumlist = getManagedAlbumList();
 718:             $albumIDs = array();
 719:             foreach ($albumlist as $albumname) {
 720:                 $subalbums = getAllSubAlbumIDs($albumname);
 721:                 foreach ($subalbums as $ID) {
 722:                     $albumIDs[] = $ID['id'];
 723:                 }
 724:             }
 725:             if (count($albumIDs) > 0) {
 726:                 $sql = "SELECT  *, (`date` + 0) AS date FROM " . prefix('comments') . " WHERE ";
 727: 
 728:                 $sql .= " (`type`='albums' AND (";
 729:                 $i = 0;
 730:                 foreach ($albumIDs as $ID) {
 731:                     if ($i > 0) {
 732:                         $sql .= " OR ";
 733:                     }
 734:                     $sql .= "(" . prefix('comments') . ".ownerid=$ID)";
 735:                     $i++;
 736:                 }
 737:                 $sql .= ")) ";
 738:                 $sql .= " ORDER BY id DESC$limit";
 739:                 $albumcomments = query($sql);
 740:                 if ($albumcomments) {
 741:                     while ($comment = db_fetch_assoc($albumcomments)) {
 742:                         $comments[$comment['id']] = $comment;
 743:                     }
 744:                     db_free_result($albumcomments);
 745:                 }
 746:                 $sql = "SELECT *, " . prefix('comments') . ".id as id, " .
 747:                                 prefix('comments') . ".name as name, (" . prefix('comments') . ".date + 0) AS date, " .
 748:                                 prefix('images') . ".`albumid` as albumid," .
 749:                                 prefix('images') . ".`id` as imageid" .
 750:                                 " FROM " . prefix('comments') . "," . prefix('images') . " WHERE ";
 751: 
 752:                 $sql .= "(`type` IN (" . zp_image_types("'") . ") AND (";
 753:                 $i = 0;
 754:                 foreach ($albumIDs as $ID) {
 755:                     if ($i > 0) {
 756:                         $sql .= " OR ";
 757:                     }
 758:                     $sql .= "(" . prefix('comments') . ".ownerid=" . prefix('images') . ".id AND " . prefix('images') . ".albumid=$ID)";
 759:                     $i++;
 760:                 }
 761:                 $sql .= "))";
 762:                 $sql .= " ORDER BY " . prefix('images') . ".`id` DESC$limit";
 763:                 $imagecomments = query($sql);
 764:                 if ($imagecomments) {
 765:                     while ($comment = db_fetch_assoc($imagecomments)) {
 766:                         $comments[$comment['id']] = $comment;
 767:                     }
 768:                     db_free_result($imagecomments);
 769:                 }
 770:                 krsort($comments);
 771:                 if ($number) {
 772:                     if ($number < count($comments)) {
 773:                         $comments = array_slice($comments, 0, $number);
 774:                     }
 775:                 }
 776:             }
 777:         }
 778:     }
 779:     return $comments;
 780: }
 781: 
 782:  783:  784:  785: 
 786: function getManagedAlbumList() {
 787:     global $_zp_admin_album_list, $_zp_current_admin_obj;
 788:     $_zp_admin_album_list = array();
 789:     if (zp_loggedin(MANAGE_ALL_ALBUM_RIGHTS)) {
 790:         $sql = "SELECT `folder` FROM " . prefix('albums') . ' WHERE `parentid` IS NULL';
 791:         $albums = query($sql);
 792:         if ($albums) {
 793:             while ($album = db_fetch_assoc($albums)) {
 794:                 $_zp_admin_album_list[$album['folder']] = 32767;
 795:             }
 796:             db_free_result($albums);
 797:         }
 798:     } else {
 799:         if ($_zp_current_admin_obj) {
 800:             $_zp_admin_album_list = array();
 801:             $objects = $_zp_current_admin_obj->getObjects();
 802:             foreach ($objects as $object) {
 803:                 if ($object['type'] == 'album') {
 804:                     $_zp_admin_album_list[$object['data']] = $object['edit'];
 805:                 }
 806:             }
 807:         }
 808:     }
 809:     return array_keys($_zp_admin_album_list);
 810: }
 811: 
 812:  813:  814:  815:  816:  817:  818:  819: 
 820: function populateManagedObjectsList($type, $id, $rights = false) {
 821:     if ($id <= 0) {
 822:         return array();
 823:     }
 824:     $cv = array();
 825:     if (empty($type) || substr($type, 0, 5) == 'album') {
 826:         $sql = "SELECT " . prefix('albums') . ".`folder`," . prefix('albums') . ".`title`," . prefix('admin_to_object') . ".`edit` FROM " . prefix('albums') . ", " .
 827:                         prefix('admin_to_object') . " WHERE " . prefix('admin_to_object') . ".adminid=" . $id .
 828:                         " AND " . prefix('albums') . ".id=" . prefix('admin_to_object') . ".objectid AND " . prefix('admin_to_object') . ".type LIKE 'album%'";
 829:         $currentvalues = query($sql, false);
 830:         if ($currentvalues) {
 831:             while ($albumitem = db_fetch_assoc($currentvalues)) {
 832:                 $folder = $albumitem['folder'];
 833:                 $name = get_language_string($albumitem['title']);
 834:                 if ($type && !$rights) {
 835:                     $cv[$name] = $folder;
 836:                 } else {
 837:                     $cv[] = array('data' => $folder, 'name' => $name, 'type' => 'album', 'edit' => $albumitem['edit'] + 0);
 838:                 }
 839:             }
 840:             db_free_result($currentvalues);
 841:         }
 842:     }
 843:     if (empty($type) || $type == 'pages') {
 844:         $sql = 'SELECT ' . prefix('pages') . '.`title`,' . prefix('pages') . '.`titlelink` FROM ' . prefix('pages') . ', ' .
 845:                         prefix('admin_to_object') . " WHERE " . prefix('admin_to_object') . ".adminid=" . $id .
 846:                         " AND " . prefix('pages') . ".id=" . prefix('admin_to_object') . ".objectid AND " . prefix('admin_to_object') . ".type='pages'";
 847:         $currentvalues = query($sql, false);
 848:         if ($currentvalues) {
 849:             while ($item = db_fetch_assoc($currentvalues)) {
 850:                 if ($type) {
 851:                     $cv[get_language_string($item['title'])] = $item['titlelink'];
 852:                 } else {
 853:                     $cv[] = array('data' => $item['titlelink'], 'name' => $item['title'], 'type' => 'pages');
 854:                 }
 855:             }
 856:             db_free_result($currentvalues);
 857:         }
 858:     }
 859:     if (empty($type) || $type == 'news') {
 860:         $sql = 'SELECT ' . prefix('news_categories') . '.`titlelink`,' . prefix('news_categories') . '.`title` FROM ' . prefix('news_categories') . ', ' .
 861:                         prefix('admin_to_object') . " WHERE " . prefix('admin_to_object') . ".adminid=" . $id .
 862:                         " AND " . prefix('news_categories') . ".id=" . prefix('admin_to_object') . ".objectid AND " . prefix('admin_to_object') . ".type='news'";
 863:         $currentvalues = query($sql, false);
 864:         if ($currentvalues) {
 865:             while ($item = db_fetch_assoc($currentvalues)) {
 866:                 if ($type) {
 867:                     $cv[get_language_string($item['title'])] = $item['titlelink'];
 868:                 } else {
 869:                     $cv[] = array('data' => $item['titlelink'], 'name' => $item['title'], 'type' => 'news');
 870:                 }
 871:             }
 872:             db_free_result($currentvalues);
 873:         }
 874:     }
 875:     return $cv;
 876: }
 877: 
 878:  879:  880:  881:  882: 
 883: function getAllSubAlbumIDs($albumfolder = '') {
 884:     global $_zp_current_album;
 885:     if (empty($albumfolder)) {
 886:         if (isset($_zp_current_album)) {
 887:             $albumfolder = $_zp_current_album->getFileName();
 888:         } else {
 889:             return null;
 890:         }
 891:     }
 892:     $query = "SELECT `id`,`folder`, `show` FROM " . prefix('albums') . " WHERE `folder` LIKE " . db_quote(db_LIKE_escape($albumfolder) . '%');
 893:     $subIDs = query_full_array($query);
 894:     return $subIDs;
 895: }
 896: 
 897:  898:  899:  900:  901:  902:  903: 
 904: function handleSearchParms($what, $album = NULL, $image = NULL) {
 905:     global $_zp_current_search, $zp_request, $_zp_last_album, $_zp_current_album,
 906:     $_zp_current_zenpage_news, $_zp_current_zenpage_page, $_zp_gallery, $_zp_loggedin;
 907:     $_zp_last_album = zp_getCookie('zenphoto_last_album');
 908:     if (is_object($zp_request) && get_class($zp_request) == 'SearchEngine') { 
 909:         return $zp_request->getAlbumList();
 910:     }
 911:     $params = zp_getCookie('zenphoto_search_params');
 912:     if (!empty($params)) {
 913:         $context = get_context();
 914:         $_zp_current_search = new SearchEngine();
 915:         $_zp_current_search->setSearchParams($params);
 916:         
 917:         if (!is_null($image)) {
 918:             $dynamic_album = $_zp_current_search->getDynamicAlbum();
 919:             if ($_zp_current_search->getImageIndex($album->name, $image->filename) !== false) {
 920:                 if ($dynamic_album) {
 921:                     $_zp_current_album = $dynamic_album;
 922:                 }
 923:                 $context = $context | ZP_SEARCH_LINKED | ZP_IMAGE_LINKED;
 924:             }
 925:         }
 926:         if (!is_null($album)) {
 927:             $albumname = $album->name;
 928:             zp_setCookie('zenphoto_last_album', $albumname);
 929:             if (hasDynamicAlbumSuffix($albumname) && !is_dir(ALBUM_FOLDER_SERVERPATH . $albumname)) {
 930:                 $albumname = stripSuffix($albumname); 
 931:             }
 932:             
 933:             $save_logon = $_zp_loggedin;
 934:             $_zp_loggedin = $_zp_loggedin | VIEW_ALL_RIGHTS;
 935:             $search_album_list = $_zp_current_search->getAlbums(0);
 936:             $_zp_loggedin = $save_logon;
 937:             foreach ($search_album_list as $searchalbum) {
 938:                 if (strpos($albumname, $searchalbum) !== false) {
 939:                     $context = $context | ZP_SEARCH_LINKED | ZP_ALBUM_LINKED;
 940:                     break;
 941:                 }
 942:             }
 943:         } else {
 944:             zp_clearCookie('zenphoto_last_album');
 945:         }
 946:         if (!is_null($_zp_current_zenpage_page)) {
 947:             $pages = $_zp_current_search->getPages();
 948:             if (!empty($pages)) {
 949:                 $tltlelink = $_zp_current_zenpage_page->getTitlelink();
 950:                 foreach ($pages as $apage) {
 951:                     if ($apage == $tltlelink) {
 952:                         $context = $context | ZP_SEARCH_LINKED;
 953:                         break;
 954:                     }
 955:                 }
 956:             }
 957:         }
 958:         if (!is_null($_zp_current_zenpage_news)) {
 959:             $news = $_zp_current_search->getArticles(0, NULL, true);
 960:             if (!empty($news)) {
 961:                 $tltlelink = $_zp_current_zenpage_news->getTitlelink();
 962:                 foreach ($news as $anews) {
 963:                     if ($anews['titlelink'] == $tltlelink) {
 964:                         $context = $context | ZP_SEARCH_LINKED;
 965:                         break;
 966:                     }
 967:                 }
 968:             }
 969:         }
 970:         if (($context & ZP_SEARCH_LINKED)) {
 971:             set_context($context);
 972:         } else { 
 973:             $_zp_current_search = null;
 974:             rem_context(ZP_SEARCH);
 975:             if (!isset($_REQUEST['preserve_serch_params'])) {
 976:                 zp_clearCookie("zenphoto_search_params");
 977:             }
 978:         }
 979:     }
 980: }
 981: 
 982:  983:  984:  985:  986: 
 987: function checkPublishDates($row) {
 988:     if (@$row['show']) {
 989:         if (isset($row['expiredate']) && $row['expiredate'] && $row['expiredate'] != '0000-00-00 00:00:00') {
 990:             if ($row['expiredate'] <= date('Y-m-d H:i:s')) {
 991:                 return 1;
 992:             }
 993:         }
 994:         if (isset($row['publishdate']) && $row['publishdate'] && $row['publishdate'] != '0000-00-00 00:00:00') {
 995:             if ($row['publishdate'] >= date('Y-m-d H:i:s')) {
 996:                 return 2;
 997:             }
 998:         }
 999:         return null;
1000:     }
1001: }
1002: 
1003: 1004: 1005: 1006: 1007: 
1008: function galleryAlbumsPerPage() {
1009:     return max(1, getOption('albums_per_page'));
1010: }
1011: 
1012: 1013: 1014: 1015: 1016: 1017: 1018: 1019: 
1020: function setupTheme($album = NULL) {
1021:     global $_zp_gallery, $_zp_current_album, $_zp_current_search, $_zp_themeroot;
1022:     $albumtheme = '';
1023:     if (is_null($album)) {
1024:         if (in_context(ZP_SEARCH_LINKED)) {
1025:             if (!$album = $_zp_current_search->getDynamicAlbum()) {
1026:                 $album = $_zp_current_album;
1027:             }
1028:         } else {
1029:             $album = $_zp_current_album;
1030:         }
1031:     }
1032:     $theme = $_zp_gallery->getCurrentTheme();
1033:     $id = 0;
1034:     if (!is_null($album)) {
1035:         $parent = getUrAlbum($album);
1036:         $albumtheme = $parent->getAlbumTheme();
1037:         if (!empty($albumtheme)) {
1038:             $theme = $albumtheme;
1039:             $id = $parent->getID();
1040:         }
1041:     }
1042:     $theme = zp_apply_filter('setupTheme', $theme);
1043:     $_zp_gallery->setCurrentTheme($theme);
1044:     $themeindex = getPlugin('index.php', $theme);
1045:     if (empty($theme) || empty($themeindex)) {
1046:         header('Last-Modified: ' . ZP_LAST_MODIFIED);
1047:         header('Content-Type: text/html; charset=' . LOCAL_CHARSET);
1048:         ?>
1049:         <!DOCTYPE html>
1050:         <html xmlns="http://www.w3.org/1999/xhtml">
1051:             <head>
1052:             </head>
1053:             <body>
1054:                 <strong><?php printf(gettext('Zenphoto found no theme scripts. Please check the <em>%s</em> folder of your installation.'), THEMEFOLDER); ?></strong>
1055:             </body>
1056:         </html>
1057:         <?php
1058:         exitZP();
1059:     } else {
1060:         loadLocalOptions($id, $theme);
1061:         $_zp_themeroot = WEBPATH . "/" . THEMEFOLDER . "/$theme";
1062:     }
1063:     return $theme;
1064: }
1065: 
1066: 1067: 1068: 1069: 1070: 1071: 1072: 
1073: function getAllTagsUnique($checkaccess = false) {
1074:   global $_zp_unique_tags, $_zp_unique_tags_excluded;
1075:   if(zp_loggedin(VIEW_ALL_RIGHTS)) {
1076:     $checkaccess = false;
1077:   }
1078:   
1079:   if ($checkaccess) {
1080:     if (!is_null($_zp_unique_tags_excluded)) {
1081:       return $_zp_unique_tags_excluded; 
1082:     }
1083:   } else {
1084:     if (!is_null($_zp_unique_tags)) {
1085:       return $_zp_unique_tags; 
1086:     }
1087:   }
1088:   $all_unique_tags = array();
1089:   $sql = "SELECT DISTINCT `name`, `id` FROM " . prefix('tags') . ' ORDER BY `name`';
1090:   $unique_tags = query($sql);
1091:   if ($unique_tags) {
1092:     while ($tagrow = db_fetch_assoc($unique_tags)) {
1093:       if ($checkaccess) {
1094:         if (getTagCountByAccess($tagrow) != 0) {
1095:           $all_unique_tags[] = $tagrow['name'];
1096:         }
1097:       } else {
1098:         $all_unique_tags[] = $tagrow['name'];
1099:       }
1100:     }
1101:     db_free_result($unique_tags);
1102:   }
1103:   if ($checkaccess) {
1104:     $_zp_unique_tags_excluded = $all_unique_tags;
1105:     return $_zp_unique_tags_excluded;
1106:   } else {
1107:     $_zp_unique_tags = $all_unique_tags;
1108:     return $_zp_unique_tags;
1109:   }
1110: }
1111: 
1112: 1113: 1114: 1115: 1116: 1117: 1118: 1119: 1120: 
1121: function getAllTagsCount($exclude_unassigned = false, $checkaccess = false) {
1122:   global $_zp_count_tags;
1123:   if (!is_null($_zp_count_tags)) {
1124:     return $_zp_count_tags;
1125:   }
1126:   if(zp_loggedin(VIEW_ALL_RIGHTS)) {
1127:     $exclude_unassigned = false;
1128:     $checkaccess = false;
1129:   }
1130:   $_zp_count_tags = array();
1131:   $sql = "SELECT DISTINCT tags.name, tags.id, (SELECT COUNT(*) FROM " . prefix('obj_to_tag') . " as object WHERE object.tagid = tags.id) AS count FROM " . prefix('tags') . " as tags ORDER BY `name`";
1132:   $tagresult = query($sql);
1133:   if ($tagresult) {
1134:     while ($tag = db_fetch_assoc($tagresult)) {
1135:       if($checkaccess) {
1136:         $count = getTagCountByAccess($tag);
1137:         if($count != 0) {
1138:           $_zp_count_tags[$tag['name']] = $count;
1139:         }
1140:       } else {
1141:         if($exclude_unassigned) {
1142:           if($tag['count'] != 0) {
1143:             $_zp_count_tags[$tag['name']] = $tag['count'];
1144:           }
1145:         } else {
1146:           $_zp_count_tags[$tag['name']] = $tag['count'];
1147:         }
1148:       }
1149:     }
1150:     db_free_result($tagresult);
1151:   }
1152:   return $_zp_count_tags;
1153: }
1154: 
1155: 1156: 1157: 1158: 1159: 1160: 1161: 1162: 
1163: function getTagCountByAccess($tag) {
1164:   global $_zp_zenpage, $_zp_object_to_tags;
1165:   if (array_key_exists('count', $tag) && $tag['count'] == 0) {
1166:     return $tag['count'];
1167:   }
1168:   $hidealbums = getNotViewableAlbums();
1169:   $hideimages = getNotViewableImages();
1170:   $hidenews = array();
1171:   $hidepages = array();
1172:   if (extensionEnabled('Zenpage')) {
1173:     $hidenews = $_zp_zenpage->getNotViewableNews();
1174:     $hidepages = $_zp_zenpage->getNotViewablePages();
1175:   }
1176:   
1177:   if (empty($hidealbums) && empty($hideimages) && empty($hidenews) && empty($hidepages)) {
1178:     if (array_key_exists('count', $tag)) {
1179:       return $tag['count'];
1180:     }
1181:     return 0;
1182:   }
1183:   if (is_null($_zp_object_to_tags)) {
1184:     $sql = "SELECT tagid, type, objectid FROM " . prefix('obj_to_tag') . " ORDER BY tagid";
1185:     $_zp_object_to_tags = query_full_array($sql);
1186:   }
1187:   $count = '';
1188:   if ($_zp_object_to_tags) {
1189:     foreach($_zp_object_to_tags as $tagcheck) {
1190:       if ($tagcheck['tagid'] == $tag['id']) {
1191:         switch ($tagcheck['type']) {
1192:           case 'albums':
1193:             if (!in_array($tagcheck['objectid'], $hidealbums)) {
1194:               $count++;
1195:             }
1196:             break;
1197:           case 'images':
1198:             if (!in_array($tagcheck['objectid'], $hideimages)) {
1199:               $count++;
1200:             }
1201:             break;
1202:           case 'news':
1203:             if (extensionEnabled('Zenpage') && ZP_NEWS_ENABLED) {
1204:               if (!in_array($tagcheck['objectid'], $hidenews)) {
1205:                 $count++;
1206:               }
1207:             }
1208:             break;
1209:           case 'pages':
1210:             if (extensionEnabled('Zenpage') && ZP_PAGES_ENABLED) {
1211:               if (!in_array($tagcheck['objectid'], $hidepages)) {
1212:                 $count++;
1213:               }
1214:             }
1215:             break;
1216:         }
1217:       }
1218:     }
1219:   }
1220:   if (empty($count)) {
1221:     $count = 0;
1222:   }
1223:   return $count;
1224: }
1225: 
1226: 1227: 1228: 1229: 1230: 1231: 1232: 
1233: function storeTags($tags, $id, $tbl) {
1234:     if ($id) {
1235:         $tagsLC = array();
1236:         foreach ($tags as $key => $tag) {
1237:             $tag = trim($tag);
1238:             if (!empty($tag)) {
1239:                 $lc_tag = mb_strtolower($tag);
1240:                 if (!in_array($lc_tag, $tagsLC)) {
1241:                     $tagsLC[$tag] = $lc_tag;
1242:                 }
1243:             }
1244:         }
1245:         $sql = "SELECT `id`, `tagid` from " . prefix('obj_to_tag') . " WHERE `objectid`='" . $id . "' AND `type`='" . $tbl . "'";
1246:         $result = query($sql);
1247:         $existing = array();
1248:         if ($result) {
1249:             while ($row = db_fetch_assoc($result)) {
1250:                 $dbtag = query_single_row("SELECT `name` FROM " . prefix('tags') . " WHERE `id`='" . $row['tagid'] . "'");
1251:                 $existingLC = mb_strtolower($dbtag['name']);
1252:                 if (in_array($existingLC, $tagsLC)) { 
1253:                     $existing[] = $existingLC;
1254:                 } else { 
1255:                     query("DELETE FROM " . prefix('obj_to_tag') . " WHERE `id`='" . $row['id'] . "'");
1256:                 }
1257:             }
1258:             db_free_result($result);
1259:         }
1260:         $tags = array_diff($tagsLC, $existing); 
1261:         foreach ($tags as $key => $tag) {
1262:             $dbtag = query_single_row("SELECT `id` FROM " . prefix('tags') . " WHERE `name`=" . db_quote($key));
1263:             if (!is_array($dbtag)) { 
1264:                 query("INSERT INTO " . prefix('tags') . " (name) VALUES (" . db_quote($key) . ")", false);
1265:                 $dbtag = array('id' => db_insert_id());
1266:             }
1267:             query("INSERT INTO " . prefix('obj_to_tag') . "(`objectid`, `tagid`, `type`) VALUES (" . $id . "," . $dbtag['id'] . ",'" . $tbl . "')");
1268:         }
1269:     }
1270: }
1271: 
1272: 1273: 1274: 1275: 1276: 1277: 1278: 1279: 
1280: function readTags($id, $tbl) {
1281:     $tags = array();
1282:     $result = query("SELECT `tagid` FROM " . prefix('obj_to_tag') . " WHERE `type`='" . $tbl . "' AND `objectid`='" . $id . "'");
1283:     if ($result) {
1284:         while ($row = db_fetch_assoc($result)) {
1285:             $dbtag = query_single_row("SELECT `name` FROM" . prefix('tags') . " WHERE `id`='" . $row['tagid'] . "'");
1286:             if ($dbtag) {
1287:                 $tags[] = $dbtag['name'];
1288:             }
1289:         }
1290:         db_free_result($result);
1291:     }
1292:     natcasesort($tags);
1293:     return $tags;
1294: }
1295: 
1296: 1297: 1298: 1299: 1300: 1301: 1302: 
1303: function generateListFromArray($currentValue, $list, $descending, $localize) {
1304:     if ($localize) {
1305:         $list = array_flip($list);
1306:         if ($descending) {
1307:             arsort($list);
1308:         } else {
1309:             natcasesort($list);
1310:         }
1311:         $list = array_flip($list);
1312:     } else {
1313:         if ($descending) {
1314:             rsort($list);
1315:         } else {
1316:             natcasesort($list);
1317:         }
1318:     }
1319:     foreach ($list as $key => $item) {
1320:         echo '<option value="' . html_encode($item) . '"';
1321:         if (in_array($item, $currentValue)) {
1322:             echo ' selected="selected"';
1323:         }
1324:         if ($localize)
1325:             $display = $key;
1326:         else
1327:             $display = $item;
1328:         echo '>' . $display . "</option>" . "\n";
1329:     }
1330: }
1331: 
1332: 1333: 1334: 1335: 1336: 1337: 1338: 1339: 
1340: function generateListFromFiles($currentValue, $root, $suffix, $descending = false) {
1341:     if (is_dir($root)) {
1342:         $curdir = getcwd();
1343:         chdir($root);
1344:         $filelist = safe_glob('*' . $suffix);
1345:         $list = array();
1346:         foreach ($filelist as $file) {
1347:             $file = str_replace($suffix, '', $file);
1348:             $list[] = filesystemToInternal($file);
1349:         }
1350:         generateListFromArray(array($currentValue), $list, $descending, false);
1351:         chdir($curdir);
1352:     }
1353: }
1354: 
1355: 1356: 1357: 1358: 1359: 1360: 1361: 
1362: function getLinkHTML($url, $text, $title = NULL, $class = NULL, $id = NULL) {
1363:     return "<a href=\"" . html_encode($url) . "\"" .
1364:                     (($title) ? " title=\"" . html_encode(getBare($title)) . "\"" : "") .
1365:                     (($class) ? " class=\"$class\"" : "") .
1366:                     (($id) ? " id=\"$id\"" : "") . ">" .
1367:                     html_encode($text) . "</a>";
1368: }
1369: 
1370: 1371: 1372: 1373: 1374: 1375: 1376: 1377: 
1378: function printLinkHTML($url, $text, $title = NULL, $class = NULL, $id = NULL) {
1379:     echo getLinkHTML($url, $text, $title, $class, $id);
1380: }
1381: 
1382: 1383: 1384: 1385: 1386: 1387: 
1388: function shuffle_assoc(&$array) {
1389:     $keys = array_keys($array);
1390:     shuffle($keys);
1391:     foreach ($keys as $key) {
1392:         $new[$key] = $array[$key];
1393:     }
1394:     $array = $new;
1395:     return true;
1396: }
1397: 
1398: 1399: 1400: 1401: 1402: 1403: 1404: 1405: 1406: 1407: 1408: 1409: 1410: 
1411: function sortByKey($results, $sortkey, $order) {
1412:     $sortkey = str_replace('`', '', $sortkey);
1413:     switch ($sortkey) {
1414:         case 'title':
1415:         case 'desc':
1416:             return sortByMultilingual($results, $sortkey, $order);
1417:         case 'RAND()':
1418:             shuffle($results);
1419:             return $results;
1420:         default:
1421:             if (preg_match('`[\/\(\)\*\+\-!\^\%\<\>\=\&\|]`', $sortkey)) {
1422:                 return $results; 
1423:             }
1424:     }
1425:     $indicies = explode(',', $sortkey);
1426:     foreach ($indicies as $key => $index) {
1427:         $indicies[$key] = trim($index);
1428:     }
1429:     $results = sortMultiArray($results, $indicies, $order, true, false, true);
1430:     return $results;
1431: }
1432: 
1433: 1434: 1435: 1436: 1437: 1438: 1439: 1440: 1441: 1442: 1443: 1444: 
1445: function sortMultiArray($array, $index, $descending = false, $natsort = true, $case_sensitive = false, $preservekeys = false, $remove_criteria = array()) {
1446:     if (is_array($array) && count($array) > 0) {
1447:         if (is_array($index)) {
1448:             $indicies = $index;
1449:         } else {
1450:             $indicies = array($index);
1451:         }
1452:         if ($descending) {
1453:             $separator = '~~';
1454:         } else {
1455:             $separator = '  ';
1456:         }
1457:         foreach ($array as $key => $row) {
1458:             $temp[$key] = '';
1459:             foreach ($indicies as $index) {
1460:                 if (is_array($row) && array_key_exists($index, $row)) {
1461:                     $temp[$key] .= get_language_string($row[$index]) . $separator;
1462:                     if (in_array($index, $remove_criteria)) {
1463:                         unset($array[$key][$index]);
1464:                     }
1465:                 }
1466:             }
1467:             $temp[$key] .= $key;
1468:         }
1469:         if ($natsort) {
1470:             if ($case_sensitive) {
1471:                 natsort($temp);
1472:             } else {
1473:                 natcasesort($temp);
1474:             }
1475:             if ($descending) {
1476:                 $temp = array_reverse($temp, TRUE);
1477:             }
1478:         } else {
1479:             if ($descending) {
1480:                 arsort($temp);
1481:             } else {
1482:                 asort($temp);
1483:             }
1484:         }
1485:         foreach (array_keys($temp) as $key) {
1486:             if (!$preservekeys && is_numeric($key)) {
1487:                 $sorted[] = $array[$key];
1488:             } else {
1489:                 $sorted[$key] = $array[$key];
1490:             }
1491:         }
1492:         return $sorted;
1493:     }
1494:     return $array;
1495: }
1496: 
1497: 1498: 1499: 1500: 1501: 
1502: function getNotViewableAlbums() {
1503:     global $_zp_not_viewable_album_list;
1504:     if (zp_loggedin(ADMIN_RIGHTS | MANAGE_ALL_ALBUM_RIGHTS))
1505:         return array(); 
1506:     if (is_null($_zp_not_viewable_album_list)) {
1507:         $sql = 'SELECT `folder`, `id`, `password`, `show` FROM ' . prefix('albums') . ' WHERE `show`=0 OR `password`!=""';
1508:         $result = query($sql);
1509:         if ($result) {
1510:             $_zp_not_viewable_album_list = array();
1511:             while ($row = db_fetch_assoc($result)) {
1512:                 if (checkAlbumPassword($row['folder'])) {
1513:                     $album = newAlbum($row['folder']);
1514:                     if (!($row['show'] || $album->isMyItem(LIST_RIGHTS))) {
1515:                         $_zp_not_viewable_album_list[] = $row['id'];
1516:                     }
1517:                 } else {
1518:                     $_zp_not_viewable_album_list[] = $row['id'];
1519:                 }
1520:             }
1521:             db_free_result($result);
1522:         }
1523:     }
1524:     return $_zp_not_viewable_album_list;
1525: }
1526: 
1527: 1528: 1529: 1530: 1531: 
1532: function getNotViewableImages() {
1533:   global $_zp_not_viewable_image_list;
1534:   if (zp_loggedin(ADMIN_RIGHTS | MANAGE_ALL_ALBUM_RIGHTS)) {
1535:     return array(); 
1536:   }
1537:   $hidealbums = getNotViewableAlbums();
1538:   $where = '';
1539:   if (!is_null($hidealbums)) {
1540:     $where = implode(',', $hidealbums);
1541:   }
1542:   if (is_null($_zp_not_viewable_image_list)) {
1543:     $sql = 'SELECT DISTINCT `id` FROM ' . prefix('images') . ' WHERE `show` = 0 OR `albumid` in (' . $where . ')';
1544:     $result = query($sql);
1545:     if ($result) {
1546:       $_zp_not_viewable_image_list = array();
1547:       while ($row = db_fetch_assoc($result)) {
1548:         $_zp_not_viewable_image_list[] = $row['id'];
1549:       }
1550:     }
1551:   }
1552:   return $_zp_not_viewable_image_list;
1553: }
1554: 
1555:   1556: 1557: 1558: 1559: 1560: 
1561: function isValidURL($url) {
1562:     return preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $url);
1563: }
1564: 
1565: 1566: 1567: 1568: 1569: 1570: 1571: 
1572: function safe_fnmatch($pattern, $string) {
1573:     return @preg_match('/^' . strtr(addcslashes($pattern, '\\.+^$(){}=!<>|'), array('*' => '.*', '?' => '.?')) . '$/i', $string);
1574: }
1575: 
1576: 1577: 1578: 1579: 1580: 1581: 
1582: function zp_image_types($quote) {
1583:     global $_zp_extra_filetypes;
1584:     $typelist = $quote . 'images' . $quote . ',' . $quote . '_images' . $quote . ',';
1585:     $types = array_unique($_zp_extra_filetypes);
1586:     foreach ($types as $type) {
1587:         $typelist .= $quote . strtolower($type) . 's' . $quote . ',';
1588:     }
1589:     return substr($typelist, 0, -1);
1590: }
1591: 
1592: 1593: 1594: 1595: 1596: 1597: 1598: 
1599: function isImageVideo($image = NULL) {
1600:     if (is_null($image)) {
1601:         if (!in_context(ZP_IMAGE))
1602:             return false;
1603:         global $_zp_current_image;
1604:         $image = $_zp_current_image;
1605:     }
1606:     return strtolower(get_class($image)) == 'video';
1607: }
1608: 
1609: 1610: 1611: 1612: 1613: 1614: 
1615: function isImagePhoto($image = NULL) {
1616:     if (is_null($image)) {
1617:         if (!in_context(ZP_IMAGE))
1618:             return false;
1619:         global $_zp_current_image;
1620:         $image = $_zp_current_image;
1621:     }
1622:     $class = strtolower(get_class($image));
1623:     return $class == 'image' || $class == 'transientimage';
1624: }
1625: 
1626: 1627: 1628: 1629: 1630: 1631: 
1632: function dircopy($srcdir, $dstdir) {
1633:     $num = 0;
1634:     if (!is_dir($dstdir))
1635:         mkdir($dstdir);
1636:     if ($curdir = opendir($srcdir)) {
1637:         while ($file = readdir($curdir)) {
1638:             if ($file != '.' && $file != '..') {
1639:                 $srcfile = $srcdir . '/' . $file;
1640:                 $dstfile = $dstdir . '/' . $file;
1641:                 if (is_file($srcfile)) {
1642:                     if (is_file($dstfile))
1643:                         $ow = filemtime($srcfile) - filemtime($dstfile);
1644:                     else
1645:                         $ow = 1;
1646:                     if ($ow > 0) {
1647:                         if (copy($srcfile, $dstfile)) {
1648:                             touch($dstfile, filemtime($srcfile));
1649:                             $num++;
1650:                         }
1651:                     }
1652:                 } else if (is_dir($srcfile)) {
1653:                     $num += dircopy($srcfile, $dstfile);
1654:                 }
1655:             }
1656:         }
1657:         closedir($curdir);
1658:     }
1659:     return $num;
1660: }
1661: 
1662: 1663: 1664: 1665: 1666: 1667: 
1668: function byteConvert($bytes) {
1669:     if ($bytes <= 0)
1670:         return gettext('0 Bytes');
1671:     $convention = 1024; 
1672:     $s = array('Bytes', 'kB', 'mB', 'GB', 'TB', 'PB', 'EB', 'ZB');
1673:     $e = floor(log($bytes, $convention));
1674:     return round($bytes / pow($convention, $e), 2) . ' ' . $s[$e];
1675: }
1676: 
1677: 1678: 1679: 1680: 1681: 1682: 1683: 
1684: function dateTimeConvert($datetime, $raw = false) {
1685:     
1686:     $datetime = preg_replace('/(\d{4}):(\d{2}):(\d{2})/', ' \1-\2-\3', $datetime);
1687:     $time = strtotime($datetime);
1688:     if ($time == -1 || $time === false)
1689:         return false;
1690:     if ($raw)
1691:         return $time;
1692:     return date('Y-m-d H:i:s', $time);
1693: }
1694: 
1695: 
1696: 
1697: 
1698: 1699: 1700: 
1701: 
1702: function get_context() {
1703:     global $_zp_current_context;
1704:     return $_zp_current_context;
1705: }
1706: 
1707: function set_context($context) {
1708:     global $_zp_current_context;
1709:     $_zp_current_context = $context;
1710: }
1711: 
1712: function in_context($context) {
1713:     return get_context() & $context;
1714: }
1715: 
1716: function add_context($context) {
1717:     set_context(get_context() | $context);
1718: }
1719: 
1720: function rem_context($context) {
1721:     global $_zp_current_context;
1722:     set_context(get_context() & ~$context);
1723: }
1724: 
1725: 
1726: function save_context() {
1727:     global $_zp_current_context, $_zp_current_context_stack;
1728:     array_push($_zp_current_context_stack, $_zp_current_context);
1729: }
1730: 
1731: function restore_context() {
1732:     global $_zp_current_context, $_zp_current_context_stack;
1733:     $_zp_current_context = array_pop($_zp_current_context_stack);
1734: }
1735: 
1736: 1737: 1738: 1739: 1740: 1741: 
1742: function sanitizeRedirect($redirectTo, $forceHost = false) {
1743:     $redirect = NULL;
1744:     if ($redirectTo && $redir = parse_url($redirectTo)) {
1745:         if (isset($redir['scheme']) && isset($redir['host'])) {
1746:             $redirect .= $redir['scheme'] . '://' . sanitize($redir['host']);
1747:         } else {
1748:             if ($forceHost) {
1749:                 $redirect .= PROTOCOL . '://' . $_SERVER['HTTP_HOST'];
1750:                 if (WEBPATH && strpos($redirectTo, WEBPATH) === false) {
1751:                     $redirect .= WEBPATH;
1752:                 }
1753:             }
1754:         }
1755:         if (isset($redir['path'])) {
1756:             $redirect .= urldecode(sanitize($redir['path']));
1757:         }
1758:         if (isset($redir['query'])) {
1759:             $redirect .= '?' . sanitize($redir['query']);
1760:         }
1761:         if (isset($redir['fragment'])) {
1762:             $redirect .= '#' . sanitize($redir['fragment']);
1763:         }
1764:     }
1765:     return $redirect;
1766: }
1767: 
1768: 1769: 1770: 1771: 1772: 
1773: function zp_handle_password($authType = NULL, $check_auth = NULL, $check_user = NULL) {
1774:     global $_zp_loggedin, $_zp_login_error, $_zp_current_album, $_zp_current_zenpage_page, $_zp_current_category, $_zp_current_zenpage_news, $_zp_gallery;
1775:     if (empty($authType)) { 
1776:         $check_auth = '';
1777:         if (isset($_GET['z']) && @$_GET['p'] == 'full-image' || isset($_GET['p']) && $_GET['p'] == '*full-image') {
1778:             $authType = 'zp_image_auth';
1779:             $check_auth = getOption('protected_image_password');
1780:             $check_user = getOption('protected_image_user');
1781:         } else if (in_context(ZP_SEARCH)) { 
1782:             $authType = 'zp_search_auth';
1783:             $check_auth = getOption('search_password');
1784:             $check_user = getOption('search_user');
1785:         } else if (in_context(ZP_ALBUM)) { 
1786:             $authType = "zp_album_auth_" . $_zp_current_album->getID();
1787:             $check_auth = $_zp_current_album->getPassword();
1788:             $check_user = $_zp_current_album->getUser();
1789:             if (empty($check_auth)) {
1790:                 $parent = $_zp_current_album->getParent();
1791:                 while (!is_null($parent)) {
1792:                     $check_auth = $parent->getPassword();
1793:                     $check_user = $parent->getUser();
1794:                     $authType = "zp_album_auth_" . $parent->getID();
1795:                     if (!empty($check_auth)) {
1796:                         break;
1797:                     }
1798:                     $parent = $parent->getParent();
1799:                 }
1800:             }
1801:         } else if (in_context(ZP_ZENPAGE_PAGE)) {
1802:             $authType = "zp_page_auth_" . $_zp_current_zenpage_page->getID();
1803:             $check_auth = $_zp_current_zenpage_page->getPassword();
1804:             $check_user = $_zp_current_zenpage_page->getUser();
1805:             if (empty($check_auth)) {
1806:                 $pageobj = $_zp_current_zenpage_page;
1807:                 while (empty($check_auth)) {
1808:                     $parentID = $pageobj->getParentID();
1809:                     if ($parentID == 0)
1810:                         break;
1811:                     $sql = 'SELECT `titlelink` FROM ' . prefix('pages') . ' WHERE `id`=' . $parentID;
1812:                     $result = query_single_row($sql);
1813:                     $pageobj = new ZenpagePage($result['titlelink']);
1814:                     $authType = "zp_page_auth_" . $pageobj->getID();
1815:                     $check_auth = $pageobj->getPassword();
1816:                     $check_user = $pageobj->getUser();
1817:                 }
1818:             }
1819:         } else if (in_context(ZP_ZENPAGE_NEWS_CATEGORY) || in_context(ZP_ZENPAGE_NEWS_ARTICLE)) {
1820:             $check_auth_user = array();
1821:             if (in_context(ZP_ZENPAGE_NEWS_CATEGORY)) {
1822:                 $checkcats = array($_zp_current_category);
1823:             } else if (in_context(ZP_ZENPAGE_NEWS_ARTICLE)) {
1824:                 $checkcats = array();
1825:                 $cats = $_zp_current_zenpage_news->getCategories();
1826:                 foreach ($cats as $cat) {
1827:                     $checkcats[] = new ZenpageCategory($cat['titlelink']);
1828:                 }
1829:             }
1830:             if (!empty($checkcats)) {
1831:                 foreach ($checkcats as $obj) {
1832:                     $authType = "zp_category_auth_" .  $obj->getID();
1833:                     $check_auth =  $obj->getPassword();
1834:                     $check_user =  $obj->getUser();
1835:                     if (empty($check_auth)) {
1836:                         $catobj =  $obj;
1837:                         while (empty($check_auth)) {
1838:                             $parentID = $catobj->getParentID();
1839:                             if ($parentID == 0)
1840:                                 break;
1841:                             $sql = 'SELECT `titlelink` FROM ' . prefix('news_categories') . ' WHERE `id`=' . $parentID;
1842:                             $result = query_single_row($sql);
1843:                             $catobj = new ZenpageCategory($result['titlelink']);
1844:                             $authType = "zp_category_auth_" . $catobj->getID();
1845:                             $check_auth = $catobj->getPassword();
1846:                             $check_user = $catobj->getUser();
1847:                         }
1848:                     }
1849:                     if(!empty($check_auth)) {
1850:                         
1851:                         $check_auth_user[] = array(
1852:                             'authtype' => $authType,
1853:                             'check_auth' => $check_auth, 
1854:                             'check_user' => $check_user
1855:                         );
1856:                     }
1857:                 }
1858:             }
1859:         }
1860:         if (empty($check_auth)) { 
1861:             $authType = 'zp_gallery_auth';
1862:             $check_auth = $_zp_gallery->getPassword();
1863:             $check_user = $_zp_gallery->getUser();
1864:         }
1865:     }
1866:     if (in_context(ZP_ZENPAGE_NEWS_ARTICLE)) {
1867:         
1868:         foreach($check_auth_user as $check) {
1869:             zp_handle_password_single($check['authtype'], $check['check_auth'], $check['check_user']);
1870:         }
1871:     } else {
1872:         zp_handle_password_single($authType, $check_auth, $check_user);
1873:     }
1874: }
1875: 1876: 1877: 1878: 1879: 1880: 1881: 1882: 
1883: function zp_handle_password_single($authType = NULL, $check_auth = NULL, $check_user = NULL) {
1884:     
1885:     if (DEBUG_LOGIN)
1886:         debugLog("zp_handle_password: \$authType=$authType; \$check_auth=$check_auth; \$check_user=$check_user; ");
1887: 
1888:     if (isset($_POST['password']) && isset($_POST['pass'])) { 
1889:         if (isset($_POST['user'])) {
1890:             $post_user = sanitize($_POST['user']);
1891:         } else {
1892:             $post_user = '';
1893:         }
1894:         $post_pass = $_POST['pass']; 
1895: 
1896:         foreach (Zenphoto_Authority::$hashList as $hash => $hi) {
1897:             $auth = Zenphoto_Authority::passwordHash($post_user, $post_pass, $hi);
1898:             $success = ($auth == $check_auth) && $post_user == $check_user;
1899:             if (DEBUG_LOGIN)
1900:                 debugLog("zp_handle_password($success): \$post_user=$post_user; \$post_pass=$post_pass; \$check_auth=$check_auth; \$auth=$auth; \$hash=$hash;");
1901:             if ($success) {
1902:                 break;
1903:             }
1904:         }
1905:         $success = zp_apply_filter('guest_login_attempt', $success, $post_user, $post_pass, $authType);
1906:         if ($success) {
1907:             
1908:             if (DEBUG_LOGIN)
1909:                 debugLog("zp_handle_password: valid credentials");
1910:             zp_setCookie($authType, $auth);
1911:             if (isset($_POST['redirect'])) {
1912:                 $redirect_to = sanitizeRedirect($_POST['redirect'], true);
1913:                 if (!empty($redirect_to)) {
1914:                     header("Location: " . $redirect_to);
1915:                     exitZP();
1916:                 }
1917:             }
1918:         } else {
1919:             
1920:             if (DEBUG_LOGIN)
1921:                 debugLog("zp_handle_password: invalid credentials");
1922:             zp_clearCookie($authType);
1923:             $_zp_login_error = true;
1924:         }
1925:         return;
1926:     }
1927:     if (empty($check_auth)) { 
1928:         return;
1929:     }
1930:     if (($saved_auth = zp_getCookie($authType)) != '') {
1931:         if ($saved_auth == $check_auth) {
1932:             if (DEBUG_LOGIN)
1933:                 debugLog("zp_handle_password: valid cookie");
1934:             return;
1935:         } else {
1936:             
1937:             if (DEBUG_LOGIN)
1938:                 debugLog("zp_handle_password: invalid cookie");
1939:             zp_clearCookie($authType);
1940:         }
1941:     }
1942: }
1943: 
1944: 1945: 1946: 1947: 1948: 
1949: function getOptionFromDB($key) {
1950:     $sql = "SELECT `value` FROM " . prefix('options') . " WHERE `name`=" . db_quote($key) . " AND `ownerid`=0";
1951:     $optionlist = query_single_row($sql, false);
1952:     return @$optionlist['value'];
1953: }
1954: 
1955: 1956: 1957: 1958: 1959: 1960: 1961: 1962: 1963: 
1964: function setThemeOption($key, $value, $album, $theme, $default = false) {
1965:     global $_zp_gallery;
1966:     if (is_null($album)) {
1967:         $id = 0;
1968:     } else {
1969:         $id = $album->getID();
1970:         $theme = $album->getAlbumTheme();
1971:     }
1972:     $creator = THEMEFOLDER . '/' . $theme;
1973: 
1974:     $sql = 'INSERT INTO ' . prefix('options') . ' (`name`,`ownerid`,`theme`,`creator`,`value`) VALUES (' . db_quote($key) . ',0,' . db_quote($theme) . ',' . db_quote($creator) . ',';
1975:     $sqlu = ' ON DUPLICATE KEY UPDATE `value`=';
1976:     if (is_null($value)) {
1977:         $sql .= 'NULL';
1978:         $sqlu .= 'NULL';
1979:     } else {
1980:         $sql .= db_quote($value);
1981:         $sqlu .= db_quote($value);
1982:     }
1983:     $sql .= ') ';
1984:     if (!$default) {
1985:         $sql .= $sqlu;
1986:     }
1987:     $result = query($sql, false);
1988: }
1989: 
1990: 1991: 1992: 1993: 1994: 1995: 
1996: function setThemeOptionDefault($key, $value) {
1997:     $bt = debug_backtrace();
1998:     $b = array_shift($bt);
1999:     $theme = basename(dirname($b['file']));
2000:     setThemeOption($key, $value, NULL, $theme, true);
2001: }
2002: 
2003: 2004: 2005: 2006: 2007: 2008: 2009: 2010: 
2011: function getThemeOption($option, $album = NULL, $theme = NULL) {
2012:     global $_set_theme_album, $_zp_gallery;
2013:     if (is_null($album)) {
2014:         $album = $_set_theme_album;
2015:     }
2016:     if (is_null($album)) {
2017:         $id = 0;
2018:     } else {
2019:         $id = $album->getID();
2020:         $theme = $album->getAlbumTheme();
2021:     }
2022:     if (empty($theme)) {
2023:         $theme = $_zp_gallery->getCurrentTheme();
2024:     }
2025: 
2026:     
2027:     $sql = "SELECT `value` FROM " . prefix('options') . " WHERE `name`=" . db_quote($option) . " AND `ownerid`=" . $id . " AND `theme`=" . db_quote($theme);
2028:     $db = query_single_row($sql);
2029:     if (!$db) {
2030:         
2031:         $sql = "SELECT `value` FROM " . prefix('options') . " WHERE `name`=" . db_quote($option) . " AND `ownerid`=0 AND `theme`=" . db_quote($theme);
2032:         $db = query_single_row($sql);
2033:         if (!$db) {
2034:             
2035:             $sql = "SELECT `value` FROM " . prefix('options') . " WHERE `name`=" . db_quote($option) . " AND `ownerid`=" . $id . " AND `theme`=NULL";
2036:             $db = query_single_row($sql);
2037:             if (!$db) {
2038:                 return getOption($option);
2039:             }
2040:         }
2041:     }
2042:     return $db['value'];
2043: }
2044: 
2045: 2046: 2047: 2048: 2049: 2050: 
2051: function commentsAllowed($type) {
2052:     return getOption($type) && (!MEMBERS_ONLY_COMMENTS || zp_loggedin(ADMIN_RIGHTS | POST_COMMENT_RIGHTS));
2053: }
2054: 
2055: 2056: 2057: 2058: 2059: 2060: 
2061: function getUserIP() {
2062:     $pattern = '~^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$~';
2063:     if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
2064:         $ip = sanitize($_SERVER['HTTP_X_FORWARDED_FOR']);
2065:         if (preg_match($pattern, $ip)) {
2066:             return $ip;
2067:         }
2068:     }
2069:     $ip = sanitize($_SERVER['REMOTE_ADDR']);
2070:     if (preg_match($pattern, $ip)) {
2071:         return $ip;
2072:     }
2073:     return NULL;
2074: }
2075: 
2076: 2077: 2078: 2079: 2080: 2081: 
2082: function seoFriendly($string) {
2083:     $string = trim(preg_replace('~\s+\.\s*~', '.', $string));
2084:     if (zp_has_filter('seoFriendly')) {
2085:         $string = zp_apply_filter('seoFriendly', $string);
2086:     } else { 
2087:         $string = trim($string);
2088:         $string = preg_replace("/\s+/", "-", $string);
2089:         $string = preg_replace("/[^a-zA-Z0-9_.-]/", "-", $string);
2090:         $string = str_replace(array('---', '--'), '-', $string);
2091:     }
2092:     return $string;
2093: }
2094: 
2095: 2096: 2097: 2098: 
2099: function seoFriendlyJS() {
2100:     if (zp_has_filter('seoFriendly_js')) {
2101:         echo zp_apply_filter('seoFriendly_js');
2102:     } else {
2103:         ?>
2104:         function seoFriendlyJS(fname) {
2105:         fname=fname.trim();
2106:         fname=fname.replace(/\s+\.\s*/,'.');
2107:         fname = fname.replace(/\s+/g, '-');
2108:         fname = fname.replace(/[^a-zA-Z0-9_.-]/g, '-');
2109:         fname = fname.replace(/--*/g, '-');
2110:         return fname;
2111:         }
2112:         <?php
2113:     }
2114: }
2115: 
2116: 2117: 2118: 2119: 2120: 2121: 2122: 
2123: function is_connected($host = 'www.zenphoto.org') {
2124:     $err_no = $err_str = false;
2125:     $connected = @fsockopen($host, 80, $errno, $errstr, 0.5);
2126:     if ($connected) {
2127:         fclose($connected);
2128:         return true;
2129:     }
2130:     return false;
2131: }
2132: 
2133: 2134: 2135: 2136: 2137: 2138: 
2139: function debug404($album, $image, $theme) {
2140:     if (DEBUG_404) {
2141:         $list = explode('/', $album);
2142:         if (array_shift($list) == 'cache') {
2143:             return;
2144:         }
2145:         $ignore = array('/favicon.ico', '/zp-data/tést.jpg');
2146:         $target = getRequestURI();
2147:         foreach ($ignore as $uri) {
2148:             if ($target == $uri)
2149:                 return;
2150:         }
2151:         $server = array();
2152:         foreach (array('REQUEST_URI', 'HTTP_REFERER', 'REMOTE_ADDR', 'REDIRECT_STATUS') as $key) {
2153:             $server[$key] = @$_SERVER[$key];
2154:         }
2155:         $request = $_REQUEST;
2156:         $request['theme'] = $theme;
2157:         if (!empty($image)) {
2158:             $request['image'] = $image;
2159:         }
2160: 
2161:         trigger_error(sprintf(gettext('Zenphoto processed a 404 error on %s. See the debug log for details.'), $target), E_USER_NOTICE);
2162:         ob_start();
2163:         var_dump($server);
2164:         $server = preg_replace('~array\s*\(.*\)\s*~', '', html_decode(getBare(ob_get_contents())));
2165:         ob_end_clean();
2166:         ob_start();
2167:         var_dump($request);
2168:         $request['theme'] = $theme;
2169:         if (!empty($image)) {
2170:             $request['image'] = $image;
2171:         }
2172:         $request = preg_replace('~array\s*\(.*\)\s*~', '', html_decode(getBare(ob_get_contents())));
2173:         ob_end_clean();
2174:         debugLog("404 error details\n" . $server . $request);
2175:     }
2176: }
2177: 
2178: 2179: 2180: 2181: 
2182: function getXSRFToken($action) {
2183:     global $_zp_current_admin_obj;
2184:     return sha1($action . prefix(ZENPHOTO_RELEASE) . serialize($_zp_current_admin_obj) . session_id());
2185: }
2186: 
2187: 2188: 2189: 2190: 
2191: function XSRFToken($action) {
2192:     ?>
2193:     <input type="hidden" name="XSRFToken" id="XSRFToken" value="<?php echo getXSRFToken($action); ?>" />
2194:     <?php
2195: }
2196: 
2197: 2198: 2199: 2200: 2201: 2202: 
2203: function cron_starter($script, $params, $offsetPath, $inline = false) {
2204:     global $_zp_authority, $_zp_loggedin, $_zp_current_admin_obj, $_zp_HTML_cache;
2205:     $admin = $_zp_authority->getMasterUser();
2206: 
2207:     if ($inline) {
2208:         $_zp_current_admin_obj = $admin;
2209:         $_zp_loggedin = $_zp_current_admin_obj->getRights();
2210:         foreach ($params as $key => $value) {
2211:             if ($key == 'XSRFTag') {
2212:                 $key = 'XSRFToken';
2213:                 $value = getXSRFToken($value);
2214:             }
2215:             $_POST[$key] = $_GET[$key] = $_REQUEST[$key] = $value;
2216:         }
2217:         require_once($script);
2218:     } else {
2219:         $auth = sha1($script . serialize($admin));
2220:         $paramlist = 'link=' . $script;
2221:         foreach ($params as $key => $value) {
2222:             $paramlist .= '&' . $key . '=' . $value;
2223:         }
2224:         $paramlist .= '&auth=' . $auth . '&offsetPath=' . $offsetPath;
2225:         $_zp_HTML_cache->abortHTMLCache();
2226:         ?>
2227:         <script type="text/javascript">
2228:             
2229:             $.ajax({
2230:                 type: 'POST',
2231:                 cache: false,
2232:                 data: '<?php echo $paramlist; ?>',
2233:                 url: '<?php echo WEBPATH . '/' . ZENFOLDER; ?>/cron_runner.php'
2234:             });
2235:             
2236:         </script>
2237:         <?php
2238:     }
2239: }
2240: 
2241: 2242: 2243: 2244: 2245: 2246: 2247: 2248: 2249: 
2250: function zp_loggedin($rights = ALL_RIGHTS) {
2251:     global $_zp_loggedin;
2252:     return $_zp_loggedin & ($rights | ADMIN_RIGHTS);
2253: }
2254: 
2255: 2256: 2257: 2258: 2259: 2260: 2261: 
2262: function read_exif_data_protected($path) {
2263:     if (DEBUG_EXIF) {
2264:         debugLog("Begin read_exif_data_protected($path)");
2265:         $start = microtime(true);
2266:     }
2267:     try {
2268:         $rslt = read_exif_data_raw($path, false);
2269:     } catch (Exception $e) {
2270:         debugLog("read_exif_data($path) exception: " . $e->getMessage());
2271:         $rslt = array();
2272:     }
2273:     if (DEBUG_EXIF) {
2274:         $time = microtime(true) - $start;
2275:         debugLog(sprintf("End read_exif_data_protected($path) [%f]", $time));
2276:     }
2277:     return $rslt;
2278: }
2279: 
2280: 2281: 2282: 2283: 2284: 2285: 
2286: function getLanguageFlag($lang) {
2287:     if (file_exists(SERVERPATH . '/' . USER_PLUGIN_FOLDER . '/locale/' . $lang . '/flag.png')) {
2288:         $flag = WEBPATH . '/' . USER_PLUGIN_FOLDER . '/locale/' . $lang . '/flag.png';
2289:     } else if (file_exists(SERVERPATH . '/' . ZENFOLDER . '/locale/' . $lang . '/flag.png')) {
2290:         $flag = WEBPATH . '/' . ZENFOLDER . '/locale/' . $lang . '/flag.png';
2291:     } else {
2292:         $flag = WEBPATH . '/' . ZENFOLDER . '/locale/missing_flag.png';
2293:     }
2294:     return $flag;
2295: }
2296: 
2297: 2298: 2299: 2300: 2301: 2302: 2303: 
2304: function getItemByID($table, $id) {
2305:     if ($result = query_single_row('SELECT * FROM ' . prefix($table) . ' WHERE id =' . (int) $id)) {
2306:         switch ($table) {
2307:             case 'images':
2308:                 if ($alb = getItemByID('albums', $result['albumid'])) {
2309:                     return newImage($alb, $result['filename'], true);
2310:                 }
2311:                 break;
2312:             case 'albums':
2313:                 return newAlbum($result['folder'], false, true);
2314:             case 'news':
2315:                 return new ZenpageNews($result['titlelink']);
2316:             case 'pages':
2317:                 return new ZenpagePage($result['titlelink']);
2318:             case 'news_categories':
2319:                 return new ZenpageCategory($result['titlelink']);
2320:         }
2321:     }
2322:     return NULL;
2323: }
2324: 
2325: 2326: 2327: 2328: 2329: 2330: 
2331: function reveal($content, $visible = false) {
2332:     ?>
2333:     <span id="<?php echo $content; ?>_reveal"<?php if ($visible) echo 'style="display:none;"'; ?> class="icons">
2334:         <a href="javascript:reveal('<?php echo $content; ?>')" title="<?php echo gettext('Click to show content'); ?>">
2335:             <img src="../../images/arrow_down.png" alt="" class="icon-position-top4" />
2336:         </a>
2337:     </span>
2338:     <span id="<?php echo $content; ?>_hide"<?php if (!$visible) echo 'style="display:none;"'; ?> class="icons">
2339:         <a href="javascript:reveal('<?php echo $content; ?>')" title="<?php echo gettext('Click to hide content'); ?>">
2340:             <img src="../../images/arrow_up.png" alt="" class="icon-position-top4" />
2341:         </a>
2342:     </span>
2343:     <?php
2344: }
2345: 
2346: 2347: 2348: 2349: 2350: 2351: 2352: 2353: 
2354: function applyMacros($text) {
2355:     $content_macros = getMacros();
2356:     preg_match_all('/\[(\w+)(.*?)\]/i', $text, $instances);
2357:     foreach ($instances[0] as $instance => $macro_instance) {
2358:         $macroname = strtoupper($instances[1][$instance]);
2359:         if (array_key_exists($macroname, $content_macros)) {
2360:             $macro = $content_macros[$macroname];
2361:             $p = $instances[2][$instance];
2362:             $data = NULL;
2363:             $class = $macro['class'];
2364:             if ($p) {
2365:                 $p = trim(utf8::sanitize(str_replace("\xC2\xA0", ' ', strip_tags($p)))); 
2366:                 $p = preg_replace("~\s+=\s+(?=(?:[^\"]*+\"[^\"]*+\")*+[^\"]*+$)~", "=", $p); 
2367:                 preg_match_all("~'[^'\"]++'|\"[^\"]++\"|[^\s]++~", $p, $l); 
2368:                 $parms = array();
2369:                 $k = 0;
2370:                 foreach ($l[0] as $s) {
2371:                     if ($s != ',') {
2372:                         $parms[$k++] = trim($s, '\'"'); 
2373:                     }
2374:                 }
2375:             } else {
2376:                 $parms = array();
2377:             }
2378:             $parameters = array();
2379:             if (!empty($macro['params'])) {
2380:                 $err = false;
2381:                 foreach ($macro['params'] as $key => $type) {
2382:                     $data = false;
2383:                     if (array_key_exists($key, $parms)) {
2384:                         switch (trim($type, '*')) {
2385:                             case 'int':
2386:                                 if (is_numeric($parms[$key])) {
2387:                                     $parameters[] = (int) $parms[$key];
2388:                                 } else {
2389:                                     $data = '<span class="error">' . sprintf(gettext('<em>[%1$s]</em> parameter %2$d should be a number.'), trim($macro_instance, '[]'), $key + 1) . '</span>';
2390:                                     $class = 'error';
2391:                                 }
2392:                                 break;
2393:                             case 'string':
2394:                                 if (is_string($parms[$key])) {
2395:                                     $parameters[] = $parms[$key];
2396:                                 } else {
2397:                                     $data = '<span class="error">' . sprintf(gettext('<em>[%1$s]</em> parameter %2$d should be a string.'), trim($macro_instance, '[]'), $key + 1) . '</span>';
2398:                                     $class = 'error';
2399:                                 }
2400:                                 break;
2401:                             case 'bool':
2402:                                 switch (strtolower($parms[$key])) {
2403:                                     case ("true"):
2404:                                         $parameters[] = true;
2405:                                         break;
2406:                                     case ("false"):
2407:                                         $parameters[] = false;
2408:                                         break;
2409:                                     default:
2410:                                         $data = '<span class="error">' . sprintf(gettext('<em>[%1$s]</em> parameter %2$d should be <code>true</code> or <code>false</code>.'), trim($macro_instance, '[]'), $key + 1) . '</span>';
2411:                                         $class = 'error';
2412:                                         break;
2413:                                 }
2414:                                 break;
2415:                             case 'array':
2416:                                 $l = array_slice($parms, $key);
2417:                                 $parms = array();
2418:                                 foreach ($l as $key => $p) {
2419:                                     $x = explode('=', $p);
2420:                                     if (count($x) == 2) {
2421:                                         $parms[$x[0]] = $x[1];
2422:                                     } else {
2423:                                         $parms[$key] = $x[0];
2424:                                     }
2425:                                 }
2426:                                 $parameters[] = $parms;
2427:                                 break;
2428:                             default:
2429:                                 $data = '<span class="error">' . sprintf(gettext('<em>[%1$s]</em> parameter %2$d is incorrectly defined.'), trim($macro_instance, '[]'), $key + 1) . '</span>';
2430:                                 $class = 'error';
2431:                                 break;
2432:                         }
2433:                     } else {
2434:                         if (strpos($type, '*') === false) {
2435:                             $data = '<span class="error">' . sprintf(gettext('<em>[%1$s]</em> parameter %2$d is missing.'), trim($macro_instance, '[]'), $key + 1) . '</span>';
2436:                             $class = 'error';
2437:                         }
2438:                         break;
2439:                     }
2440:                 }
2441:             } else {
2442:                 if (!empty($p)) {
2443:                     $class = 'error';
2444:                     $data = '<span class="error">' . sprintf(gettext('<em>[%1$s]</em> macro does not take parameters'), trim($macro_instance, '[]')) . '</span>';
2445:                 }
2446:             }
2447:             switch ($class) {
2448:                 case 'error':
2449:                     break;
2450:                 case 'function';
2451:                 case 'procedure':
2452:                     if (is_callable($macro['value'])) {
2453:                         if ($class == 'function') {
2454:                             ob_start();
2455:                             $data = call_user_func_array($macro['value'], $parameters);
2456:                             if (empty($data)) {
2457:                                 $data = ob_get_contents();
2458:                             }
2459:                             ob_end_clean();
2460:                         } else {
2461:                             ob_start();
2462:                             call_user_func_array($macro['value'], $parameters);
2463:                             $data = ob_get_contents();
2464:                             ob_end_clean();
2465:                         }
2466:                         if (empty($data)) {
2467:                             $data = '<span class="error">' . sprintf(gettext('<em>[%1$s]</em> retuned no data'), trim($macro_instance, '[]')) . '</span>';
2468:                         } else {
2469:                             $data = "\n<!--Begin " . $macroname . "-->\n" . $data . "\n<!--End " . $macroname . "-->\n";
2470:                         }
2471:                     } else {
2472:                         $data = '<span class="error">' . sprintf(gettext('<em>[%1$s]</em> <code>%2$s</code> is not callable'), trim($macro_instance, '[]'), $macro['value']) . '</span>';
2473:                     }
2474:                     break;
2475:                 case 'constant':
2476:                     $data = "\n<!--Begin " . $macroname . "-->\n" . $macro['value'] . "\n<!--End " . $macroname . "-->\n";
2477:                     break;
2478:                 case 'expression':
2479:                     $expression = '$data = ' . $macro['value'];
2480:                     $parms = array_reverse($parms, true);
2481:                     preg_match_all('/\$\d+/', $macro['value'], $replacements);
2482:                     foreach ($replacements as $rkey => $v) {
2483:                         if (empty($v))
2484:                             unset($replacements[$rkey]);
2485:                     }
2486:                     if (count($parms) == count($replacements)) {
2487: 
2488:                         foreach ($parms as $key => $value) {
2489:                             $key++;
2490:                             $expression = preg_replace('/\$' . $key . '/', db_quote($value), $expression);
2491:                         }
2492:                         eval($expression);
2493:                         if (!isset($data) || is_null($data)) {
2494:                             $data = '<span class="error">' . sprintf(gettext('<em>[%1$s]</em> retuned no data'), trim($macro_instance, '[]')) . '</span>';
2495:                         } else {
2496:                             $data = "\n<!--Begin " . $macroname . "-->\n" . $data . "\n<!--End " . $macroname . "-->\n";
2497:                         }
2498:                     } else {
2499:                         $data = '<span class="error">' . sprintf(ngettext('<em>[%1$s]</em> takes %2$d parameter', '<em>[%1$s]</em> takes %2$d parameters', count($replacements)), trim($macro_instance, '[]'), count($replacements)) . '</span>';
2500:                     }
2501:                     break;
2502:             }
2503:             $text = str_replace($macro_instance, $data, $text);
2504:         }
2505:     }
2506:     return $text;
2507: }
2508: 
2509: function getMacros() {
2510:     global $_zp_content_macros;
2511:     if (is_null($_zp_content_macros)) {
2512:         $_zp_content_macros = zp_apply_filter('content_macro', array());
2513:     }
2514:     return $_zp_content_macros;
2515: }
2516: 
2517: 2518: 2519: 2520: 2521: 2522: 2523: 2524: 2525: 2526: 2527: 2528: 
2529: function getNestedAlbumList($subalbum, $levels, $checkalbumrights = true, $level = array()) {
2530:     global $_zp_gallery;
2531:     $cur = count($level);
2532:     $levels--; 
2533:     if (is_null($subalbum)) {
2534:         $albums = $_zp_gallery->getAlbums();
2535:     } else {
2536:         $albums = $subalbum->getAlbums();
2537:     }
2538:     $list = array();
2539:     foreach ($albums as $analbum) {
2540:         $albumobj = newAlbum($analbum);
2541:   $accessallowed = true;
2542:   if($checkalbumrights) {
2543:     $accessallowed = $albumobj->isMyItem(ALBUM_RIGHTS);
2544:   }
2545:         if (!is_null($subalbum) || $accessallowed) {
2546:             $level[$cur] = sprintf('%03u', $albumobj->getSortOrder());
2547:             $list[] = array('name' => $analbum, 'sort_order' => $level);
2548:             if ($cur < $levels && ($albumobj->getNumAlbums()) && !$albumobj->isDynamic()) {
2549:                 $list = array_merge($list, getNestedAlbumList($albumobj, $levels + 1, $checkalbumrights, $level));
2550:             }
2551:         }
2552:     }
2553:     return $list;
2554: }
2555: 
2556: class zpFunctions {
2557: 
2558:     2559: 2560: 2561: 
2562:     static function LanguageSubdomains() {
2563:         $domains = array();
2564:         $langs = generateLanguageList();
2565:         $domains = array();
2566:         foreach ($langs as $value) {
2567:             $domains[substr($value, 0, 2)][] = $value;
2568:         }
2569:         $langs = array();
2570:         foreach ($domains as $simple => $full) {
2571:             if (count($full) > 1) {
2572:                 foreach ($full as $loc) {
2573:                     $langs[$loc] = $loc;
2574:                 }
2575:             } else {
2576:                 $langs[$full[0]] = $simple;
2577:             }
2578:         }
2579:         if (isset($langs[SITE_LOCALE])) {
2580:             $langs[SITE_LOCALE] = '';
2581:         }
2582:         return $langs;
2583:     }
2584: 
2585:     2586: 2587: 2588: 2589: 2590: 2591: 2592: 
2593:     static function getLanguageText($loc = NULL, $separator = NULL) {
2594:         global $_locale_Subdomains;
2595:         if (is_null($loc)) {
2596:             $text = @$_locale_Subdomains[zp_getCookie('dynamic_locale')];
2597:         } else {
2598:             $text = @$_locale_Subdomains[$loc];
2599:             
2600:             if(empty($text)) {
2601:                 $text = $loc;
2602:             }
2603:         }
2604:         if (!is_null($separator)) {
2605:             $text = str_replace('_', $separator, $text);
2606:         }
2607:         return $text;
2608:     }
2609: 
2610:     2611: 2612: 2613: 
2614:     static function setexifvars() {
2615:         global $_zp_exifvars;
2616:         2617: 2618: 2619: 2620: 2621: 2622: 
2623:         $_zp_exifvars = array(
2624:                         
2625:                         'EXIFMake'                                   => array('IFD0', 'Make', gettext('Camera Maker'), true, 52, true, 'string'),
2626:                         'EXIFModel'                                  => array('IFD0', 'Model', gettext('Camera Model'), true, 52, true, 'string'),
2627:                         'EXIFDescription'                        => array('IFD0', 'ImageDescription', gettext('Image Title'), false, 52, true, 'string'),
2628:                         'IPTCObjectName'                         => array('IPTC', 'ObjectName', gettext('Object Name'), false, 256, true, 'string'),
2629:                         'IPTCImageHeadline'                  => array('IPTC', 'ImageHeadline', gettext('Image Headline'), false, 256, true, 'string'),
2630:                         'IPTCImageCaption'                   => array('IPTC', 'ImageCaption', gettext('Image Caption'), false, 2000, true, 'string'),
2631:                         'IPTCImageCaptionWriter'         => array('IPTC', 'ImageCaptionWriter', gettext('Image Caption Writer'), false, 32, true, 'string'),
2632:                         'EXIFDateTime'                           => array('SubIFD', 'DateTime', gettext('Time Taken'), true, 52, true, 'time'),
2633:                         'EXIFDateTimeOriginal'           => array('SubIFD', 'DateTimeOriginal', gettext('Original Time Taken'), true, 52, true, 'time'),
2634:                         'EXIFDateTimeDigitized'          => array('SubIFD', 'DateTimeDigitized', gettext('Time Digitized'), true, 52, true, 'time'),
2635:                         'IPTCDateCreated'                        => array('IPTC', 'DateCreated', gettext('Date Created'), false, 8, true, 'time'),
2636:                         'IPTCTimeCreated'                        => array('IPTC', 'TimeCreated', gettext('Time Created'), false, 11, true, 'time'),
2637:                         'IPTCDigitizeDate'                   => array('IPTC', 'DigitizeDate', gettext('Digital Creation Date'), false, 8, true, 'time'),
2638:                         'IPTCDigitizeTime'                   => array('IPTC', 'DigitizeTime', gettext('Digital Creation Time'), false, 11, true, 'time'),
2639:                         'EXIFArtist'                                 => array('IFD0', 'Artist', gettext('Artist'), false, 52, true, 'string'),
2640:                         'IPTCImageCredit'                        => array('IPTC', 'ImageCredit', gettext('Image Credit'), false, 32, true, 'string'),
2641:                         'IPTCByLine'                                 => array('IPTC', 'ByLine', gettext('Byline'), false, 32, true, 'string'),
2642:                         'IPTCByLineTitle'                        => array('IPTC', 'ByLineTitle', gettext('Byline Title'), false, 32, true, 'string'),
2643:                         'IPTCSource'                                 => array('IPTC', 'Source', gettext('Image Source'), false, 32, true, 'string'),
2644:                         'IPTCContact'                                => array('IPTC', 'Contact', gettext('Contact'), false, 128, true, 'string'),
2645:                         'EXIFCopyright'                          => array('IFD0', 'Copyright', gettext('Copyright Holder'), false, 128, true, 'string'),
2646:                         'IPTCCopyright'                          => array('IPTC', 'Copyright', gettext('Copyright Notice'), false, 128, true, 'string'),
2647:                         'IPTCKeywords'                           => array('IPTC', 'Keywords', gettext('Keywords'), false, 0, true, 'string'),
2648:                         'EXIFExposureTime'                   => array('SubIFD', 'ExposureTime', gettext('Shutter Speed'), true, 52, true, 'string'),
2649:                         'EXIFFNumber'                                => array('SubIFD', 'FNumber', gettext('Aperture'), true, 52, true, 'number'),
2650:                         'EXIFISOSpeedRatings'                => array('SubIFD', 'ISOSpeedRatings', gettext('ISO Sensitivity'), true, 52, true, 'number'),
2651:                         'EXIFExposureBiasValue'          => array('SubIFD', 'ExposureBiasValue', gettext('Exposure Compensation'), true, 52, true, 'string'),
2652:                         'EXIFMeteringMode'                   => array('SubIFD', 'MeteringMode', gettext('Metering Mode'), true, 52, true, 'string'),
2653:                         'EXIFFlash'                                  => array('SubIFD', 'Flash', gettext('Flash Fired'), true, 52, true, 'string'),
2654:                         'EXIFImageWidth'                         => array('SubIFD', 'ExifImageWidth', gettext('Original Width'), false, 52, true, 'number'),
2655:                         'EXIFImageHeight'                        => array('SubIFD', 'ExifImageHeight', gettext('Original Height'), false, 52, true, 'number'),
2656:                         'EXIFOrientation'                        => array('IFD0', 'Orientation', gettext('Orientation'), false, 52, true, 'string'),
2657:                         'EXIFSoftware'                           => array('IFD0', 'Software', gettext('Software'), false, 999, true, 'string'),
2658:                         'EXIFContrast'                           => array('SubIFD', 'Contrast', gettext('Contrast Setting'), false, 52, true, 'string'),
2659:                         'EXIFSharpness'                          => array('SubIFD', 'Sharpness', gettext('Sharpness Setting'), false, 52, true, 'string'),
2660:                         'EXIFSaturation'                         => array('SubIFD', 'Saturation', gettext('Saturation Setting'), false, 52, true, 'string'),
2661:                         'EXIFWhiteBalance'                   => array('SubIFD', 'WhiteBalance', gettext('White Balance'), false, 52, true, 'string'),
2662:                         'EXIFSubjectDistance'                => array('SubIFD', 'SubjectDistance', gettext('Subject Distance'), false, 52, true, 'number'),
2663:                         'EXIFFocalLength'                        => array('SubIFD', 'FocalLength', gettext('Focal Length'), true, 52, true, 'number'),
2664:                         'EXIFLensType'                           => array('SubIFD', 'LensType', gettext('Lens Type'), false, 52, true, 'string'),
2665:                         'EXIFLensInfo'                           => array('SubIFD', 'LensInfo', gettext('Lens Info'), false, 52, true, 'string'),
2666:                         'EXIFFocalLengthIn35mmFilm'  => array('SubIFD', 'FocalLengthIn35mmFilm', gettext('35mm Focal Length Equivalent'), false, 52, true, 'string'),
2667:                         'IPTCCity'                                   => array('IPTC', 'City', gettext('City'), false, 32, true, 'string'),
2668:                         'IPTCSubLocation'                        => array('IPTC', 'SubLocation', gettext('Sub-location'), false, 32, true, 'string'),
2669:                         'IPTCState'                                  => array('IPTC', 'State', gettext('Province/State'), false, 32, true, 'string'),
2670:                         'IPTCLocationCode'                   => array('IPTC', 'LocationCode', gettext('Country/Primary Location Code'), false, 3, true, 'string'),
2671:                         'IPTCLocationName'                   => array('IPTC', 'LocationName', gettext('Country/Primary Location Name'), false, 64, true, 'string'),
2672:                         'IPTCContentLocationCode'        => array('IPTC', 'ContentLocationCode', gettext('Content Location Code'), false, 3, true, 'string'),
2673:                         'IPTCContentLocationName'        => array('IPTC', 'ContentLocationName', gettext('Content Location Name'), false, 64, true, 'string'),
2674:                         'EXIFGPSLatitude'                        => array('GPS', 'Latitude', gettext('Latitude'), false, 52, true, 'number'),
2675:                         'EXIFGPSLatitudeRef'                 => array('GPS', 'Latitude Reference', gettext('Latitude Reference'), false, 52, true, 'string'),
2676:                         'EXIFGPSLongitude'                   => array('GPS', 'Longitude', gettext('Longitude'), false, 52, true, 'number'),
2677:                         'EXIFGPSLongitudeRef'                => array('GPS', 'Longitude Reference', gettext('Longitude Reference'), false, 52, true, 'string'),
2678:                         'EXIFGPSAltitude'                        => array('GPS', 'Altitude', gettext('Altitude'), false, 52, true, 'number'),
2679:                         'EXIFGPSAltitudeRef'                 => array('GPS', 'Altitude Reference', gettext('Altitude Reference'), false, 52, true, 'string'),
2680:                         'IPTCOriginatingProgram'         => array('IPTC', 'OriginatingProgram', gettext('Originating Program '), false, 32, true, 'string'),
2681:                         'IPTCProgramVersion'                 => array('IPTC', 'ProgramVersion', gettext('Program Version'), false, 10, true, 'string'),
2682:                         'VideoFormat'                                => array('VIDEO', 'fileformat', gettext('Video File Format'), false, 32, true, 'string'),
2683:                         'VideoSize'                                  => array('VIDEO', 'filesize', gettext('Video File Size'), false, 32, true, 'number'),
2684:                         'VideoArtist'                                => array('VIDEO', 'artist', gettext('Video Artist'), false, 256, true, 'string'),
2685:                         'VideoTitle'                                 => array('VIDEO', 'title', gettext('Video Title'), false, 256, true, 'string'),
2686:                         'VideoBitrate'                           => array('VIDEO', 'bitrate', gettext('Bitrate'), false, 32, true, 'number'),
2687:                         'VideoBitrate_mode'                  => array('VIDEO', 'bitrate_mode', gettext('Bitrate_Mode'), false, 32, true, 'string'),
2688:                         'VideoBits_per_sample'           => array('VIDEO', 'bits_per_sample', gettext('Bits per sample'), false, 32, true, 'number'),
2689:                         'VideoCodec'                                 => array('VIDEO', 'codec', gettext('Codec'), false, 32, true, 'string'),
2690:                         'VideoCompression_ratio'         => array('VIDEO', 'compression_ratio', gettext('Compression Ratio'), false, 32, true, 'number'),
2691:                         'VideoDataformat'                        => array('VIDEO', 'dataformat', gettext('Video Dataformat'), false, 32, true, 'string'),
2692:                         'VideoEncoder'                           => array('VIDEO', 'encoder', gettext('File Encoder'), false, 10, true, 'string'),
2693:                         'VideoSamplerate'                        => array('VIDEO', 'Samplerate', gettext('Sample rate'), false, 32, true, 'number'),
2694:                         'VideoChannelmode'                   => array('VIDEO', 'channelmode', gettext('Channel mode'), false, 32, true, 'string'),
2695:                         'VideoFormat'                                => array('VIDEO', 'format', gettext('Format'), false, 10, true, 'string'),
2696:                         'VideoChannels'                          => array('VIDEO', 'channels', gettext('Channels'), false, 10, true, 'number'),
2697:                         'VideoFramerate'                         => array('VIDEO', 'framerate', gettext('Frame rate'), false, 32, true, 'number'),
2698:                         'VideoResolution_x'                  => array('VIDEO', 'resolution_x', gettext('X Resolution'), false, 32, true, 'number'),
2699:                         'VideoResolution_y'                  => array('VIDEO', 'resolution_y', gettext('Y Resolution'), false, 32, true, 'number'),
2700:                         'VideoAspect_ratio'                  => array('VIDEO', 'pixel_aspect_ratio', gettext('Aspect ratio'), false, 32, true, 'number'),
2701:                         'VideoPlaytime'                          => array('VIDEO', 'playtime_string', gettext('Play Time'), false, 10, true, 'number'),
2702:                         'XMPrating'                                  => array('XMP', 'rating', gettext('XMP Rating'), false, 10, true, 'string'),
2703:         );
2704:         foreach ($_zp_exifvars as $key => $item) {
2705:             if (!is_null($disable = getOption($key . '-disabled'))) {
2706:                 $_zp_exifvars[$key][5] = !$disable;
2707:             }
2708:             $_zp_exifvars[$key][3] = getOption($key);
2709:         }
2710:     }
2711: 
2712:     2713: 2714: 2715: 
2716:     static function hasPrimaryScripts() {
2717:         if (!defined('PRIMARY_INSTALLATION')) {
2718:             if (function_exists('readlink') && ($zen = str_replace('\\', '/', @readlink(SERVERPATH . '/' . ZENFOLDER)))) {
2719:                 
2720:                 $os = strtoupper(PHP_OS);
2721:                 $sp = SERVERPATH;
2722:                 if (substr($os, 0, 3) == 'WIN' || $os == 'DARWIN') { 
2723:                     $sp = strtolower($sp);
2724:                     $zen = strtolower($zen);
2725:                 }
2726:                 define('PRIMARY_INSTALLATION', $sp == dirname($zen));
2727:             } else {
2728:                 define('PRIMARY_INSTALLATION', true);
2729:             }
2730:         }
2731:         return PRIMARY_INSTALLATION;
2732:     }
2733: 
2734:     2735: 2736: 2737: 2738: 2739: 
2740:     static function removeDir($path, $within = false) {
2741:         if (($dir = @opendir($path)) !== false) {
2742:             while (($file = readdir($dir)) !== false) {
2743:                 if ($file != '.' && $file != '..') {
2744:                     if ((is_dir($path . '/' . $file))) {
2745:                         if (!zpFunctions::removeDir($path . '/' . $file)) {
2746:                             return false;
2747:                         }
2748:                     } else {
2749:                         @chmod($path . $file, 0777);
2750:                         if (!@unlink($path . '/' . $file)) {
2751:                             return false;
2752:                         }
2753:                     }
2754:                 }
2755:             }
2756:             closedir($dir);
2757:             if (!$within) {
2758:                 @chmod($path, 0777);
2759:                 if (!@rmdir($path)) {
2760:                     return false;
2761:                 }
2762:             }
2763:             return true;
2764:         }
2765:         return false;
2766:     }
2767: 
2768:     2769: 2770: 2771: 
2772:     static function tagURLs($text) {
2773:         if (is_string($text) && preg_match('/^a:[0-9]+:{/', $text)) { 
2774:             $text = getSerializedArray($text);
2775:             $serial = true;
2776:         } else {
2777:             $serial = false;
2778:         }
2779:         if (is_array($text)) {
2780:             foreach ($text as $key => $textelement) {
2781:                 $text[$key] = self::TagURLs($textelement);
2782:             }
2783:             if ($serial) {
2784:                 $text = serialize($text);
2785:             }
2786:         } else {
2787:             $text = str_replace(WEBPATH, '{*WEBPATH*}', str_replace(FULLWEBPATH, '{*FULLWEBPATH*}', $text));
2788:         }
2789:         return $text;
2790:     }
2791: 
2792:     2793: 2794: 2795: 2796: 
2797:     static function unTagURLs($text) {
2798:         if (is_string($text) && preg_match('/^a:[0-9]+:{/', $text)) { 
2799:             $text = getSerializedArray($text);
2800:             $serial = true;
2801:         } else {
2802:             $serial = false;
2803:         }
2804:         if (is_array($text)) {
2805:             foreach ($text as $key => $textelement) {
2806:                 $text[$key] = self::unTagURLs($textelement);
2807:             }
2808:             if ($serial) {
2809:                 $text = serialize($text);
2810:             }
2811:         } else {
2812:             $text = str_replace('{*WEBPATH*}', WEBPATH, str_replace('{*FULLWEBPATH*}', FULLWEBPATH, $text));
2813:         }
2814:         return $text;
2815:     }
2816: 
2817:     2818: 2819: 2820: 2821: 
2822:     static function updateImageProcessorLink($text) {
2823:         if (is_string($text) && preg_match('/^a:[0-9]+:{/', $text)) { 
2824:             $text = getSerializedArray($text);
2825:             $serial = true;
2826:         } else {
2827:             $serial = false;
2828:         }
2829:         if (is_array($text)) {
2830:             foreach ($text as $key => $textelement) {
2831:                 $text[$key] = self::updateImageProcessorLink($textelement);
2832:             }
2833:             if ($serial) {
2834:                 $text = serialize($text);
2835:             }
2836:         } else {
2837:             preg_match_all('|<\s*img.*?\ssrc\s*=\s*"([^"]*)?|', $text, $matches);
2838:             foreach ($matches[1] as $key => $match) {
2839:                 preg_match('|.*i\.php\?(.*)|', $match, $imgproc);
2840:                 if ($imgproc) {
2841:                     $match = preg_split('~\&[amp;]*~', $imgproc[1]);
2842:                     $set = array();
2843:                     foreach ($match as $v) {
2844:                         $s = explode('=', $v);
2845:                         $set[$s[0]] = $s[1];
2846:                     }
2847:                     $args = getImageArgs($set);
2848:                     $imageuri = getImageURI($args, urldecode($set['a']), urldecode($set['i']), NULL);
2849:                     if (strpos($imageuri, 'i.php') === false) {
2850:                         $text = str_replace($matches[1][$key], $imageuri, $text);
2851:                     }
2852:                 }
2853:             }
2854:         }
2855:         return $text;
2856:     }
2857: 
2858:     static function pluginDebug($extension, $priority, $start) {
2859:         list($usec, $sec) = explode(" ", microtime());
2860:         $end = (float) $usec + (float) $sec;
2861:         $class = array();
2862:         if ($priority & CLASS_PLUGIN) {
2863:             $class[] = 'CLASS';
2864:         }
2865:         if ($priority & ADMIN_PLUGIN) {
2866:             $class[] = 'ADMIN';
2867:         }
2868:         if ($priority & FEATURE_PLUGIN) {
2869:             $class[] = 'FEATURE';
2870:         }
2871:         if ($priority & THEME_PLUGIN) {
2872:             $class[] = 'THEME';
2873:         }
2874:         if (empty($class))
2875:             $class[] = 'theme';
2876:         debugLog(sprintf('    ' . $extension . '(%s:%u)=>%.4fs', implode('|', $class), $priority & PLUGIN_PRIORITY, $end - $start));
2877:     }
2878:     
2879:     2880: 2881: 2882: 2883: 2884: 2885: 2886: 
2887:     static function removeTrailingSlash($string) {
2888:         if (substr($string, -1) == '/') {
2889:             $length = strlen($string) - 1;
2890:             return substr($string, 0, $length);
2891:         }
2892:         return $string;
2893:     }
2894:     
2895:     2896: 2897: 2898: 2899: 2900: 2901: 2902: 2903: 
2904:     static function tidyHTML($html) {
2905:         if (class_exists('tidy')) {
2906:             $options = array(
2907:                     'new-blocklevel-tags' => 'article aside audio bdi canvas details dialog figcaption figure footer header main nav section source summary template track video',
2908:                     'new-empty-tags' => 'command embed keygen source track wbr',
2909:                     'new-inline-tags' => 'audio command datalist embed keygen mark menuitem meter output progress source time video wbr',
2910:                     'show-body-only' => true
2911:             );
2912:             $tidy = new tidy();
2913:             $tidy->parseString($html, $options, 'utf8');
2914:             $tidy->cleanRepair();
2915:             return trim($tidy);
2916:         }
2917:         return $html;
2918:     }
2919: 
2920: }
2921: 
2922: 2923: 2924: 
2925: class _zp_captcha {
2926: 
2927:     var $name = NULL; 
2928: 
2929:     function getCaptcha($prompt) {
2930:         return array('input' => NULL, 'html' => '<p class="errorbox">' . gettext('No captcha handler is enabled.') . '</p>', 'hidden' => '');
2931:     }
2932: 
2933:     function checkCaptcha($s1, $s2) {
2934:         return false;
2935:     }
2936: 
2937: }
2938: 
2939: 2940: 2941: 
2942: class _zp_HTML_cache {
2943: 
2944:     function disable() {
2945: 
2946:     }
2947: 
2948:     function startHTMLCache() {
2949: 
2950:     }
2951: 
2952:     function abortHTMLCache() {
2953: 
2954:     }
2955: 
2956:     function endHTMLCache() {
2957: 
2958:     }
2959: 
2960:     function clearHtmlCache() {
2961: 
2962:     }
2963: 
2964: }
2965: 
2966: zpFunctions::setexifvars();
2967: $_locale_Subdomains = zpFunctions::LanguageSubdomains();
2968: ?>
2969: