*/
function strToLower($string) {
return strtr($string, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
}
/**
* ASCII version of PHP's strtoupper().
* @param string $string
* @return string uppercase version of the string
*/
function strToUpper($string) {
return strtr($string, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
}
/**
* Checks whether the given HTTP header is safe.
*
* PHP versions before PHP 4.4.2 / PHP 5.1.2 allowed for HTTP header injection (HTTP RS).
* This function ensures that servers running older PHP versions are protected as well.
*
* @param string $header
* @return bool true if the given header is safe
*/
function isSafeHttpHeader($header) {
if (!is_string($header)) {
return false;
}
/* Don't allow plain occurrences of CR or LF */
if (strpos($header, chr(13)) !== false || strpos($header, chr(10)) !== false) {
return false;
}
/* Don't allow (x times) url encoded versions of CR or LF */
if (preg_match('/%(25)*(0a|0d)/i', $header)) {
return false;
}
return true;
}
}
?>
($themeId) {
$validTheme = false;
list ($ret, $theme) = GalleryCoreApi::loadPlugin('theme', $themeId, false, true);
if ($ret) {
return array($ret, null);
}
if (isset($theme)) {
list ($ret, $validTheme) = $theme->isActive();
if ($ret) {
return array($ret, null);
}
}
if (!$validTheme) {
$theme = null;
}
return array(null, $theme);
}
/**
* Method to opt-in to managed HTTP cache control
*
* Override this method in a view to opt-out from the managed cache control and to set the
* cache headers yourself. (Like isImmediate() and similar methods)
*
* @return bool (default true) to opt-in to itemId oriented cache control
*/
function autoCacheControl() {
return true;
}
/**
* Set cache headers for sensitive pages
* @param GalleryTemplate $template (optional) Adding HTML cache headers to this template
* @param string $access (optional) no-cache
* @return GalleryStatus
*/
function setCacheControl(&$template, $access=null) {
global $gallery;
$phpVm = $gallery->getPhpVm();
$itemId = (int)GalleryUtilities::getRequestVariables('itemId');
if (!isset($access)) {
switch ($this->getViewType()) {
case VIEW_TYPE_ADMIN:
$access = 'no-cache';
break;
case VIEW_TYPE_MODULE:
if (empty($itemId)) {
$access = 'no-cache';
break;
}
/* If itemId is defined, handle the same way as SHOW_ITEM type */
case VIEW_TYPE_SHOW_ITEM:
list ($ret, $anonymousUserId) = GalleryCoreApi::getAnonymousUserId();
if ($ret) {
return $ret;
}
/* Pages shouldn't be cached if not accessible for anonymous */
if (empty($itemId)) {
/* If we don't have an itemId, default to the root album */
list ($ret, $itemId) = GalleryCoreApi::getDefaultAlbumId();
if ($ret) {
return $ret;
}
}
list ($ret, $anonymousViewable) = GalleryCoreApi::hasItemPermission(
$itemId, 'core.view', $anonymousUserId, false);
if ($ret) {
return $ret;
}
if (!$anonymousViewable) {
$access = 'no-cache';
}
break;
default:
$access = '';
}
}
/* http://www.mnot.net/cache_docs */
if ($access == 'no-cache') {
$expires = $gallery->getHttpDate($phpVm->time() - 7*24*3600);
if (!($phpVm->headers_sent())) {
$phpVm->header('Cache-Control: ' . $access);
$phpVm->header('Pragma: ' . $access);
$phpVm->header('Expires: ' . $expires);
}
if (isset($template)) {
$template->meta('Cache-Control', $access, true);
$template->meta('Pragma', $access, true);
$template->meta('Expires', $expires, true);
}
}
return null;
}
/**
* Set standard user information available for every view.
* @param GalleryTemplate $template
* @return GalleryStatus
* @static
*/
function setStandardTemplateVariables(&$template) {
global $gallery;
$session =& $gallery->getSession();
$user = (array)$gallery->getActiveUser();
list ($ret, $user['isGuest']) = GalleryCoreApi::isAnonymousUser($user['id']);
if ($ret) {
return $ret;
}
$user['isRegisteredUser'] = !$user['isGuest'];
list ($ret, $user['isAdmin']) = GalleryCoreApi::isUserInSiteAdminGroup();
if ($ret) {
$user['isAdmin'] = false;
}
$template->setVariable('user', $user);
$themeVars = array('guestPreviewMode' => $session->get('theme.guestPreviewMode') ? 1 : 0);
if (!$themeVars['guestPreviewMode']) {
$themeVars['actingUserId'] = $gallery->getActiveUserId();
} else {
list ($ret, $themeVars['actingUserId']) = GalleryCoreApi::getAnonymousUserId();
if ($ret) {
return $ret;
}
}
$template->setVariable('theme', $themeVars);
return null;
}
/**
* Process possible permission errors when accessing a view.
* If the given status indicates permission denied or missing object and this is a guest
* user, redirect to the login view. Otherwise return given status to be shown by the
* error handler. Missing object is treated like permission denied to avoid information
* disclosure by trying URLs with different ids.
* @param GalleryStatus $ret or null
* @return array for return from GalleryView::loadTemplate or null
* @access protected
*/
function _permissionCheck($ret) {
global $gallery;
$session =& $gallery->getSession();
$result = null;
if ($ret) {
list ($ret2, $inGroup) = GalleryCoreApi::isUserInSiteAdminGroup();
/* MISSING_OBJECT should be handled like PERMISSION_DENIED, unless it's an admin */
if ($ret->getErrorCode() & ERROR_MISSING_OBJECT && ($ret2 || !$inGroup)) {
$ret->addErrorCode(ERROR_PERMISSION_DENIED);
}
$result = array($ret, null);
if ($ret2) {
return $result;
}
if ($ret->getErrorCode() & ERROR_PERMISSION_DENIED) {
list ($ret2, $isAnonymous) = GalleryCoreApi::isAnonymousUser();
if ($ret2) {
return $result;
}
if ($isAnonymous || $inGroup) {
/* Redirect to login view */
$result = array(null,
array('redirect' => $gallery->getConfig('loginRedirect')));
}
}
}
return $result;
}
}
?>
while (isset($data['arg' . $i])) {
$args[] = $data['arg' . $i];
$i++;
/* Catch runaways */
if ($i > 100) {
return array(GalleryCoreApi::error(ERROR_UNKNOWN), null);
}
}
/* If we have arguments, then feed the localized string and the arguments into sprintf */
if (count($args) > 0) {
$localized = vsprintf($localized, $args);
}
/*
* This is a useful debug routine. Uncomment it to have every string prefixed with the
* domain it was localized in.
*/
// $localized = "$domain/{$this->_languageCode}:$localized";
return array(null, $localized);
}
/**
* Convert the locale to the language code
* @param string $locale The locale code to be converted (i.e. en_US, en_GB, etc.)
* @return array GalleryStatus a status code
* string language code (i.e. en, en_GB, etc.)
*/
function getLanguageCodeFromLocale($locale) {
list ($language, $country) = explode('_', $locale . '_' );
/* Don't apply default to Chinese for political correctness */
if ($language == 'zh') {
return array(null, $locale);
}
list ($value, $defaultCountries) = $this->getLanguageData();
if (!isset($defaultCountries[$language])) {
return array(GalleryCoreApi::error(ERROR_BAD_PARAMETER, __FILE__, __LINE__,
"No default country defined for \"$locale\"."), null);
}
return array(null, ($country == $defaultCountries[$language]) ? $language : $locale);
}
/**
* Determine the language and country given the language code (i.e. en, en_GB)
* @param string $langCode The language code to be converted.
* @return array GalleryStatus a status code
* string language
* string country
*/
function getLanguageAndCountryFromLanguageCode($langCode) {
list ($language, $country) = explode('_', $langCode . '_');
if (empty($country)) {
list ($value, $defaultCountries) = $this->getLanguageData();
if (!isset($defaultCountries[$language])) {
return array(GalleryCoreApi::error(ERROR_BAD_PARAMETER, __FILE__, __LINE__,
"No default country defined for \"$langCode\"."), null, null);
}
$country = $defaultCountries[$language];
}
return array(null, $language, $country);
}
}
?>
oad it every single time.
*
* @see GalleryModule::install
*/
function upgrade($currentVersion, $statusMonitor) {
GalleryCoreApi::requireOnce('modules/core/CoreModuleExtras.inc');
$ret = CoreModuleExtras::upgrade($this, $currentVersion, $statusMonitor);
if ($ret) {
return $ret;
}
return null;
}
/**
* Set the current version of Gallery.
*/
function setGalleryVersion($version) {
$this->_galleryVersion = $version;
}
/**
* Get the current version of Gallery.
*/
function getGalleryVersion() {
return $this->_galleryVersion;
}
/**
* Get the version of the core module and of Gallery itself. We store this on disk to avoid
* having to load up the database (which can be problematic if we're doing an upgrade and don't
* want to count a specific database schema). If the versions.dat file indicates that Gallery
* is in maintenance mode, then set the configuration value to indicate this.
*
* @return array 'core' => core module version, 'gallery' => gallery version
* @static
*/
function getInstalledVersions() {
global $gallery;
if (GalleryDataCache::containsKey('CoreModule::installedVersions')) {
$versions = GalleryDataCache::get('CoreModule::installedVersions');
} else {
$platform =& $gallery->getPlatform();
$versionFile = $gallery->getConfig('data.gallery.version');
if ($platform->file_exists($versionFile)) {
$versionArray = $platform->file($versionFile);
if (count($versionArray) >= 2) {
$versions['core'] = rtrim($versionArray[0]);
$versions['gallery'] = rtrim($versionArray[1]);
GalleryDataCache::put('CoreModule::installedVersions', $versions, true);
if (isset($versionArray[2])) {
$maintenanceMode = explode(':', rtrim($versionArray[2]), 2);
if ($maintenanceMode[0] == 'maintenance-mode') {
$newMode = empty($maintenanceMode[1]) ? true : $maintenanceMode[1];
$gallery->setConfig('mode.maintenance', $newMode);
}
}
}
} else {
/*
* If we get here we are probably doing a fresh install so just return 0, 0 and
* the rest of the install should work properly.
*/
$versions = array('core' => 0, 'gallery' => 0);
}
}
return $versions;
}
/**
* @see GalleryModule::performFactoryRegistrations
*/
function performFactoryRegistrations() {
GalleryCoreApi::requireOnce('modules/core/CoreModuleExtras.inc');
$ret = CoreModuleExtras::performFactoryRegistrations($this);
if ($ret) {
return $ret;
}
return null;
}
}
?>
* @return string
*/
function getType() {
return 'mysql';
}
/**
* @see GalleryStorage::_setConnectionSettings
*/
function _setConnectionSettings(&$db) {
/* MySQL 4.1.0+ support UTF-8, for details, see: http://drupal.org/node/40515 */
$this->_serverInfo = ($this->_type == 'mysqli')
? mysqli_get_server_info($db->_connectionID) : mysql_get_server_info();
if ($this->_serverInfo && version_compare($this->_serverInfo, '4.1.0', '>=')) {
$this->_traceStart();
$recordSet = $db->execute('SET NAMES "utf8"');
$this->_traceStop();
if (!$recordSet) {
return GalleryCoreApi::error(ERROR_STORAGE_FAILURE);
}
}
return null;
}
/**
* @see GalleryStorage::_getSqlReplacements
*/
function _getSqlReplacements() {
/* 3.23.0-4.0.17 used TYPE, 5.1+ only accepts ENGINE, between accepts either */
$typeKeyword = ($this->_serverInfo && version_compare($this->_serverInfo, '4.0.18', '>='))
? 'ENGINE' : 'TYPE';
/* Use InnoDB for transactional tables */
$tableType = $this->_isTransactional ? 'InnoDB' : 'MyISAM';
/**
* @todo On next major bump of Module API, remove 'TYPE=DB_TABLE_TYPE' entry below.
* In revision 14158, we switched from replacing DB_TABLE_TYPE with the tableType to
* replacing it with {ENGINE|TYPE}=tableType. Handle both cases else installing older
* modules will fail.
*/
return array('TYPE=DB_TABLE_TYPE' => $typeKeyword . '=' . $tableType,
'DB_TABLE_TYPE' => $typeKeyword . '=' . $tableType);
}
/**
* @see GalleryStorage::getFunctionsSql
*/
function getFunctionSql($functionName, $args) {
switch($functionName) {
case 'CONCAT':
$sql = sprintf('CONCAT(%s)', implode(', ', $args));
break;
case 'BITAND':
$sql = $args[0] . ' & ' . $args[1];
break;
case 'BIT_OR':
$sql = 'BIT_OR(' . $args[0] . ')';
break;
case 'UNIX_TIMESTAMP':
$sql = sprintf('UNIX_TIMESTAMP(%s)', $args[0]);
break;
case 'AS':
$sql = 'AS';
break;
case 'SUBSTRING':
$sql = sprintf('SUBSTRING(%s)', implode(', ', $args));
break;
case 'RAND':
$sql = sprintf('RAND(%s)', empty($args) ? '' : $args[0]);
break;
case 'RANDOM_INTEGER':
$sql = 'FLOOR(RAND() * 2147483647)';
break;
case 'LIMIT':
$sql = $args[1] . ' LIMIT ' . $args[0];
break;
case 'CASE': // condition value (condition value)* else-value
if (count($args) == 3) {
$sql = sprintf('IF(%s)', implode(', ', $args));
} else {
$sql = array();
while (count($args) > 1) {
$sql[] = 'WHEN ' . array_shift($args) . ' THEN ' . array_shift($args);
}
$sql = 'CASE ' . implode(' ', $sql) . ' ELSE ' . $args[0] . ' END';
}
break;
case 'LIKE':
$sql = $args[0] . ' LIKE ' . $args[1];
break;
case 'MULTI_INSERT':
/*
* 0 - table name
* 1 - array of column names
* 2 - number of rows
*/
$markers = GalleryUtilities::makeMarkers(sizeof($args[1]));
$rowList = rtrim(str_repeat('(' . $markers . '), ', $args[2]), ', ');
$sql = 'INSERT INTO ' . $args[0] . ' (';
$sql .= join(', ', $args[1]);
$sql .= ') VALUES ' . $rowList;
break;
case 'AVG':
$sql = sprintf('AVG(%s)', $args[0]);
break;
default:
return array(GalleryCoreApi::error(ERROR_UNIMPLEMENTED, __FILE__, __LINE__,
$functionName . ' ' . implode(' ', $args)), null);
}
return array(null, $sql);
}
/**
* @see GalleryStorage::encodeBlob
*/
function encodeBlob($blob) {
if (!isset($this->_db)) {
list ($ret, $this->_db) = $this->_getConnection();
}
if ($this->_serverInfo && version_compare($this->_serverInfo, '4.1.0', '>=')) {
/* See: http://www.postgresql.org/docs/8.1/interactive/datatype-binary.html */
$blob = addcslashes($blob, "\000..\037\047\134\177..\377");
}
return $blob;
}
/**
* @see GalleryStorage::decodeBlob
*/
function decodeBlob($blob) {
if (!isset($this->_db)) {
list ($ret, $this->_db) = $this->_getConnection();
}
if ($this->_serverInfo && version_compare($this->_serverInfo, '4.1.0', '>=')) {
$blob = stripcslashes($blob);
}
return $blob;
}
/**
* Get database version.
* @return string version
*/
function getVersion() {
if (!isset($this->_db)) {
list ($ret, $this->_db) = $this->_getConnection();
if ($ret) {
return ($this->_type == 'mysqli'
? mysqli_get_client_info() : mysql_get_client_info()) . ' client';
}
}
return $this->_serverInfo;
}
/**
* @see GalleryStorage::_getOptimizeStatements
*/
function _getOptimizeStatements() {
return array('OPTIMIZE TABLE `%s`;', 'ANALYZE TABLE `%s`;');
}
/**
* @see GalleryStorage::getUniqueId
*/
function getUniqueId($sequence=DATABASE_SEQUENCE_ID) {
/* Make sure we're using a non-transactional connection to avoid duplicating sequence ids */
$extras =& $this->_getExtras();
list ($ret, $db) = $extras->_getNonTransactionalDatabaseConnection();
if ($ret) {
return array($ret, null);
}
return $extras->_getUniqueIdWithConnection($db, $sequence);
}
/**
* Truncate UTF-8 strings either to given character or to byte length depending on the MySQL
* version.
* @see GalleryStorage::_truncateString
*/
function _truncateString($value, $size, $lengthInBytes=false) {
static $lengthInBytes;
if (!isset($lengthInBytes)) {
$lengthInBytes =
$this->_serverInfo && version_compare($this->_serverInfo, '4.1.0', '<');
}
return parent::_truncateString($value, $size, $lengthInBytes);
}
}
?>
tity type [%s].', $entity->getId(), $entity->getEntityType(),
implode(', ', $requiredEntityType));
return array(GalleryCoreApi::error(ERROR_MISSING_OBJECT, __FILE__, __LINE__,
$errorMessage),
null);
}
}
}
if (!$returnArray) {
$results = $results[0];
}
return array(null, $results);
}
/**
* @see GalleryCoreApi::loadEntityByExternalId
*/
function loadEntityByExternalId($externalId, $entityType) {
global $gallery;
list ($ret, $results) = GalleryCoreApi::getMapEntry('ExternalIdMap',
array('entityId'), array('externalId' => $externalId, 'entityType' => $entityType));
if ($ret) {
return array($ret, null);
}
if (!($result = $results->nextResult())) {
return array(GalleryCoreApi::error(ERROR_MISSING_OBJECT, __FILE__, __LINE__,
"$externalId $entityType"), null);
}
list ($ret, $entity) =
GalleryEntityHelper_simple::loadEntitiesById($result[0], $entityType);
if ($ret) {
return array($ret, null);
}
return array(null, $entity);
}
}
?>
l() {
return $this->email;
}
function setEmail($email) {
$this->email = $email;
}
function getLanguage() {
return $this->language;
}
function setLanguage($language) {
$this->language = $language;
}
function isLocked() {
return (bool)$this->locked;
}
function setLocked($lock) {
$this->locked = (bool)$lock;
}
}
?>
l/en/template.resources.php
*
* This is basically the same as the file: resource except that we look for templates based on
* the search algorithm used by the _getActualTemplatePath method. This allows users and
* theme developers to override templates with our own copies without modifying the original.
*
* @see function _getActualTemplatePath
*/
function resourceGetTemplate($templateName, &$templateSource, &$smarty) {
$templatePath = GalleryTemplate::_getActualTemplatePath($templateName, $smarty);
$success = false;
if (isset($templatePath)) {
$templateSource = $smarty->_read_file($templatePath);
if ($templateSource !== false) {
$success = true;
} else {
$smarty->trigger_error("The template '$templateName' does not exist.",
GALLERY_ERROR);
}
}
return $success;
}
/**
* @see http://smarty.php.net/manual/en/template.resources.php
*
* This is basically the same as the file: resource except that we look for templates based on
* the search algorithm used by the _getActualTemplatePath method. This allows users and theme
* developers to override templates with our own copies without modifying the original.
*
* @see function _getActualTemplatePath
*/
function resourceGetTimestamp($templateName, &$templateTimestamp, &$smarty) {
global $gallery;
$platform =& $gallery->getPlatform();
$success = false;
$templatePath = GalleryTemplate::_getActualTemplatePath($templateName, $smarty);
if (isset($templatePath) && $platform->file_exists($templatePath)) {
$stat = $platform->stat($templatePath);
$templateTimestamp = $stat[9];
$success = true;
}
return $success;
}
/**
* Given a template name (foo/bar/path/file.tpl), return the active template path based on the
* following:
* if (module bar): /fullpath/themes/themeId/templates/bar_templateversion/path/local/file.tpl
* if (module bar): /fullpath/themes/themeId/templates/bar_templateversion/path/file.tpl
* /fullpath/foo/bar/path/local/file.tpl
* /fullpath/foo/bar/path/file.tpl
*
* @param string $templateName base template name
* @param Smarty $smarty
* @return string path to the current active template file for the specified template name
* @static
* @access private
*/
function _getActualTemplatePath($templateName, &$smarty) {
global $gallery;
$platform =& $gallery->getPlatform();
/* Check template override */
if (preg_match('#^modules/(\w+)/templates/(.*/)?([^/]+)$#', $templateName, $match)) {
list ($unused, $moduleId, $moduleBase, $tplFile) = $match;
$theme = $smarty->get_template_vars("theme");
if (empty($theme['themeId'])) {
list ($ret, $themeId) = GalleryTemplate::_getThemeId();
if ($ret) {
/** @todo Log this as soon as we have an event log */
$gallery->debug('_getThemeId failed with the following error: '
. $ret->getAsHtml());
}
} else {
$themeId = $theme['themeId'];
}
if (!empty($themeId)) {
list ($ret, $module) = GalleryCoreApi::loadPlugin('module', $moduleId);
if (!$ret) {
$tplVersion = $module->getTemplateVersion();
$themeOverrideDir =
"{$smarty->template_dir}/themes/$themeId/templates/{$moduleId}_$tplVersion";
/* Check local module template override */
$file = "$themeOverrideDir/{$moduleBase}local/$tplFile";
if ($platform->is_readable($file)) {
$qualifiedTemplatePath = $file;
} else {
/* Check module template override through theme */
$file = "$themeOverrideDir/{$moduleBase}$tplFile";
if ($platform->is_readable($file)) {
$qualifiedTemplatePath = $file;
}
}
} else {
/** @todo Log this as soon as we have an event log */
$gallery->debug('loadPlugin failed with the following error: '
. $ret->getAsHtml());
}
}
}
if (empty($qualifiedTemplatePath)) {
$tplFile = basename($templateName);
$qualifiedTemplateName = $smarty->template_dir . '/' . $templateName;
$base = dirname($qualifiedTemplateName);
$file = "$base/local/$tplFile";
if ($platform->is_readable($file)) {
$qualifiedTemplatePath = $file;
} else {
/* Use whatever was passed. Use the smarty default as the directory base */
$qualifiedTemplatePath = $qualifiedTemplateName;
}
}
return $qualifiedTemplatePath;
}
/**
* Return the themeid for the current item.
* @return array GalleryStatus a status code
* string ThemeId
* @static
* @access private
*/
function _getThemeId() {
$view = new GalleryView();
list ($ret, $itemId) = $view->getItem();
if ($ret) {
/*
* Missing object / permission denied errors are handled elsewhere.
* At this point we want to keep things going to render a page.
*/
if ($ret->getErrorCode() & (ERROR_MISSING_OBJECT | ERROR_PERMISSION_DENIED)) {
$itemId = null;
} else {
return array($ret, null);
}
}
list ($ret, $theme) = $view->loadThemeForItem($itemId);
if (!$ret && isset($theme)) {
$themeId = $theme->getId();
} else {
if (!isset($theme) || $ret->getErrorCode() &
(ERROR_BAD_PARAMETER | ERROR_BAD_PLUGIN | ERROR_PLUGIN_VERSION_MISMATCH)) {
/*
* See bug 2032636.
* We just need some default theme id in this context.
* GalleryView::doLoadTemplate handles theme errors.
*/
list ($ret, $themeId) =
GalleryCoreApi::getPluginParameter('module', 'core', 'default.theme');
if ($ret) {
return array($ret, null);
}
} else {
return array($ret, null);
}
}
return array(null, $themeId);
}
/**
* @see http://smarty.php.net/manual/en/template.resources.php
*/
function resourceGetSecure($templateName, &$smarty) {
/* Assume all templates are secure */
return true;
}
/**
* @see http://smarty.php.net/manual/en/template.resources.php
*/
function resourceGetTrusted($templateName, &$smarty) {
/* Not used for templates */
}
}
?>
$status) = GalleryCoreApi::fetchPluginStatus('module');
if ($ret) {
/* What can we do with this error? */
$gallery->debug("Error performing $params[type] callback");
$gallery->debug($ret->getAsHtml());
}
}
list ($module, $file) = explode('.', $params['type']);
if (!empty($status[$module]['active'])) {
GalleryCoreApi::requireOnce("modules/$module/Callbacks.inc");
$userId = $smarty->_tpl_vars['theme']['actingUserId'];
$className = "${module}Callbacks";
$class = new $className;
$ret = $class->callback($params, $smarty, $file, $userId);
if ($ret) {
/* What can we do with this error? */
$gallery->debug("Error performing $params[type] callback");
$gallery->debug($ret->getAsHtml());
}
}
}
/**
* Add the content to our trailer block
*
* @param array $params
* @param string $content
* @param Smarty $smarty the smarty instance
*/
function addToTrailer($params, $content, &$smarty) {
if (!isset($content)) {
return;
}
$this->_trailer .= $content;
}
/**
* Register a callback function to be executed when we run the trailer.
*
* @param callback $callback suitable to be used as an input for call_user_func()
* @param array $args for callback
*/
function registerTrailerCallback($callback, $args) {
$this->_trailerCallbacks[] = array('function' => $callback, 'args' => $args);
}
/**
* Render trailer output
*/
function trailer($params, &$smarty) {
print $this->_trailer;
foreach ($this->_trailerCallbacks as $callback) {
$ret = call_user_func_array($callback['function'], $callback['args']);
if (is_array($ret)) {
$ret = $ret[0];
}
if ($ret) {
/* If progress bar is in use, report error via its interface */
global $gallery;
if ($gallery->getCurrentView() == 'core.ProgressBar') {
$this->errorProgressBar($ret);
} else {
$summary = $ret->getErrorMessage();
if (empty($summary)) {
$summary = implode(', ', $ret->getErrorCodeConstants($ret->getErrorCode()));
}
GalleryCoreApi::addEventLogEntry('Gallery Error', $summary, $ret->getAsText());
}
}
}
}
/**
* Use GalleryUtilities::shrinkDimensionsToFit to scale template vars to new target size.
*
* @param array $params args; should contain widthVar, heightVar, maxSize keys
* @param Smarty $smarty the smarty instance
*/
function shrinkDimensions($params, &$smarty) {
if (!isset($params['widthVar']) || !isset($params['heightVar']) ||
!isset($params['maxSize'])) {
return;
}
$widthVar = $params['widthVar'];
$heightVar = $params['heightVar'];
if (!isset($smarty->_tpl_vars[$widthVar]) || !isset($smarty->_tpl_vars[$heightVar])) {
return;
}
list ($smarty->_tpl_vars[$widthVar], $smarty->_tpl_vars[$heightVar]) =
GalleryUtilities::shrinkDimensionsToFit(
$smarty->_tpl_vars[$widthVar], $smarty->_tpl_vars[$heightVar], $params['maxSize']);
}
/**
* Update progress bar
* @param string $title top heading
* @param string $description subheading
* @param float $percentComplete from 0 to 1
*/
function updateProgressBar($title, $description, $percentComplete) {
static $coreModule;
if (!isset($coreModule)) {
list ($ret, $coreModule) = GalleryCoreApi::loadPlugin('module', 'core');
if ($ret) {
/*
* Unlikely this will ever be used.. but do update it if exact form of
* translate() calls (with text+arg1+arg2) in this function ever change.
*/
eval('class GalleryTemplateAdapterFallbackCoreModule {
function translate($x) {
return sprintf($x[\'text\'], $x[\'arg1\'], $x[\'arg2\']);
}
}');
$coreModule = new GalleryTemplateAdapterFallbackCoreModule();
}
}
if (empty($this->_progressBarStats)) {
$this->_progressBarStats['startTime'] = time();
}
/*
* Calculate the time remaining
*
* TODO: Use a weighted measurement to provide a balanced estimate. Consider the case
* where the first 50% goes really quickly and the second 50% goes really slowly; the
* estimate will be wildly inaccurate at the transition.
*/
if ($percentComplete > 0 &&
$percentComplete < 1 && time() > $this->_progressBarStats['startTime']) {
$elapsed = (int)(time() - $this->_progressBarStats['startTime']);
$timeRemaining = ($elapsed / $percentComplete) - $elapsed;
$timeRemaining = $coreModule->translate(
array('text' => 'Estimated time remaining: %d:%02d',
'arg1' => (int)($timeRemaining / 60),
'arg2' => $timeRemaining % 60));
} else {
$timeRemaining = '';
}
/* it is possible to not have this function compiled into php */
$memoryUsed = (function_exists('memory_get_usage')) ? memory_get_usage() : 0;
/* A disabled memory_limit is -1, 0 crashes php */
$memoryTotal = (0 < ini_get('memory_limit')) ? ini_get('memory_limit') : 0;
/*
* Ensure that percentComplete is in a dotted-decimal format. Since the immediateView
* is dealing in percentages, anything beyond two decimal places is unnecessary.
*/
$percentComplete = GalleryUtilities::roundToString($percentComplete, 2);
/* Need to escape for javascript (backslash, ..) */
if (!function_exists('smarty_modifier_escape')) {
GalleryCoreApi::requireOnce('lib/smarty/plugins/modifier.escape.php');
}
$title = smarty_modifier_escape($title, 'javascript');
$description = smarty_modifier_escape($description, 'javascript', 'UTF-8');
$memoryInfo = $coreModule->translate(
array('text' => 'Memory used: %s, total: %s',
'arg1' => $memoryUsed,
'arg2' => $memoryTotal));
/* Newline needed or Opera 9.02 won't show updates */
printf('%s',
$title, $description, $percentComplete, $timeRemaining, $memoryInfo, "\n");
flush();
}
/**
* Reset progress bar timing stats.
*/
function resetProgressBarStats() {
$this->_progressBarStats = array();
}
/**
* Display error progress bar.
* @param GalleryStatus $status
*/
function errorProgressBar($status) {
global $gallery;
list ($ret, $isAdmin) = GalleryCoreApi::isUserInSiteAdminGroup();
if ($ret) {
$isAdmin = false;
}
/* Log the error */
$summary = $status->getErrorMessage();
if (empty($summary)) {
$summary = implode(', ', $status->getErrorCodeConstants($status->getErrorCode()));
}
GalleryCoreApi::addEventLogEntry('Gallery Error', $summary, $status->getAsText());
/* Display an error message */
if ($gallery->getDebug() || $isAdmin) {
$status = $status->getAsHtml($isAdmin);
} else {
$status = 'Error ('
. implode(', ', $status->getErrorCodeConstants($status->getErrorCode())) . ')';
}
if (!function_exists('smarty_modifier_escape')) {
GalleryCoreApi::requireOnce('lib/smarty/plugins/modifier.escape.php');
}
$status = smarty_modifier_escape($status, 'javascript', 'UTF-8');
printf('', $status);
}
/**
* Complete progress bar.
* @param string $continueUrl URL shown to continue the process
* @param bool $doRedirect Whether to redirect automatically. Defaults to false, requiring
* user-interaction to follow the continue link.
*/
function completeProgressBar($continueUrl, $doRedirect=false) {
global $gallery;
$continueUrl = str_replace('&', '&', $continueUrl);
/* Display the continue link after a short delay to avoid bug 2031942 */
printf('',
$continueUrl);
if (($debug = $gallery->getDebug()) && $debug != 'logged') {
/* Don't automatically redirect when in debug mode */
print '
';
print '
';
print $gallery->getDebugBuffer();
print '
';
} else if ($doRedirect) {
/*
* Redirect after a short delay giving the server time to store the session before
* the next page is requested.
*/
printf('', $continueUrl);
}
}
}
?>
eKey =
"GalleryPermissionHelper::getPermissions($itemId,$userId,$sessionPermissions)";
if (GalleryDataCache::containsKey($cacheKey)) {
$permissions = GalleryDataCache::get($cacheKey);
} else {
list ($ret, $permissionsTable) = GalleryCoreApi::fetchPermissionsForItems(
array($itemId), $userId, $sessionPermissions);
if ($ret) {
return array($ret, null);
}
if (isset($permissionsTable[$itemId])) {
$permissions = $permissionsTable[$itemId];
} else {
$permissions = array();
/* fetchPermissionsForItems already caches all hits, cache misses here too. */
GalleryDataCache::put($cacheKey, array());
}
}
return array(null, $permissions);
}
/**
* @see GalleryCoreApi::addPermissionToSession
*/
function addPermissionToSession($entityId) {
global $gallery;
$session =& $gallery->getSession();
if (!$session->exists(GALLERY_PERMISSION_SESSION_KEY)) {
$session->put(GALLERY_PERMISSION_SESSION_KEY, array());
}
$sessionPerms =& $session->get(GALLERY_PERMISSION_SESSION_KEY);
if (!in_array($entityId, $sessionPerms)) {
$sessionPerms[] = (int)$entityId;
}
}
}
?>
ult[0]] = array();
}
return array(null, $tree);
}
}
?>
s.
*
* @param string $mainHtml the main html (, , etc)
* @param array $extraHtml any extra html that we've generated, like sidebar HTML
* @return array('headHtml' => ..., 'bodyHtml' => ...)
*/
function splitHtml($mainHtml, $extraHtml) {
/*
* Avoid regular expressions on very large strings due to PHP's pcre.backtrack_limit.
* It's faster (no excessive backtracking) and actually required due to PHP 5.2.0's
* pcre.backtrack_limit which is reached with large pages like AdminPlugins.
*/
$results = array();
if (($headStart = strpos($mainHtml, '')) !== false) {
if (($headEnd = strpos($mainHtml, '', $headStart)) !== false) {
$headStart += strlen('');
$results['headHtml'] = substr($mainHtml, $headStart, $headEnd - $headStart);
if (($bodyStart = strpos($mainHtml, '', $bodyStart)) !== false) {
if (($bodyEnd = strpos($mainHtml, '', $bodyStart)) !== false) {
$results['bodyHtml'] =
substr($mainHtml, ++$bodyStart, $bodyEnd - $bodyStart);
$mainHtml = null;
}
}
}
}
}
if (empty($results['bodyHtml'])) {
$results = array('bodyHtml' => $mainHtml);
}
/* If we extracted the sidebar, it'll be in our extra html, so move that over */
if (isset($extraHtml['sidebarBlocksHtml'])) {
$results['sidebarBlocksHtml'] = $extraHtml['sidebarBlocksHtml'];
}
return $results;
}
/**
* @see GalleryPlugin::getPluginType
*/
function getPluginType() {
return 'theme';
}
function setRequiredThemeApi($requirement) {
$this->_requiredThemeApi = $requirement;
}
function getRequiredThemeApi() {
return $this->_requiredThemeApi;
}
function setStandardSettings($standardSettings) {
$this->_standardSettings = $standardSettings;
}
function getStandardSettings() {
return $this->_standardSettings;
}
}
?>
column)) {
$order[] = $column . $direction;
$select[] = $column;
}
}
return array(null, $select, $join, $condition, $order);
}
}
?>
rray(null, $derivativeTable);
}
}
?>
}
/**
* Static array of registered event listeners.
* @return array
* @access private
* @todo Remove on next major API bump
*/
function &_getEventListeners() {
static $allListeners = array();
return $allListeners;
}
/**
* @see GalleryCoreApi::registerEventListener
* @todo Remove on next major API bump
*/
function registerEventListener($eventName, &$eventListener, $disableForTests=false) {
if ($disableForTests && class_exists('GalleryTestCase')) {
return;
}
$allListeners =& GalleryEventHelper_simple::_getEventListeners();
$allListeners[$eventName][] =& $eventListener;
}
}
?>
}
}
return array(null, null);
}
}
?>
', 'lastAttempt'),
array('userName' => $userName));
if ($ret) {
return array($ret, null);
}
if ($searchResults->resultCount() == 0) {
$count = 0;
$lastAttempt = 0;
} else {
$result = $searchResults->nextResult();
$count = $result[0];
$lastAttempt = $result[1];
}
return array(null, GalleryUserHelper_medium::_isDisabled($count, $lastAttempt));
}
/**
* Return true if the failure count and last attempt are over our
* threshold. For every 10 failures, logins are disabled for 1 hour.
*
* @param int $count the number of consecutive failed logins
* @param int $lastAttempt the time of the last failed login attempt
* @return bool true if the account is disabled
* @access private
*/
function _isDisabled($count, $lastAttempt) {
global $gallery;
if ($count >= 10) {
$phpVm = $gallery->getPhpVm();
$hoursDisabled = ((int)$count / 10);
if (($phpVm->time() - $lastAttempt) < $hoursDisabled * 3600) {
return true;
}
}
return false;
}
}
?>
Exoplan Galerie Start - Projekt