'generic', 'adult' => 'adult', 'blog' => 'blog', // 'clan' => 'clan', // 'children' => 'children', 'corporate' => 'corporate', // 'forum' => 'forum', 'gaming' => 'gaming', // 'gallery' => 'gallery', 'news' => 'news', // 'social' => 'social', // 'video' => 'video', // 'multimedia' => 'multimedia' ); private $_data = array(); private $_current = null; private $_frontcss = null; private $_admincss = null; private $_legacy_themes = array(); const CACHETIME = 120; // 2 hours const CACHETAG = "Meta_theme"; /** * @param $options */ function __construct($options=array()) { $options['force'] = isset($options['force']) ? $options['force'] : false; if(!empty($options['themedir'])) { $this->_current = $options['themedir']; } if(!defined('E107_INSTALL')) { $this->_frontcss = e107::getPref('themecss'); $this->_admincss = e107::getPref('admincss'); } if(empty($this->_data) || $options['force'] === true) { $this->load($options['force']); } } /** * @return string[] */ function getCategoryList() { return self::$allowedCategories; } /** * Load theme layout from html files * Requires theme.html file in the theme root directory. * @param string $key layout name * @return array|bool */ public static function loadLayout($key=null, $theme = null) { if($theme === null) { $theme = deftrue('USERTHEME', e107::pref('core','sitetheme')); if(defined('PREVIEWTHEME')) { $theme = PREVIEWTHEME; } } if(!is_readable(e_THEME.$theme."/layouts/".$key."_layout.html") || !is_readable(e_THEME.$theme."/theme.html")) { return false; } e107::getDebug()->log("Using HTML layout: ".$key.".html"); $tmp = file_get_contents(e_THEME.$theme."/theme.html"); $LAYOUT = array(); list($LAYOUT['_header_'], $LAYOUT['_footer_']) = explode("{---LAYOUT---}", $tmp, 2); $tp = e107::getParser(); e107::getScParser()->loadThemeShortcodes($theme); if(strpos($LAYOUT['_header_'], '{---HEADER---}')!==false) { $LAYOUT['_header_'] = str_replace('{---HEADER---}', $tp->parseTemplate('{HEADER}'), $LAYOUT['_header_']); } if(strpos($LAYOUT['_footer_'], '{---FOOTER---}')!==false) { $LAYOUT['_footer_'] = str_replace('{---FOOTER---}', $tp->parseTemplate('{FOOTER}'), $LAYOUT['_footer_']); } $LAYOUT[$key] = file_get_contents(e_THEME.$theme."/layouts/".$key."_layout.html"); return $LAYOUT; } /** * @return void */ public static function showPreview() { /* e107::includeLan(e_LANGUAGEDIR.e_LANGUAGE."/admin/lan_theme.php"); $text = "
".TPVLAN_1.".

