getThemeName(); } public function hasStylesheet() { $cssFilename = sprintf('%s/%s/theme.css', $this->getThemePublicPath(), $this->getThemeName()); return file_exists($cssFilename); } public function info() { $themeName = $this->getThemeName(); $jsonFile = sprintf('%s/%s/theme.json', $this->getThemePrivatePath(), $this->sanitiseThemeName($themeName)); if (file_exists($jsonFile)) { return json_decode(file_get_contents($jsonFile), true); } return array(); } public function render($viewPath, array $viewData = array()) { $themeName = $this->getThemeName(); // First see if the current theme has the specified file $requestedViewFilename = $this->getRealFilePath($themeName, $viewPath); if (!file_exists($requestedViewFilename)) { // If it doesn't, revert to the base theme // TODO allow themes to specify another theme as the parent, and traverse up the theme tree to find the // relevant file - this allows for sub-themes $themeName = ThemeHelper::DEFAULT_THEME; } return view(sprintf('themes.%s.%s', $themeName, $viewPath), $viewData); } private function getRealFilePath($themeName, $viewPath) { return sprintf( '%s/%s/%s.blade.php', $this->getThemePrivatePath(), $themeName, str_replace('.', DIRECTORY_SEPARATOR, $viewPath) ); } private function getThemePrivatePath() { return sprintf('%s/resources/views/themes', dirname(dirname(__DIR__))); } private function getThemePublicPath() { return sprintf('%s/public/themes', dirname(dirname(__DIR__))); } private function getThemeName() { $themeName = ThemeHelper::DEFAULT_THEME; $currentTheme = Configuration::where('key', 'theme')->first(); if (!is_null($currentTheme)) { $themeName = $currentTheme->value; } return $this->sanitiseThemeName($themeName); } private function sanitiseThemeName($themeName) { // Ensure nasty people can't try and trick us into traversing the directory tree return preg_replace('/[\\\.\/]/', '', strtolower($themeName)); } }