X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=lib%2Ftheme.php;h=95b7c1de4b584982ea4f4841962e27299a3581f9;hb=b26eccf33cf69c04a96d5d6d3eddc0ef68ffd4b1;hp=e5fad2316bcb82797f9901b29b4b6360e28f0129;hpb=cbae1b0c8b18de0b6643e066c89578523c5e8002;p=quix0rs-gnu-social.git diff --git a/lib/theme.php b/lib/theme.php index e5fad2316b..95b7c1de4b 100644 --- a/lib/theme.php +++ b/lib/theme.php @@ -39,6 +39,9 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * in them. They're found in either local/theme (for locally-installed themes) * or theme/ subdir of installation dir. * + * Note that the 'local' directory can be overridden as $config['local']['path'] + * and $config['local']['dir'] etc. + * * This used to be a couple of functions, but for various reasons it's nice * to have a class instead. * @@ -51,6 +54,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { class Theme { + var $name = null; var $dir = null; var $path = null; @@ -67,53 +71,105 @@ class Theme if (empty($name)) { $name = common_config('site', 'theme'); } + if (!self::validName($name)) { + throw new ServerException("Invalid theme name."); + } + $this->name = $name; // Check to see if it's in the local dir - $localroot = Theme::localRoot(); + $localroot = self::localRoot(); $fulldir = $localroot.'/'.$name; if (file_exists($fulldir) && is_dir($fulldir)) { $this->dir = $fulldir; - $this->path = common_path('local/theme/'.$name.'/'); + $this->path = $this->relativeThemePath('local', 'local', 'theme/' . $name); return; } // Check to see if it's in the distribution dir - $instroot = Theme::installRoot(); + $instroot = self::installRoot(); $fulldir = $instroot.'/'.$name; if (file_exists($fulldir) && is_dir($fulldir)) { $this->dir = $fulldir; + $this->path = $this->relativeThemePath('theme', 'theme', $name); + } + } - $path = common_config('theme', 'path'); + /** + * Build a full URL to the given theme's base directory, possibly + * using an offsite theme server path. + * + * @param string $group configuration section name to pull paths from + * @param string $fallbackSubdir default subdirectory under INSTALLDIR + * @param string $name theme name + * + * @return string URL + * + * @todo consolidate code with that for other customizable paths + */ - if (empty($path)) { - $path = common_config('site', 'path') . '/theme/'; + protected function relativeThemePath($group, $fallbackSubdir, $name) + { + if (StatusNet::isHTTPS()) { + + $sslserver = common_config($group, 'sslserver'); + + if (empty($sslserver)) { + if (is_string(common_config('site', 'sslserver')) && + mb_strlen(common_config('site', 'sslserver')) > 0) { + $server = common_config('site', 'sslserver'); + } else if (common_config('site', 'server')) { + $server = common_config('site', 'server'); + } + $path = common_config('site', 'path') . '/'; + if ($fallbackSubdir) { + $path .= $fallbackSubdir . '/'; + } + } else { + $server = $sslserver; + $path = common_config($group, 'sslpath'); + if (empty($path)) { + $path = common_config($group, 'path'); + } } - if ($path[strlen($path)-1] != '/') { - $path .= '/'; - } + $protocol = 'https'; - if ($path[0] != '/') { - $path = '/'.$path; + } else { + + $path = common_config($group, 'path'); + + if (empty($path)) { + $path = common_config('site', 'path') . '/'; + if ($fallbackSubdir) { + $path .= $fallbackSubdir . '/'; + } } - $server = common_config('theme', 'server'); + $server = common_config($group, 'server'); if (empty($server)) { $server = common_config('site', 'server'); } - // XXX: protocol + $protocol = 'http'; + } + + if ($path[strlen($path)-1] != '/') { + $path .= '/'; + } - $this->path = 'http://'.$server.$path.$name; + if ($path[0] != '/') { + $path = '/'.$path; } + + return $protocol.'://'.$server.$path.$name; } /** @@ -142,6 +198,58 @@ class Theme return $this->path.'/'.$relative; } + /** + * Fetch a list of other themes whose CSS needs to be pulled in before + * this theme's, based on following the theme.ini 'include' settings. + * (May be empty if this theme has no include dependencies.) + * + * @return array of strings with theme names + */ + function getDeps() + { + $chain = $this->doGetDeps(array($this->name)); + array_pop($chain); // Drop us back off + return $chain; + } + + protected function doGetDeps($chain) + { + $data = $this->getMetadata(); + if (!empty($data['include'])) { + $include = $data['include']; + + // Protect against cycles! + if (!in_array($include, $chain)) { + try { + $theme = new Theme($include); + array_unshift($chain, $include); + return $theme->doGetDeps($chain); + } catch (Exception $e) { + common_log(LOG_ERR, + "Exception while fetching theme dependencies " . + "for $this->name: " . $e->getMessage()); + } + } + } + return $chain; + } + + /** + * Pull data from the theme's theme.ini file. + * @fixme calling getFile will fall back to default theme, this may be unsafe. + * + * @return associative array of strings + */ + function getMetadata() + { + $iniFile = $this->getFile('theme.ini'); + if (file_exists($iniFile)) { + return parse_ini_file($iniFile); + } else { + return array(); + } + } + /** * Gets the full path of a file in a theme dir based on its relative name * @@ -172,6 +280,51 @@ class Theme return $theme->getPath($relative); } + /** + * list available theme names + * + * @return array list of available theme names + */ + + static function listAvailable() + { + $local = self::subdirsOf(self::localRoot()); + $install = self::subdirsOf(self::installRoot()); + + $i = array_search('base', $install); + + unset($install[$i]); + + return array_merge($local, $install); + } + + /** + * Utility for getting subdirs of a directory + * + * @param string $dir full path to directory to check + * + * @return array relative filenames of subdirs, or empty array + */ + + protected static function subdirsOf($dir) + { + $subdirs = array(); + + if (is_dir($dir)) { + if ($dh = opendir($dir)) { + while (($filename = readdir($dh)) !== false) { + if ($filename != '..' && $filename !== '.' && + is_dir($dir.'/'.$filename)) { + $subdirs[] = $filename; + } + } + closedir($dh); + } + } + + return $subdirs; + } + /** * Local root dir for themes * @@ -180,7 +333,13 @@ class Theme protected static function localRoot() { - return INSTALLDIR.'/local/theme'; + $basedir = common_config('local', 'dir'); + + if (empty($basedir)) { + $basedir = INSTALLDIR . '/local'; + } + + return $basedir . '/theme'; } /** @@ -199,4 +358,9 @@ class Theme return $instroot; } + + static function validName($name) + { + return preg_match('/^[a-z0-9][a-z0-9_-]*$/i', $name); + } }