= GalleryCoreApi::updateMapEntry('GalleryCacheMap', array('userId' => $userIdForSql, 'timestamp' => new GallerySqlFragment('< ?', (int)$cutoff), 'isEmpty' => 0), array('value' => null, 'isEmpty' => 1)); if ($ret) { return $ret; } return null; } } ?> */ 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; } } ?> . Try getting our active user from registered authentication plugins. If * not, make us the anonymous user. If we don't have a session, this will initiate one for us. */ list ($ret, $pluginIds) = GalleryCoreApi::getAllFactoryImplementationIds('GalleryAuthPlugin'); if ($ret) { return $ret; } foreach ($pluginIds as $pluginId => $className) { list ($ret, $plugin) = GalleryCoreApi::newFactoryInstanceById('GalleryAuthPlugin', $pluginId); if ($ret) { return $ret; } list ($ret, $user) = $plugin->getUser(); if ($ret) { return $ret; } if (isset($user)) { break; } } if (!isset($user)) { /* Missing user, be anonymous */ list ($ret, $userId) = GalleryCoreApi::getAnonymousUserId(); if ($ret) { return $ret; } list ($ret, $user) = GalleryCoreApi::loadEntitiesById($userId, 'GalleryUser'); if ($ret) { return $ret; } } $gallery->setActiveUser($user); return null; } /** * Interceptor for the standard PHP error handler. We log any errors in the database, then * proceed with the regular error handler. * @see http://www.php.net/manual/en/function.set-error-handler.php * * @param int $errorNumber the code for the error * @param string $errorString an error message * @param string $file the file where the error occurred * @param int $line the line number of the error * @param mixed $context the complete context at the time of the error * @return boolean true if we should skip the regular PHP error handler */ function GalleryPhpErrorHandler($errorNumber, $errorString, $file, $line, $context) { if (error_reporting() == 0) { /* The @ error suppression operator was used, so don't log this error. */ return false; } $errorType = array( E_ERROR => 'Error', E_WARNING => 'Warning', E_PARSE => 'Parsing Error', E_NOTICE => 'Notice', E_CORE_ERROR => 'Core Error', E_CORE_WARNING => 'Core Warning', E_COMPILE_ERROR => 'Compile Error', E_COMPILE_WARNING => 'Compile Warning', E_USER_ERROR => 'User Error', E_USER_WARNING => 'User Warning', E_USER_NOTICE => 'User Notice', /* PHP5+: E_STRICT => 'Runtime Notice' */ /* PHP5.2+: E_RECOVERABLE_ERROR => 'Catchable Fatal Error' */ ); GalleryCoreApi::addEventLogEntry( 'PHP Error', sprintf("[%s] %s in file %s on line %d", $errorType[$errorNumber], $errorString, $file, $line), $errorString); /* Fall back to the internal error handler */ return false; } ?> class name * @param boolean $tryAllModules true if we should scan all modules, not just the active ones * @return array GalleryStatus a status code * entity associative array */ function describeEntity($entityName, $tryAllModules=false) { global $gallery; $storage =& $gallery->getStorage(); list ($ret, $entityInfo) = $storage->describeEntity($entityName, $tryAllModules); if ($ret) { return array($ret, null); } return array(null, $entityInfo); } /** * Delete the fast download file for a specific entity * * @param int $entityId */ function deleteFastDownloadFileById($entityId) { GalleryCoreApi::requireOnce( 'modules/core/classes/helpers/GalleryEntityHelper_medium.class'); return GalleryEntityHelper_medium::deleteFastDownloadFileById($entityId); } /** * Create a small PHP file containing all the information we need to send a data item or * derivative to the browser. * Note that fast-downloads are only created for items with public permissions * * @param object $entity GalleryDataItem or GalleryDerivative object * @param bool $runEvenInUnitTest (optional) force this to run, even in the unit test framework * @return GalleryStatus a status code */ function createFastDownloadFile($entity, $runEvenInUnitTest=false) { GalleryCoreApi::requireOnce( 'modules/core/classes/helpers/GalleryEntityHelper_medium.class'); return GalleryEntityHelper_medium::createFastDownloadFile($entity, $runEvenInUnitTest); } /** * Get id of the album to display by default. * @return array GalleryStatus a status code * int album id */ function getDefaultAlbumId() { global $gallery; $defaultId = $gallery->getConfig('defaultAlbumId'); if (empty($defaultId)) { list ($ret, $defaultId) = GalleryCoreApi::getPluginParameter( 'module', 'core', 'id.rootAlbum'); if ($ret) { return array($ret, null); } } return array(null, (int)$defaultId); } /** * Get id of the guest user. * * @return array GalleryStatus a status code * int user id */ function getAnonymousUserId() { global $gallery; $id = $gallery->getConfig('anonymousUserId'); if (empty($id)) { list ($ret, $id) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.anonymousUser'); if ($ret) { return array($ret, null); } } return array(null, $id); } /** * Is the user a guest? * * @param int $userId id of user (default is current user) * @return array GalleryStatus a status code * boolean true if anonymous */ function isAnonymousUser($userId=null) { if (empty($userId)) { global $gallery; $userId = $gallery->getActiveUserId(); } list ($ret, $anonymousId) = GalleryCoreApi::getAnonymousUserId(); if ($ret) { return array($ret, null); } return array(null, $userId == $anonymousId); } /** * Remove the given sort order from any thing in the framework that uses it * (albums and the default sort order). * * @param string $sortOrder * @return GalleryStatus a status code */ function deleteSortOrder($sortOrder) { GalleryCoreApi::requireOnce( 'modules/core/classes/helpers/GalleryItemHelper_advanced.class'); return GalleryItemHelper_advanced::deleteSortOrder($sortOrder); } /** * Remove the given renderer from all items that are using it. * * @param string $rendererClassName * @return GalleryStatus a status code */ function deleteRenderer($rendererClassName) { GalleryCoreApi::requireOnce( 'modules/core/classes/helpers/GalleryItemHelper_advanced.class'); return GalleryItemHelper_advanced::deleteRenderer($rendererClassName); } /** * Load template data for a theme settings form * * @param string $themeId if empty, site default theme is used * @param int $itemId * @param GalleryTemplate $template * @param array $form * @return GalleryStatus a status code */ function loadThemeSettingsForm($themeId, $itemId, &$template, &$form) { GalleryCoreApi::requireOnce('modules/core/classes/helpers/GalleryThemeHelper_medium.class'); return GalleryThemeHelper_medium::loadThemeSettingsForm( $themeId, $itemId, $template, $form); } /** * Load the block configuration files from every module * * @param bool $getInactive (optional) by default, only active modules' blocks are returned * @return array GalleryStatus a status code * array block configurations */ function loadAvailableBlocks($getInactive=false) { GalleryCoreApi::requireOnce('modules/core/classes/helpers/GalleryThemeHelper_medium.class'); return GalleryThemeHelper_medium::loadAvailableBlocks($getInactive); } /** * Handle theme settings form submission * * @param string $themeId if empty, site default theme is used * @param int $itemId * @param array $form form values * @return array GalleryStatus a status code * array error messages * string localized status message */ function handleThemeSettingsRequest($themeId, $itemId, $form) { GalleryCoreApi::requireOnce('modules/core/classes/helpers/GalleryThemeHelper_medium.class'); return GalleryThemeHelper_medium::handleThemeSettingsRequest($themeId, $itemId, $form); } /** * Return true if this username is not allowed to log in (generally due to automated abuse). * The username doesn't have to correspond to a real user in the system. * * @param string $userName a username * @return array GalleryStatus a status code * bool true if the account is disabled */ function isDisabledUsername($userName) { GalleryCoreApi::requireOnce('modules/core/classes/helpers/GalleryUserHelper_medium.class'); return GalleryUserHelper_medium::isDisabledUsername($userName); } /** * Get a list of entity members which are allowed to be shown / set by external systems (e.g. * via remote protocols like WebDAV, XML-RPC, etc). * This does not include any permission checking. * @param string $entityName name of the entity * @return array GalleryStatus a status code * array(string memberName => * array('read' => boolean true if it's ok to show, * 'write' => boolean true if it's ok to set)) */ function getExternalAccessMemberList($entityName) { GalleryCoreApi::requireOnce( 'modules/core/classes/helpers/GalleryEntityHelper_medium.class'); return GalleryEntityHelper_medium::getExternalAccessMemberList($entityName); } /** * Copy the translations for a given plugin into our locale hierarchy. * * @param string $pluginType 'module' or 'theme' * @param string $pluginId the id of the plugin * @return GalleryStatus a status code */ function installTranslationsForPlugin($pluginType, $pluginId) { GalleryCoreApi::requireOnce( 'modules/core/classes/helpers/GalleryTranslatorHelper_medium.class'); return GalleryTranslatorHelper_medium::installTranslationsForPlugin($pluginType, $pluginId); } /** * Remove the translations for a given plugin from our locale hierarchy. * * @param string $pluginType 'module' or 'theme' * @param string $pluginId the id of the plugin * @return GalleryStatus a status code */ function removeTranslationsForPlugin($pluginType, $pluginId) { GalleryCoreApi::requireOnce( 'modules/core/classes/helpers/GalleryTranslatorHelper_medium.class'); return GalleryTranslatorHelper_medium::removeTranslationsForPlugin($pluginType, $pluginId); } /** * Copy the translations for a given locale into our locale hierarchy. * Copies for all available (even uninstalled) plugins. * @param string $locale (optional) Defaults to translator's current locale * @return GalleryStatus a status code */ function installTranslationsForLocale($locale=null) { GalleryCoreApi::requireOnce( 'modules/core/classes/helpers/GalleryTranslatorHelper_medium.class'); return GalleryTranslatorHelper_medium::installTranslationsForLocale($locale); } /** * Return the list of languages that we support. * @return array['language code']['country code'] = * array('description', 'right-to-left'?) */ function getSupportedLanguages() { GalleryCoreApi::requireOnce( 'modules/core/classes/helpers/GalleryTranslatorHelper_medium.class'); return GalleryTranslatorHelper_medium::getSupportedLanguages(); } /** * Returns the language description of the specified language-country code. * eg. en_US => English (US) * * @param string $languageCode * @return array GalleryStatus a status code * string language description */ function getLanguageDescription($languageCode) { GalleryCoreApi::requireOnce( 'modules/core/classes/helpers/GalleryTranslatorHelper_medium.class'); return GalleryTranslatorHelper_medium::getLanguageDescription($languageCode); } /** * Get the local path to the Gallery code base path (not URL or web root). Optionally append a * relative path. * @param string $relativePath (optional) Relative path to append to the code base path. * @return string local path to the Gallery code base. If the optional parameter has not been * supplied the return value will have the trailing slash appended. */ function getCodeBasePath($relativePath=null) { static $codeBaseDirectory; if (!isset($codeBaseDirectory)) { $codeBaseDirectory = dirname(dirname(dirname(dirname(__FILE__)))) . DIRECTORY_SEPARATOR; } return ($relativePath == null) ? $codeBaseDirectory : $codeBaseDirectory . $relativePath; } /** * Check whether modification checks should be done to see if the compiled templates * are still up to date. The result is cached in memory. * @return boolean false if the compiled templates should be used without any checking */ function shouldDoCompileCheck() { GalleryCoreApi::requireOnce('modules/core/classes/GalleryTemplate.class'); return GalleryTemplate::shouldDoCompileCheck(); } /** * Allows the application to programmatically set Gallery into or out of maintenance mode. * @param mixed $mode This can either be a boolean flag or a string representing the url of the * custom maintenance mode page. * @return GalleryStatus a status code */ function setMaintenanceMode($mode) { GalleryCoreApi::requireOnce('modules/core/classes/helpers/MaintenanceHelper_simple.class'); return MaintenanceHelper_simple::setMaintenanceMode($mode); } /** * Store a value in the event log. * @param string $type a short string with the type of event * (e.g.: 'Gallery Error', 'PHP Error', 'comment module') * @param string $summary a brief summary of the event * @param string $detail the event details * @return GalleryStatus a status code */ function addEventLogEntry($type, $summary, $details) { GalleryCoreApi::requireOnce( 'modules/core/classes/helpers/GalleryEventLogHelper_medium.class'); return GalleryEventLogHelper_medium::addEventLogEntry($type, $summary, $details); } } ?> * **************************************** * Export / Import Schema Version Number * **************************************** */ /** * Current Schema Version */ define('EXPORT_SCHEMA_VERSION', '1.1'); ?> leryView::_loadTheme($themeId); if ($ret) { return array($ret, null, null); } } return array(null, $theme, $params); } /** * Let non-core code override the theme and its parameters for this request. * * @param GalleryItem $item The item defining the context of the request. * @return array GalleryStatus A status code, * GalleryTheme|null The theme to be used for this request, * array Theme parameters, see GalleryTheme::fetchParameters() * @access private */ function _getThemeAndParametersByEvent($item) { global $gallery; $event = GalleryCoreApi::newEvent('Gallery::LoadThemeAndParameters'); $event->setEntity($item); $event->setData(array('viewType' => $this->getViewType(), 'viewName' => $gallery->getCurrentView())); list ($ret, $eventResults) = GalleryCoreApi::postEvent($event); if ($ret) { return array($ret, null, null); } $themeId = $theme = $params = null; foreach ($eventResults as $eventResult) { if (!empty($eventResult['themeId'])) { $themeId = $eventResult['themeId']; if (!empty($eventResult['params'])) { $params = $eventResult['params']; } break; } } if (!empty($themeId)) { list ($ret, $theme) = $this->_loadTheme($themeId); if ($ret) { /* Handle bad event results gracefully by ignoring it. */ if ($ret->getErrorCode() & (ERROR_BAD_PARAMETER | ERROR_PLUGIN_VERSION_MISMATCH)) { global $gallery; $gallery->debug(sprintf('Error: The theme [%s] specified by a [%s] event ' . 'handler could not be loaded', $themeId, 'Gallery::LoadThemeAndParameters')); $theme = $params = null; } else { return array($ret, null, null); } } } if (!isset($theme)) { $params = null; } return array(null, $theme, $params); } /** * Load the given theme if it's active. * * @param string $themeId * @return array GalleryStatus a status code * GalleryTheme theme or null * @access private * @static */ function _loadTheme($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; } } ?> mId (optional) * @return GalleryStatus a status code */ function removeParameter($parameterName, $itemId=0) { $ret = GalleryCoreApi::removePluginParameter( $this->getPluginType(), $this->getId(), $parameterName, $itemId); if ($ret) { return $ret; } return null; } /** * Fetch all plugin specific parameters for the given item. The results will contain * a mixture of global parameters and item specific parameters, where the * item specific ones ones override the global ones. * * @param int $itemId (optional) * @return array GalleryStatus a status code * array parameters in key => value form */ function fetchParameters($itemId=null) { $order = array(null); if ($itemId) { $order[] = $itemId; } $results = array(); /* TODO: we should do this in one database query, ordered by id. */ foreach ($order as $id) { list ($ret, $params) = GalleryCoreApi::fetchAllPluginParameters( $this->getPluginType(), $this->getId(), $id); if ($ret) { return array($ret, null); } $results = array_merge($results, $params); } return array(null, $results); } /** * Perform any upgrade tasks required at this point. This method is called * if the plugin version in the code does not match the version number in * the database. For modules, the framework will upgrade database tables as * necessary, but it is the responsibility of the module to: * * 1. Register/unregister permissions * 2. Move or massage data as required by the upgrade * * This method will be called with a null version on an initial install. * @param string $currentVersion the current version (null if this is an initial install) * @return GalleryStatus a status code * @access protected */ function upgrade($currentVersion) { return null; } /* Getters and setters below */ function setId($id) { $this->_id = $id; } function getId() { return $this->_id; } function setName($name) { $this->_name = $name; } function getName() { return $this->_name; } function setDescription($description) { $this->_description = $description; } function getDescription() { return $this->_description; } function setVersion($version) { $this->_version = $version; } function getVersion() { return $this->_version; } function getL10Domain() { return $this->getPluginType() . 's_' . $this->getId(); } function setRequiredCoreApi($requirement) { $this->_requiredCoreApi = $requirement; } function getRequiredCoreApi() { return $this->_requiredCoreApi; } /** * @access protected */ function getPluginType() { return null; } } ?> return $this->_requiredModuleApi; } /** * Translate string. Results are cached. * @param mixed $params string or array for translation * @param string $postSprintf (optional) attempt to translate post-sprintf string using this * value. This allows specific translation of strings like "Edit Album" or "Edit Photo" * with a fallback to translation of "Edit %s" for other %s values. * Currently only input string with single % token is supported. * @return translated string * @access protected */ function _translate($params, $postSprintf=null) { if (isset($postSprintf)) { $string = sprintf($params['text'], $postSprintf); } else if (is_string($params)) { $string = $params; } if (isset($string) && GalleryDataCache::containsKey('_translate ' . $string)) { return GalleryDataCache::get('_translate ' . $string); } if (isset($postSprintf)) { $result = $this->translate($string); } if (!isset($result) || $result == $string) { $result = $this->translate($params); } if (isset($string)) { GalleryDataCache::put('_translate ' . $string, $result); } return $result; } /** * Remove obsolete blocks from existing themes (bug #1636339). * * @return GalleryStatus a status code */ function _removeObsoleteThemeBlocks() { /* Get all available blocks, even from inactive modules; and used blocks. */ list ($ret, $blocks) = GalleryCoreApi::loadAvailableBlocks(true); if ($ret) { return $ret; } list ($ret, $searchResults) = GalleryCoreApi::getMapEntry('GalleryPluginParameterMap', array('pluginId', 'itemId', 'parameterName', 'parameterValue'), array('pluginType' => 'theme', 'parameterName' => new GallerySqlFragment('LIKE ?', '%Blocks'))); if ($ret) { return $ret; } /* Go through each available theme and find which blocks they're using. */ while ($result = $searchResults->nextResult()) { $themeId = $result[0]; $itemId = $result[1]; $paramName = $result[2]; $themeBlocks = unserialize($result[3]); if (!is_array($themeBlocks)) { continue; } foreach ($themeBlocks as $key => $blockInfo) { $blockInfo = explode('.', $blockInfo[0]); $pluginName = $blockInfo[0]; $blockName = $blockInfo[1]; /* Remove used block if it is not available any more. */ if ($pluginName == $this->getId() && !isset($blocks[$pluginName][$blockName])) { unset($themeBlocks[$key]); $ret = GalleryCoreApi::setPluginParameter( 'theme', $themeId, $paramName, serialize($themeBlocks), $itemId); if ($ret) { return $ret; } } } } return null; } } ?> path $path the directory which should be fixed * @return boolean true if all went well, false if there was an error. * @deprecated -- TODO: remove at the next major version bump of core API */ function recursiveFixDirPermissions($path) { global $gallery; if ($gallery->getDebug()) { $gallery->debug("recursiveFixDirPermissions($path)"); } if (!$this->is_dir($path)) { return true; } else if (!$this->chmod($path)) { return false; } $dir = $this->opendir($path); if (!$dir) { return false; } $slash = $this->getDirectorySeparator(); while ($file = $this->readdir($dir)) { if ($file != '.' && $file != '..' && !$this->recursiveFixDirPermissions($path . $slash . $file)) { return false; } } $this->closedir($dir); return true; } /** * Format a local time/date according to locale settings. Converts any text output from * strftime tokens to UTF-8. * @param string $format * @param int $timestamp (optional) * @return string */ function strftime($format, $timestamp=null) { global $gallery; if ($gallery->getDebug()) { $gallery->debug("strftime($format, $timestamp)"); } $i = 0; $newFormat = ''; $textPieces = array(); /* Separate text and tokens so we can convert only token output to UTF-8 */ foreach (preg_split('{(%.)}', $format, -1, PREG_SPLIT_DELIM_CAPTURE) as $piece) { if (++$i % 2) { $textPieces[] = $piece; $newFormat .= '&%%&s'; } else { $newFormat .= $piece; } } /* Call strftime and convert to UTF-8; escape % characters before sprintf */ $newFormat = str_replace(array('%', '&%%&'), array('%%', '%'), GalleryCoreApi::convertToUtf8( isset($timestamp) ? strftime($newFormat, $timestamp) : strftime($newFormat))); return vsprintf($newFormat, $textPieces); } /** * The glob() function searches for all the pathnames matching pattern according to the rules * used by the libc glob() function, which is similar to the rules used by common shells. No * tilde expansion or parameter substitution is done. * @param string pattern * @param int flags (optional) * @return array containing the matched files/directories or FALSE on error. */ function glob($pattern, $flags=null) { global $gallery; if ($gallery->getDebug()) { $gallery->debug("glob($pattern, $flags)"); } if (isset($flags)) { return glob($pattern, $flags); } else { return glob($pattern); } } /** * Clear any cached saved state in this platform. */ function resetPlatform() { unset($this->_umask); unset($this->_filePerms); unset($this->_dirPerms); GalleryDataCache::remove('GalleryPlatform::_loadPermissionPreferences'); } } ?> ?>