"; $srch = array( '{PREVIEWTHEMENAME}' => PREVIEWTHEME, '{e_ADMIN}' => e_ADMIN );*/ // $text = str_replace(array_keys($srch),$srch,$text); echo "
Theme Preview Mode: " . PREVIEWTHEME . "
"; // global $ns; // $ns->tablerender(TPVLAN_2, $text); } /** * Return an array of theme library or stylesheet values (as defined in theme.xml) that match the desired scope. * @note New in v2.3.1+ * @param string $type library | css * @param string $scope front | admin | all | auto (as defined in theme.xml) * @return array */ public function getScope($type, $scope) { $validScopes = array('auto', 'all', 'front', 'admin', 'wysiwyg'); if($scope === 'auto') { $scope = 'front'; if(deftrue('e_ADMIN_AREA', false)) { $scope = 'admin'; } } elseif(!in_array($scope, $validScopes)) { return false; } if($type === 'library') { $themeXMLData = $this->get('library'); } elseif($type === 'css') { $themeXMLData = $this->get('css'); } $ret = []; if(empty($themeXMLData)) { return $ret; } foreach($themeXMLData as $info) { if(!isset($info['scope'])) { continue; } $tmp = explode(',', $info['scope']); $name = $info['name']; foreach($tmp as $scp) { $scp = trim($scp); if($scp === $scope || $scp === 'all' || $scope === 'all') { unset($info['scope']); $ret[$name] = $info; } } } return $ret; } /** * Returns an array of all files defined in theme.xml based on the specified scope. * @param $type * @param $scope * @return array */ function getThemeFiles($type, $scope) { $data = $this->getScope($type, $scope); $ret = []; if($type === 'library') { foreach($data as $name => $var) { $files = !empty($var['files']) ? array($var['files']) : null; if(strpos($name,'fontawesome')!==false && ($files === null)) { $files = array('css'); } if($name === 'bootstrap' && ((int) $var['version'] > 3)) // quick fix. { $name .= (string) $var['version']; } elseif($name === 'fontawesome' && ((int) $var['version'] > 4)) // quick fix. { $name .= (string) $var['version']; } $ret[] = e107::library('files', $name, null, $files); } } elseif($type === 'css') { $ret['css'] = array(); foreach($data as $file => $var) { $ret['css'][] = '{e_THEME}'.$this->get('path').'/'.$file; } } return $ret; } /** * Load library dependencies. * * @param string $scope front | admin | all | auto */ public function loadLibrary($scope = 'auto') { $libraries = $this->getScope('library', $scope); if(empty($libraries)) { return; } $loaded = []; $excludeCSS = (string) $this->cssAttribute('auto', 'exclude'); // current theme style foreach($libraries as $name => $library) { if(empty($name)) { continue; } if($name === $excludeCSS) { $library['files'] = 'js'; // load only JS, but not CSS since the style excluded it. } if($name === 'bootstrap' && !empty($library['version'])) { if((int) $library['version'] > 3) // quick fix. { $name .= (string) $library['version']; } e107::getParser()->setBootstrap($library['version']); if(!defined('BOOTSTRAP')) { define('BOOTSTRAP', (int) $library['version']); } } elseif($name === 'fontawesome' && !empty($library['version'])) { if((int) $library['version'] > 4) // quick fix. { $name .= (string) $library['version']; } e107::getParser()->setFontAwesome($library['version']); if(!defined('FONTAWESOME')) { define('FONTAWESOME', (int) $library['version']); } if(empty($library['files'])) // force CSS only for backward compatibility. { $library['files'] = 'css'; } } // support for 'files' attribute in theme.xml library tag. Specific which part of library to load. js || css or leave empty for both. /* @see theme.xml */ $files = !empty($library['files']) ? array($library['files']) : ['js', 'css']; e107::library('load', $name, null, $files); e107::library('preload', $name); $loaded[] = $name; } return $loaded; } /** * Get info on the current front or admin theme and selected style. * (ie. as found in theme.xml ) * * @param string $mode * front | admin | auto * @param string $var * file | name | scope | exclude * * @return mixed */ public function cssAttribute($mode = 'front', $var = null) { $css = $this->get('css'); if(empty($css)) { return false; } if($mode === 'auto') { $mode = 'front'; if(deftrue('e_ADMIN_AREA', false)) { $mode = 'admin'; } } foreach($css as $k => $v) { if($mode === 'front' && $v['name'] === $this->_frontcss) { return !empty($var) ? varset($v[$var], null) : $v; } if($mode === 'admin' && $v['name'] === $this->_admincss) { return !empty($var) ? varset($v[$var], null) : $v; } } return false; } /** * @return $this */ public function clearCache() { e107::getCache()->clear(self::CACHETAG, true); return $this; } /** * @param $text * @return array|string|string[] */ public function upgradeThemeCode($text) { $search = array(); $replace = array(); $search[0] = '$HEADER '; $replace[0] = '$HEADER["default"] '; $search[1] = '$FOOTER '; $replace[1] = '$FOOTER["default"] '; // Early 0.6 and 0.7 Themes $search[2] = '$CUSTOMHEADER '; $replace[2] = '$HEADER["custom"] '; $search[3] = '$CUSTOMFOOTER '; $replace[3] = '$FOOTER["custom"] '; //TODO Handle v1.x style themes. eg. $CUSTOMHEADER['something']; $text = str_replace($_SESSION['themebulder-remove'],"",$text); $text = str_replace($search, $replace, $text); return $text; } /** * Load data for all themes in theme directory. * @param bool|false $force * @return $this */ private function load($force=false) { $themeArray = array(); $cacheTag = self::CACHETAG; if($force === false && $tmp = e107::getCache()->retrieve($cacheTag, self::CACHETIME, true, true)) { $this->_data = e107::unserialize($tmp); return $this; } // $array = scandir(e_THEME); $array = e107::getFile()->get_dirs(e_THEME); $tloop = 1; foreach($array as $file) { if($file != "CVS" && $file != "templates" && is_readable(e_THEME.$file."/theme.php")) { $themeArray[$file] = self::getThemeInfo($file); $themeArray[$file]['id'] = $tloop; $tloop++; } } $cacheSet = e107::serialize($themeArray,'json'); e107::getCache()->set($cacheTag,$cacheSet,true,true,true); $this->_data = $themeArray; } /** * Return a var from the current theme or all vars if $var is empty. * @param string|null $var * @param null $key * @return array|bool */ public function get($var=null, $key=null) { if(empty($var) && isset($this->_data[$this->_current])) { return $this->_data[$this->_current]; } return isset($this->_data[$this->_current][$var]) ? $this->_data[$this->_current][$var] : false; } /** * Returns the fontawesome version of the currently loaded theme. * @return integer|false */ public function getFontAwesome() { return $this->getLibVersion('fontawesome'); } /** * Returns the libarie's version of the currently loaded theme. * @param string $name eg. 'fontawesome' or 'bootstrap' * @return false|int */ public function getLibVersion($name) { $lib = $this->get('library'); foreach($lib as $var) { if($var['name'] === $name && !empty($var['version']) ) { return (int) $var['version']; } } return false; } /** * Rebuild URL without trackers, for matching against theme_layout prefs. * @param string $url * @return string */ private static function filterTrackers($url) { if(strpos($url,'?') === false || empty($url)) { return $url; } list($site,$query) = explode('?',$url); parse_str($query,$get); $get = eHelper::removeTrackers($get); return empty($get) ? $site : $site.'?'.http_build_query($get); } /** * Calculate THEME_LAYOUT constant based on theme preferences and current request. (url, script, route) * * @param array $cusPagePref * @param string $defaultLayout * @param array $request url => (optional) defaults to e_REQUEST_URL, 'script'=> $_SERVER['SCRIPT_FILENAME'], 'route' => e_ROUTE * @return int|string */ public static function getThemeLayout($cusPagePref, $defaultLayout, $request) { $request_url = isset($request['url']) ? $request['url'] : null; $request_script = isset($request['script']) ? $request['script'] : null; if($request_url === null) { $request_url = e_REQUEST_URL; } $def = ""; // no custom pages found yet. $matches = array(); if(is_array($cusPagePref) && count($cusPagePref)>0) // check if we match a page in layout custompages. { //e_SELF.(e_QUERY ? '?'.e_QUERY : ''); $c_url = str_replace(array('&'), array('&'), $request_url);//.(e_QUERY ? '?'.e_QUERY : '');// mod_rewrite support // FIX - check against urldecoded strings $c_url = rtrim(rawurldecode($c_url), '?'); $c_url = self::filterTrackers($c_url); // First check all layouts for exact matches - possible fix for future issues?. /* foreach($cusPagePref as $lyout=>$cusPageArray) { if(!is_array($cusPageArray)) { continue; } $base = basename($request_url); if(in_array("/".$base, $cusPageArray) || in_array($base, $cusPageArray)) { return $lyout; } }*/ foreach($cusPagePref as $lyout=>$cusPageArray) { if(!is_array($cusPageArray)) { continue; } // NEW - Front page template check - early if(in_array('FRONTPAGE', $cusPageArray) && ($c_url == SITEURL || rtrim($c_url, '/') === SITEURL.'index.php')) { return $lyout; } foreach($cusPageArray as $kpage) { // e_ROUTE if(!empty($request['route']) && (strpos(':'.$request['route'], $kpage) === 0)) { return $lyout; } $kpage = str_replace('$', '$', $kpage); // convert database encoding. $lastChar = substr($kpage, -1); if($lastChar === '$') // script name match. { $kpage = rtrim($kpage, '$'); if(!empty($request_script) && strpos($request_script, '/'.$kpage) !== false) { return $lyout; } } if($lastChar === '!') { $kpage = rtrim($kpage, '!'); if(basename($request_url) === $kpage) // exact match specified by '!', skip other processing. { return $lyout; } elseif(substr($c_url, - strlen($kpage)) === $kpage) { $def = $lyout; } continue; } if (!empty($kpage) && (strpos($c_url, $kpage) !== false)) // partial URL match { similar_text($c_url,$kpage,$perc); $matches[$lyout] = round($perc,2); // rank the match // echo $c_url." : ".$kpage." --- ".$perc."\n"; } } } } if(!empty($matches)) // return the highest ranking match. { $top = array_keys($matches, max($matches)); $def = $top[0]; //print_r($matches); } if($def) // custom-page layout. { $layout = $def; } else // default layout. { $layout = $defaultLayout; } return $layout; } /** * Return a list of all local themes in various formats. * Replaces getThemeList * @param null|string $mode null, 'version' | 'id' | 'xml' * @return array|bool a list or false if no results */ public function getList($mode=null) { $arr = array(); switch ($mode) { case "version": foreach($this->_data as $dir=>$v) { $arr[$dir] = array('version'=>$v['version'], 'author'=>$v['author']); } break; case "id": $count = 1; foreach($this->_data as $dir=>$v) { $arr[$count] = $dir; $count++; } break; case 'xml': $count = 1; foreach($this->_data as $dir=>$v) { if($v['legacy'] === true) { continue; } $v['id'] = $count; // reset the counter. $arr[$dir] = $v; $count++; } break; default: $arr = $this->_data; } return !empty($arr) ? $arr : false; } /** * Get a list of all themes in theme folder and its data. * @deprecated Use getList($mode) instead * @see load(); * @param bool|false xml|false * @param bool|false $force force a refresh ie. ignore cached list. * @return array *//* public static function getThemeList($mode = false, $force = false) { trigger_error(''.__METHOD__.' is deprecated. Use getList() instead.', E_USER_DEPRECATED); // NO LAN $themeArray = array(); $tloop = 1; $cacheTag = self::CACHETAG; if(!empty($mode)) { $cacheTag = self::CACHETAG.'_'.$mode; } if($force === false && $tmp = e107::getCache()->retrieve($cacheTag, self::CACHETIME, true, true)) { return e107::unserialize($tmp); } $array = scandir(e_THEME); foreach($array as $file) { if(($mode == 'xml') && !is_readable(e_THEME.$file."/theme.xml")) { continue; } if($file != "." && $file != ".." && $file != "CVS" && $file != "templates" && is_dir(e_THEME.$file) && is_readable(e_THEME.$file."/theme.php")) { if($mode === "id") { $themeArray[$tloop] = $file; } elseif($mode === 'version') { $data = self::getThemeInfo($file); $themeArray[$file] = $data['version']; } else { $themeArray[$file] = self::getThemeInfo($file); $themeArray[$file]['id'] = $tloop; } $tloop++; } } $cacheSet = e107::serialize($themeArray,'json'); e107::getCache()->set($cacheTag,$cacheSet,true,true,true); return $themeArray; } */ /** * Internal Use. Heavy CPU usage. * Use e107::getTheme($themeDir,$force)->get() instead. * @param string $file theme directory name. * @return mixed */ public static function getThemeInfo($file) { $reject = array('e_.*'); $handle2 = e107::getFile()->get_files(e_THEME.$file."/", "\.php|\.css|\.xml|preview\.jpg|preview\.png", $reject, 1); $themeArray = array(); $themeArray[$file] = array(); foreach ($handle2 as $fln) { $file2 = str_replace(e_THEME.$file."/", "", $fln['path']).$fln['fname']; $themeArray[$file]['files'][] = $file2; if(strpos($file2, "preview.") !== false) { $themeArray[$file]['preview'] = e_THEME.$file."/".$file2; } // ---------------- get information string for css file - Legacy mode (no theme.xml) if(strpos($file2, ".css") !== false && strpos($file2, "menu.css") === false && strpos($file2, "e_") !== 0) { if($cssContents = file_get_contents(e_THEME.$file."/".$file2)) { $nonadmin = preg_match('/\* Non-Admin(.*?)\*\//', $cssContents) ? true : false; preg_match('/\* info:(.*?)\*\//', $cssContents, $match); $match[1] = varset($match[1]); $scope = ($nonadmin == true) ? 'front' : ''; $themeArray[$file]['css'][] = array("name"=>$file2, "info"=>$match[1], "scope"=>$scope, "nonadmin"=>$nonadmin); } //else //{ // $mes->addDebug("Couldn't read file: ".e_THEME.$file."/".$file2); // } } } // end foreach // Load Theme information and merge with existing array. theme.xml (v2.x theme) is given priority over theme.php (v1.x). if(!empty($themeArray[$file]['files'])) { if(in_array("theme.xml", $themeArray[$file]['files'])) { $themeArray[$file] = array_merge($themeArray[$file], self::parse_theme_xml($file)); } elseif(in_array("theme.php", $themeArray[$file]['files'])) { $themeArray[$file] = array_merge($themeArray[$file], self::parse_theme_php($file)); } } if(!empty($themeArray[$file]['css']) && count($themeArray[$file]['css']) > 1) { $themeArray[$file]['multipleStylesheets'] = true; } return $themeArray[$file]; } /** * Legacy Plugin theme.php meta data parser. * @param string $path theme folder name * @return array */ public static function parse_theme_php($path) { $CUSTOMPAGES = null; $tp = e107::getParser(); // could be used by a theme file. $sql = e107::getDb(); // could be used by a theme file. $fp = fopen(e_THEME.$path."/theme.php", "r"); $themeContents = fread($fp, filesize(e_THEME.$path."/theme.php")); fclose($fp); preg_match('/themename(\s*?=\s*?)("|\')(.*?)("|\');/si', $themeContents, $match); $themeArray['name'] = varset($match[3]); preg_match('/themeversion(\s*?=\s*?)("|\')(.*?)("|\');/si', $themeContents, $match); $themeArray['version'] = varset($match[3]); preg_match('/themeauthor(\s*?=\s*?)("|\')(.*?)("|\');/si', $themeContents, $match); $themeArray['author'] = varset($match[3]); preg_match('/themeemail(\s*?=\s*?)("|\')(.*?)("|\');/si', $themeContents, $match); $themeArray['email'] = varset($match[3]); preg_match('/themewebsite(\s*?=\s*?)("|\')(.*?)("|\');/si', $themeContents, $match); $themeArray['website'] = varset($match[3]); preg_match('/themedate(\s*?=\s*?)("|\')(.*?)("|\');/si', $themeContents, $match); $themeArray['date'] = varset($match[3]); preg_match('/themeinfo(\s*?=\s*?)("|\')(.*?)("|\');/si', $themeContents, $match); $themeArray['info'] = varset($match[3]); preg_match('/xhtmlcompliant(\s*?=\s*?)(\S*?);/si', $themeContents, $match); $xhtml = !empty($match[2]) ? strtolower($match[2]) : ''; $themeArray['xhtmlcompliant'] = ($xhtml == "true" ? "1.1" : false); preg_match('/csscompliant(\s*?=\s*?)(\S*?);/si', $themeContents, $match); $css = !empty($match[2]) ? strtolower($match[2]) : ''; $themeArray['csscompliant'] = ($css == "true" ? "2.1" : false); if(!empty($themeArray['version'])) { $themeArray['version'] = str_replace(array('
','
','
'),' ', $themeArray['version']); } /* preg_match('/CUSTOMPAGES(\s*?=\s*?)("|\')(.*?)("|\');/si', $themeContents, $match); $themeArray['custompages'] = array_filter(explode(" ",$match[3]));*/ $themeContentsArray = explode("\n", $themeContents); preg_match_all("#\\$"."CUSTOMHEADER\[(\"|')(.*?)('|\")\].*?#",$themeContents,$match); $customHeaderArray = $match[2]; preg_match_all("#\\$"."CUSTOMFOOTER\[(\"|')(.*?)('|\")\].*?#",$themeContents,$match); $customFooterArray = $match[2]; if(!$themeArray['name']) { unset($themeArray); } $lays['legacyDefault']['@attributes'] = array('title'=>'Default', 'plugins'=>'', 'default'=>'true'); // load custompages from theme.php only when theme.xml doesn't exist. if(!file_exists(e_THEME.$path."theme.xml")) { foreach ($themeContentsArray as $line) { if(strpos($line, "CUSTOMPAGES") !== false) { try { @eval(str_replace("$", "\$", $line)); // detect arrays also. } catch (ParseError $e) { } } } if(is_array($CUSTOMPAGES)) { foreach ($CUSTOMPAGES as $key=>$val) { $themeArray['custompages'][$key] = explode(" ", trim($val)); $lays[$key]['custompages'] = trim($val); } } elseif($CUSTOMPAGES) { $themeArray['custompages']['legacyCustom'] = explode(" ", $CUSTOMPAGES); $lays['legacyCustom']['@attributes'] = array('title'=>'Custom', 'plugins'=>''); } foreach($customHeaderArray as $tm) { $lays[$tm]['@attributes'] = array('title'=>str_replace("_"," ",$tm), 'plugins'=>''); } foreach($customFooterArray as $tm) { $lays[$tm]['@attributes'] = array('title'=>str_replace("_"," ",$tm), 'plugins'=>''); } } $themeArray['path'] = $path; $themeArray['layouts'] = $lays; $themeArray['description'] = $themeArray['info']; if(file_exists(e_THEME.$path."/preview.jpg")) { $themeArray['preview'] = array("preview.jpg"); $themeArray['thumbnail'] = "preview.jpg"; } if(file_exists(e_THEME.$path."/preview.png")) { $themeArray['preview'] = array("preview.png"); $themeArray['thumbnail'] = "preview.png"; } // echo "

".$themeArray['name']."

"; // print_a($lays); $themeArray['legacy'] = true; $themeArray['html'] = false; $themeArray['compatibility'] = '1'; return $themeArray; } /** * Reads theme.xml and returns an array of data from it. * @param string $path theme folder name * @return array */ public static function parse_theme_xml($path) { $tp = e107::getParser(); $xml = e107::getXml(); // loadLanFiles($path, 'admin'); // Look for LAN files on default paths // layout should always be an array. $xml->setOptArrayTags('layout,screenshots/image,plugins/plugin'); $xml->setOptStringTags('menuPresets,customPages,custompages'); // // $vars = $xml->loadXMLfile(e_THEME.$path.'/theme.xml', true, true); // $oldvars = $vars = $xml->loadXMLfile(e_THEME.$path.'/theme.xml', 'advanced', true); // must be 'advanced' //if($path == "bootstrap3" ) // { // echo " // //
oldnew parser
".print_a($oldvars,true)."".print_a($vars,true)."
"; // } $vars['name'] = varset($vars['@attributes']['name']); $vars['version'] = varset($vars['@attributes']['version']); $vars['date'] = varset($vars['@attributes']['date']); $vars['compatibility'] = !empty($vars['@attributes']['compatibility']) ? $tp->filter($vars['@attributes']['compatibility'], 'version') : ''; $vars['releaseUrl'] = varset($vars['@attributes']['releaseUrl']); $vars['email'] = varset($vars['author']['@attributes']['email']); $vars['website'] = varset($vars['author']['@attributes']['url']); $vars['author'] = varset($vars['author']['@attributes']['name']); $vars['info'] = !empty($vars['description']['@value']) ? $vars['description']['@value'] : varset($vars['description']); $vars['category'] = self::getThemeCategory(varset($vars['category'])); $vars['xhtmlcompliant'] = varset($vars['compliance']['@attributes']['xhtml']); $vars['csscompliant'] = varset($vars['compliance']['@attributes']['css']); $vars['@attributes']['default'] = (varset($vars['@attributes']['default']) && strtolower($vars['@attributes']['default']) == 'true') ? 1 : 0; $vars['preview'] = varset($vars['screenshots']['image']); $vars['thumbnail'] = isset($vars['preview'][0]) && file_exists(e_THEME.$path.'/'.$vars['preview'][0]) ? $vars['preview'][0] : ''; $vars['html'] = (file_exists(e_THEME . $path . '/theme.html') && is_dir(e_THEME . $path . '/layouts')); if(!empty($vars['themePrefs'])) { foreach($vars['themePrefs']['pref'] as $k=>$val) { $name = $val['@attributes']['name']; $vars['preferences'][$name] = $val['@value']; } } unset($vars['authorEmail'], $vars['authorUrl'], $vars['xhtmlCompliant'], $vars['cssCompliant'], $vars['screenshots']); // Compile layout information into a more usable format. $custom = array(); /* foreach ($vars['layouts'] as $layout) { foreach ($layout as $key=>$val) { $name = $val['@attributes']['name']; unset($val['@attributes']['name']); $lays[$name] = $val; if(isset($val['customPages'])) { $cusArray = explode(" ", $val['customPages']); $custom[$name] = array_filter($cusArray); } if(isset($val['custompages'])) { $cusArray = explode(" ", $val['custompages']); $custom[$name] = array_filter(explode(" ", $val['custompages'])); } } } */ $lays = array(); foreach($vars['layouts']['layout'] as $k=>$val) { $name = $val['@attributes']['name']; unset($val['@attributes']['name']); $lays[$name] = $val; if(isset($val['custompages'])) { if(is_string($val['custompages'])) { $custom[$name] = array_filter(explode(" ", $val['custompages'])); } elseif(is_array($val['custompages'])) { $custom[$name] = $val['custompages']; } } } $vars['layouts'] = $lays; $vars['path'] = $path; $vars['custompages'] = $custom; $vars['legacy'] = false; $vars['library'] = array(); if(!empty($vars['libraries']['library'])) { $vars['css'] = array(); foreach($vars['libraries']['library'] as $c=>$val) { foreach($val['@attributes'] as $k=>$v) { $vars['library'][$c][$k] = $v; } /* $vars['library'][] = array( 'name' => $val['@attributes']['name'], 'version' => varset($val['@attributes']['version']), 'scope' => varset($val['@attributes']['scope'], 'front'), );*/ } unset($vars['libraries']); } else // detect defined constants in legacy theme.php file. { if($data = self::getLegacyBSFA($path)) { $vars['library'] = $data; } } if(!empty($vars['stylesheets']['css'])) { $vars['css'] = array(); foreach($vars['stylesheets']['css'] as $val) { // $notadmin = vartrue($val['@attributes']['admin']) ? false : true; $notadmin = varset($val['@attributes']['scope']) !== 'admin'; $vars['css'][] = array( "name" => $val['@attributes']['file'], "info" => $val['@attributes']['name'], "nonadmin" => $notadmin, 'default' => vartrue($val['@attributes']['default'], false), 'scope' => vartrue($val['@attributes']['scope'], 'front'), 'exclude' => vartrue($val['@attributes']['exclude']), 'description' => vartrue($val['@attributes']['description']), 'thumbnail' => vartrue($val['@attributes']['thumbnail']) ); } unset($vars['stylesheets']); } $vars['glyphs'] = array(); if(!empty($vars['glyphicons']['glyph'])) { foreach($vars['glyphicons']['glyph'] as $val) { $vars['glyphs'][] = array( 'name' => isset($val['@attributes']['name']) ? $val['@attributes']['name'] : '', 'pattern' => isset($val['@attributes']['pattern']) ? $val['@attributes']['pattern'] : '', 'path' => isset($val['@attributes']['path']) ? $val['@attributes']['path'] : '', 'class' => isset($val['@attributes']['class']) ? $val['@attributes']['class'] : '', 'prefix' => isset($val['@attributes']['prefix']) ? $val['@attributes']['prefix'] : '', 'tag' => isset($val['@attributes']['tag']) ? $val['@attributes']['tag'] : '', ); } unset($vars['glyphicons']); } //if($path == "bootstrap3" ) // { // e107::getMessage()->addDebug("

".$path."

"); // e107::getMessage()->addDebug(print_a($vars,true)); // print_a($vars); // echo "
".print_a($vars,true)."".print_a($adv,true)."
"; // } return $vars; } /** * Read legacy bootstrap/fontawesome constants from theme.php * @param string $path theme directory */ public static function getLegacyBSFA($path) { if(!$content = file_get_contents(e_THEME.$path.'/theme.php')) { return false; } $ret = []; if(preg_match('/define[ ]*?\([\'|"]BOOTSTRAP[\'|"],[ \t]*(\d)\);/', $content, $m) && strpos($content,'bootstrap.min.css') === false && strpos($content,'bootstrap.min.js') === false) { $ret[] = array('name' => 'bootstrap', 'version' => $m[1], 'scope' => 'front,wysiwyg', ); } if(preg_match('/define[ ]*?\([\'|"]FONTAWESOME[\'|"],[ \t]*(\d)\);/', $content, $m) && strpos($content, 'font-awesome.min.css') === false) { $ret[] = array('name' => 'fontawesome', 'version' => $m[1], 'scope' => 'front,wysiwyg', ); } // e107::getDebug()->log($ret); return $ret; } /** * Validate and return the name of the categories. * * @param string [optional] $categoryfromXML * @return string */ private static function getThemeCategory($categoryfromXML = '') { if(!$categoryfromXML) { return 'generic'; } $tmp = explode(",", $categoryfromXML); $category = array(); foreach ($tmp as $cat) { $cat = trim($cat); if(in_array($cat, self::$allowedCategories)) { $category[] = $cat; } else { $category[] = 'generic'; } } return implode(', ', $category); } /** * @param $themeDir * @param $layout * @return void */ private static function initThemePreview($themeDir, $layout=null) { $themeDir = filter_var($themeDir); $themeDir = basename($themeDir); $themeobj = new themeHandler; $defLayout = !empty($layout) ? $layout : $themeobj->findDefault($themeDir); define('THEME_LAYOUT', $defLayout); define('PREVIEWTHEME', $themeDir); define('THEME', e_THEME . $themeDir . '/'); define('THEME_ABS', e_THEME_ABS . $themeDir . '/'); $legacy = (file_exists(e_THEME . $themeDir . '/theme.xml') === false); if($legacy === true) { $version = 1.0; } else { $version = (file_exists(e_THEME . $themeDir . '/theme.html')) ? 2.3 : 2.0; } define('THEME_VERSION', $version); define('THEME_LEGACY', $legacy); } /** * Define the THEME_STYLE constant * @param $pref */ public static function initThemeStyle($pref) { e107::getDebug()->logTime('Find/Load Theme-Layout'); // needs to run after checkvalidtheme() (for theme previewing). if(deftrue('e_ADMIN_AREA')) { define('THEME_STYLE', $pref['admincss']); self::initThemeLayout(); // the equivalent for frontend is in header_default.php } elseif(!empty($pref['themecss']) && (file_exists(THEME.$pref['themecss']) || strpos($pref['themecss'],'https') === 0)) { define('THEME_STYLE', $pref['themecss']); } else { define('THEME_STYLE', 'style.css'); } } /** * define the THEME_LAYOUT constant. * @return null */ public static function initThemeLayout() { if(defined('THEME_LAYOUT')) { return null; } $sitetheme_custompages = e107::getPref('sitetheme_custompages', array()); $sitetheme_deflayout = e107::getPref('sitetheme_deflayout'); $user_pref = e107::getUser()->getPref(); $cusPagePref = !empty($user_pref['sitetheme_custompages']) ? $user_pref['sitetheme_custompages'] : $sitetheme_custompages; $cusPageDef = !empty($user_pref['sitetheme_deflayout']) ? $user_pref['sitetheme_deflayout'] : $sitetheme_deflayout; $request = [ 'url' => e_REQUEST_URL, 'script' => varset($_SERVER['SCRIPT_FILENAME'],null), 'route' => e107::route(), ]; $deflayout = self::getThemeLayout($cusPagePref, $cusPageDef, $request); define('THEME_LAYOUT',$deflayout); } /** * Replacement of checkvalidtheme() * @param string $themeDir */ public static function initTheme($themeDir) { $sql = e107::getDb(); $e107 = e107::getInstance(); $tp = e107::getParser(); $pref = e107::getPref(); e107::getDebug()->logTime('Theme Check'); // e_QUERY not set when in single entry mod if (getperms('0') && !empty($_GET['themepreview'])) { $layout = !empty($_GET['layout']) ? $_GET['layout'] : null; self::initThemePreview($_GET['themepreview'], $layout); self::initThemeStyle($pref); return; } // check for valid theme. if (@fopen(e_THEME . $themeDir . '/theme.php', 'r')) { define('THEME', e_THEME . $themeDir . '/'); define('THEME_ABS', e_THEME_ABS . $themeDir . '/'); $legacy = (file_exists(e_THEME . $themeDir . '/theme.xml') === false); define('THEME_LEGACY', $legacy); if($legacy === true) { $version = 1.0; } else { $version = (file_exists(e_THEME . $themeDir . '/theme.html')) ? 2.3 : 2.0; } define('THEME_VERSION', $version); $e107->site_theme = $themeDir; e107::getDebug()->logTime('Theme Check End'); self::initThemeStyle($pref); return; } // fallback in case selected theme failed. $ADMIN_DIRECTORY = e107::getFolder('admin'); $e107tmp_theme = 'bootstrap3'; // set to bootstrap3 by default. define('THEME', e_THEME . $e107tmp_theme . '/'); define('THEME_ABS', e_THEME_ABS . $e107tmp_theme . '/'); define('THEME_VERSION', 2.3); define('THEME_LEGACY', false); define('USERTHEME', 'bootstrap3'); define('BOOTSTRAP', 3); define('FONTAWESOME', 5); if (ADMIN && (e_ADMIN_AREA !== true)) { echo "
".$themeDir." ".str_replace('\n','
',CORE_LAN1)."
"; } e107::getDebug()->logTime('Theme Check End'); self::initThemeStyle($pref); } } /** * */ class themeHandler { var $themeArray; var $action; var $id; var $frm; var $fl; var $themeConfigObj = null; var $themeConfigFormObj= null; var $noLog = FALSE; private $curTheme = null; // private $approvedAdminThemes = array('bootstrap','bootstrap3', 'bootstrap5'); /* public $allowedCategories = array('generic', 'adult', 'blog', 'clan', 'children', 'corporate', 'forum', 'gaming', 'gallery', 'news', 'social', 'video', 'multimedia');*/ /** * Marketplace handler instance * @var e_marketplace */ protected $mp; // const RENDER_THUMBNAIL = 0; const RENDER_SITEPREFS = 1; const RENDER_ADMINPREFS = 2; /* constructor */ function __construct() { global $e107cache,$pref; $mes = e107::getMessage(); require_once (e_HANDLER."form_handler.php"); //enable inner tabindex counter if(!deftrue("E107_INSTALL")) { $this->frm = new e_form(); } $this->fl = e107::getFile(); $this->postObserver(); } /** * @return void */ public function postObserver() { $mes = e107::getMessage(); $pref = e107::getPref(); if(!empty($_POST['upload'])) { $unzippedTheme = $this->themeUpload(); } if(!empty($_POST['curTheme'])) { $this->curTheme = e107::getParser()->filter($_POST['curTheme'],'file'); } if(!empty($_POST['setUploadTheme']) && !empty($unzippedTheme)) { $themeArray = e107::getTheme()->getList(); $this->id = $themeArray[$unzippedTheme]['id']; if($this->setTheme()) { $mes->addSuccess(TPVLAN_3); } else { $mes->addError(TPVLAN_86); } } if(!empty($_POST['installContent'])) { $this->installContent($_POST['installContent']); } $this->themeArray = (defined('E107_INSTALL')) ?e107::getTheme()->getList('xml') : e107::getTheme()->getList(); // print_a($this -> themeArray); foreach ($_POST as $key=>$post) { if(strpos($key, "preview") !== false) { // $this -> id = str_replace("preview_", "", $key); $this->id = key($post); $this->themePreview(); } /* if(strstr($key, "selectmain")) { // $this -> id = str_replace("selectmain_", "", $key); $this->id = key($post); if($this->setTheme()) { $mes->addSuccess(TPVLAN_3); } else { $mes->addError(TPVLAN_3); } }*/ /* if(strpos($key, "selectadmin") !== false) { $this->id = key($post); $this->setAdminTheme(); $this->refreshPage('admin'); }*/ } if(isset($_POST['submit_adminstyle'])) { $this->id = $this->curTheme; $this->setAdminStyle(); // this redirects. /*if($this->setAdminStyle()) { eMessage::getInstance()->add(TPVLAN_43, E_MESSAGE_SUCCESS); } e107::getConfig()->save(true);*/ } if(isset($_POST['submit_style'])) { $this->id = $this->curTheme; $this->setLayouts(); // Update the layouts in case they have been manually changed. $this->SetCustomPages($_POST['custompages']); $this->setStyle(); e107::getConfig()->save(); } if(!empty($_POST['git_pull'])) { $gitTheme = e107::getParser()->filter($_POST['git_pull'],'w'); $return = e107::getFile()->gitPull($gitTheme, 'theme'); $mes->addSuccess($return); } if(isset($_POST['installplugin'])) { $key = key($_POST['installplugin']); e107::includeLan(e_LANGUAGEDIR.e_LANGUAGE."/admin/lan_plugin.php"); require_once (e_HANDLER."plugin_class.php"); $eplug = new e107plugin; $message = $eplug->install_plugin($key); $mes->add($message, E_MESSAGE_SUCCESS); } if(isset($_POST['setMenuPreset'])) { $key = key($_POST['setMenuPreset']); e107::includeLan(e_LANGUAGEDIR.e_LANGUAGE."/admin/lan_menus.php"); require_once (e_HANDLER."menumanager_class.php"); $men = new e_menuManager(); $men->curLayout = $key; //menu_layout is left blank when it's default. $men->dbLayout = ($men->curLayout != $pref['sitetheme_deflayout']) ? $men->curLayout : ""; if($areas = $men->menuSetPreset()) { $message = ''; foreach ($areas as $val) { $ar[$val['menu_location']][] = $val['menu_name']; } foreach ($ar as $k=>$v) { $message .= MENLAN_14." ".$k." : ".implode(", ", $v)."
"; } $mes->add(MENLAN_43." : ".$key."
".$message, E_MESSAGE_SUCCESS); } } } /** * Returns a list of themes and their information. * @deprecated * @param false $mode * @return array|bool */ public function getThemes($mode = FALSE) { trigger_error(''.__METHOD__.' is deprecated. Use e107::getTheme()->getList($mode); instead. ', E_USER_DEPRECATED); return e107::getTheme()->getList($mode); } /** * @param string $file - theme folder name. * @return array|bool *@deprecated Use e107::getTheme($file)->get(); instead. */ function getThemeInfo($file) { trigger_error(''.__METHOD__.' is deprecated. Use e107::getTheme($themedir)->get(); instead. ', E_USER_DEPRECATED); return e107::getTheme($file)->get(); } /** * Validate and return the name of the categories. * * @param string [optional] $categoryfromXML * @return string */ /* function getThemeCategory($categoryfromXML = '') { if(!$categoryfromXML) { return 'generic'; } $tmp = explode(",", $categoryfromXML); $category = array(); foreach ($tmp as $cat) { $cat = trim($cat); if(in_array($cat, $this->allowedCategories)) { $category[] = $cat; } else { $category[] = 'generic'; } } return implode(', ', $category); } */ function themeUpload() { if(!$_POST['ac'] == md5(ADMINPWCHANGE)) { exit; } $mes = e107::getMessage(); $ns = e107::getRender(); // extract($_FILES); //print_a($_FILES); if(!is_writable(e_TEMP)) { $mes->addInfo(TPVLAN_20); return FALSE; } $fl = e107::getFile(); $mp = $this->getMarketplace(); $status = $fl->getUploaded(e_TEMP); if(!empty($status[0]['error'])) { $mes->addError($status[0]['message']); return; } $mes->addSuccess($status[0]['message']); return $fl->unzipArchive($status[0]['name'],'theme'); // else /* { // FIXME - temporary fixes to upload process, check required. // Probably in need of a rewrite to use process_uploaded_files(); require_once (e_HANDLER."upload_handler.php"); $fileName = $_FILES['file_userfile']['name'][0]; $fileSize = $_FILES['file_userfile']['size'][0]; $fileType = $_FILES['file_userfile']['type'][0]; // type is returned as mime type (application/octet-stream) not as zip/rar // There may be a better way to do this.. MIME may not be secure enough // process_uploaded_files() ? $mime_zip = array("application/octet-stream", "application/zip", "multipart/x-zip"); $mime_gzip = array("application/x-gzip", "multipart/x-gzip"); // rar? if(in_array($fileType, $mime_zip)) { $fileType = "zip"; } elseif(in_array($fileType, $mime_gzip)) { $fileType = "gzip"; } else { $mes->addError(TPVLAN_17); return FALSE; } if($fileSize) { $uploaded = file_upload(e_THEME); $archiveName = $uploaded[0]['name']; if($fileType == "zip") { require_once (e_HANDLER."pclzip.lib.php"); $archive = new PclZip(e_THEME.$archiveName); $unarc = ($fileList = $archive->extract(PCLZIP_OPT_PATH, e_THEME, PCLZIP_OPT_SET_CHMOD, 0666)); // FIXME - detect folder structure similar to 'Find themes' } else { require_once (e_HANDLER."pcltar.lib.php"); $unarc = ($fileList = PclTarExtract($archiveName, e_THEME)); // FIXME - detect folder structure similar to 'Find themes' } if(!$unarc) { if($fileType == "zip") { $error = TPVLAN_46." '".$archive->errorName(TRUE)."'"; } else { $error = TPVLAN_47.PclErrorString().", ".TPVLAN_48.intval(PclErrorCode()); } $mes->addError(TPVLAN_18." ".$archiveName." ".$error); return FALSE; } $folderName = substr($fileList[0]['stored_filename'], 0, (strpos($fileList[0]['stored_filename'], "/"))); $mes->addSuccess(TPVLAN_19); if(varset($_POST['setUploadTheme'])) { $themeArray = $this->getThemes(); $this->id = $themeArray[$folderName]['id']; if($this->setTheme()) { $mes->addSuccess(TPVLAN_3); } else { $mes->addError("Could not change site theme."); // TODO LAN } } @unlink(e_THEME.$archiveName); } } * */ } /** * @param $name * @param $searchVal * @param $submitName * @param $filterName * @param $filterArray * @param $filterVal * @return string */ private function search($name, $searchVal, $submitName, $filterName='', $filterArray=false, $filterVal=false) { $frm = e107::getForm(); return $frm->search($name, $searchVal, $submitName, $filterName, $filterArray, $filterVal); /* $text = ' '.$frm->text($name, $searchVal,20,'class=search-query').' '; // $text .= $this->admin_button($submitName,LAN_SEARCH,'search'); return $text; */ } /** * Temporary, e107::getMarketplace() coming soon * @return e_marketplace */ public function getMarketplace() { if(null === $this->mp) { require_once(e_HANDLER.'e_marketplace.php'); $this->mp = new e_marketplace(); // autodetect the best method } return $this->mp; } /* function renderOnline($ajax=false) { global $e107SiteUsername, $e107SiteUserpass; $xml = e107::getXml(); $mes = e107::getMessage(); $frm = e107::getForm(); $ns = e107::getRender(); $mp = $this->getMarketplace(); $from = intval(varset($_GET['frm'])); $limit = 96; // FIXME - ajax pages load $srch = preg_replace('/[\W]/','', vartrue($_GET['srch'])); // check for cURL if(!function_exists('curl_init')) { $mes->addWarning(TPVLAN_79); } // auth // $mp->generateAuthKey($e107SiteUsername, $e107SiteUserpass); // do the request, retrieve and parse data $xdata = $mp->call('getList', array( 'type' => 'theme', 'params' => array('limit' => $limit, 'search' => $srch, 'from' => $from) )); $total = $xdata['params']['count']; $amount =$limit; $c = 1; $filterName = ''; $filterArray = array(); $filterVal = ''; $text = "