0byt3m1n1
Path:
/
data
/
applications
/
aps
/
tikiwiki
/
14.1-0
/
standard
/
htdocs
/
lib
/
theme
/
[
Home
]
File: themegenlib.php
<?php // (c) Copyright 2002-2015 by authors of the Tiki Wiki CMS Groupware Project // // All Rights Reserved. See copyright.txt for details and a complete list of authors. // Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details. // $Id: themegenlib.php 53473 2015-01-12 18:33:21Z jonnybradley $ //this script may only be included - so its better to die if called directly. if (strpos($_SERVER['SCRIPT_NAME'], basename(__FILE__)) !== false) { header('location: index.php'); exit; } /* ThemeGenLib @extends ThemeLib */ class ThemeGenLib extends ThemeLib { private $currentTheme; // ThemeGenTheme private $tg_data; /** * */ public function __construct() { global $prefs; // array containing customisable elements // some handy matches $unit = '[-+]?[\d\.]+(?:px|em|ex|%|in|cm|mm|pt|pc)?'; $color = '#[0-9a-f]{3,6}|aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow'; $delims = '[\s\!;\}]'; // delimiter with space $delimn = '[\!;\}]'; // delimiter with NO space $selector = '[\}]\s*([^\{]*)\{[^\}]*'; $bstyles = 'dotted|dashed|solid|double|groove|ridge|inset|outset'; // no 'none' for now $this->tg_data = array( 'colors' => array( 'types' => array( 'fgcolors' => array( 'items' => array(), 'title' => tra('Foreground Colors'), 'selector' => 'color', 'regexps' => array( 'find' => '/(?<!-)color:\s*('.$color.')[;\}\!]/Umis', 'context' => '/'.$selector.'(?<!-)color:\s*$0'.$delims.'/Umis', 'replace' => '/((?<!-)color:\s*)$0('.$delims.')/Umis', ), ), 'bgcolors' => array( 'items' => array(), 'title' => tra('Background Colors'), 'selector' => 'color', 'regexps' => array( 'find' => '/background(?:-color)?:[^\};]*?('.$color.')'.$delims.'/Umis', 'context' => '/'.$selector.'background(?:-color)?:\s*$0'.$delims.'/Umis', 'replace' => '/(background(?:-color)?:[^;\}]*)$0('.$delims.')/Umis', ), ), ), 'title' => tra('Colors'), ), 'borders' => array( 'types' => array( 'bordercolors' => array( 'items' => array(), 'title' => tra('Border Colors'), 'selector' => 'color', 'regexps' => array( // special single find capture for borders with multiple colours 'find' => '/border[\w-]*\:[^;\}]*(#[0-9a-f\s]{3,6}[\s#0-9a-f]*)'.$delimn.'/Umis', 'context' => '/'.$selector.'border[\w-]*:[^\;\}\!]*$0[^\;\}\!]*'.$delimn.'/Umis', // special single replace capture for borders with multiple colours 'replace' => '/border[\w-]*:[^\;\}\!]*$0[^\;\}\!]*'.$delimn.'/Umis', ), ), 'borderwidths' => array( 'items' => array(), 'title' => tra('Border Widths'), 'selector' => 'size', 'regexps' => array( 'find' => '/border(?!-radius)[\w-]*(?<!radius):[^\};]*((?<![\da-f#])'.$unit.')[\s;\}\!]/Umis', 'context' => '/'.$selector.'border(?:(?!-radius)[\w-]*(?<!radius))?:[^\}]*(?<![\da-f#])$0'.$delims.'/Umis', 'replace' => '/(border(?!-radius)[\w-]*(?<!radius):[^;\}]*)(?<![\da-f#])$0('.$delims.')/Umis', ), ), 'borderstyles' => array( 'items' => array(), 'title' => tra('Border Styles'), 'selector' => 'borderstyle', 'regexps' => array( 'find' => '/border[\w-]*:[^\};]*('.$bstyles.')[\s;\}\!]/Umis', 'context' => '/'.$selector.'border[\w-]*:.*$0'.$delims.'/Umis', 'replace' => '/(border[\w-]*:[^;\}]*)$0('.$delims.')/Umis', ), ), 'borderradii' => array( 'items' => array(), 'title' => tra('Border Radii'), 'selector' => 'size', 'regexps' => array( 'find' => '/border(?:-[^\};]*)?-radius(?:-[^\};]*)?:[^\};]*('.$unit.')[\s;\}\!]/Umis', 'context' => '/'.$selector.'border(?:-.*)?:.*(?<![\da-f#])$0'.$delims.'/Umis', 'replace' => '/(border[^:]*:[^;\}]*)(?<![\da-f#])$0('.$delims.')/Umis', ), ), ), 'title' => tra('Borders'), ), 'typography' => array( 'types' => array( 'fontsize' => array( 'items' => array(), 'title' => tra('Font Sizes'), 'selector' => 'size', 'regexps' => array( 'find' => '/font-size:[^\};]*?('.$unit.')/i', 'context' => '/'.$selector.'font-size:\s*$0'.$delims.'/Umis', 'replace' => '/(font-size:\s*)$0('.$delims.')/Umis', ), ), 'lineheight' => array( 'items' => array(), 'title' => tra('Line Heights'), 'selector' => 'size', 'regexps' => array( 'find' => '/line-height:[^\};]*?('.$unit.')/i', 'context' => '/'.$selector.'line-height:\s*$0'.$delims.'/Umis', 'replace' => '/(line-height:\s*)$0('.$delims.')/Umis', ), ), 'font' => array( 'items' => array(), 'title' => tra('Font'), 'selector' => 'text', 'regexps' => array( 'find' => '/font:\s*?([^;\}]*)/i', 'context' => '/'.$selector.'font:\s*$0'.$delimn.'/Umis', 'replace' => '/(font:\s*)$0('.$delimn.')/Umis', ), ), 'fontfamily' => array( 'items' => array(), 'title' => tra('Font Families'), 'selector' => 'fontfamily', 'regexps' => array( 'find' => '/font-family:\s*?([^;\}]*)/i', 'context' => '/'.$selector.'font-family:\s*$0'.$delimn.'/Umis', 'replace' => '/(font-family:\s*)$0('.$delimn.')/Umis', ), ), ), 'title' => tra('Typography'), ), ); if (!empty($prefs['themegenerator_theme'])) { $t = $prefs['themegenerator_theme']; } else { $t = ''; } $this->currentTheme = new ThemeGenTheme($t); } public function setupEditor() { global $prefs; $headerlib = TikiLib::lib('header'); $smarty = TikiLib::lib('smarty'); $tikilib = TikiLib::lib('tiki'); if ($this->currentTheme->initDone || // filter out unnecessay setups strpos($_SERVER['SCRIPT_NAME'], 'tiki-download_file.php') !== false || strpos($_SERVER['SCRIPT_NAME'], 'tiki-ajax_services.php') !== false) { return; } // tiki themegen include $headerlib->add_jsfile('lib/jquery_tiki/tiki-themegenerator.js'); $headerlib->add_cssfile('themes/base_files/feature_css/admin.css'); // set up colorpicker $headerlib->add_cssfile('vendor/jquery/plugins/colorpicker/css/colorpicker.css'); $headerlib->add_cssfile('lib/jquery_tiki/colorpicker/layout.css'); $headerlib->add_jsfile('vendor/jquery/plugins/colorpicker/js/colorpicker.js'); // units converter $headerlib->add_jsfile('vendor/jquery/plugins/pxem/pxem.jQuery.js'); if (!empty($_COOKIE['themegen'])) { if (strpos($_COOKIE['themegen'], 'state:open') !== false) { $headerlib->add_jq_onready('openThemeGenDialog();', 100); } } else if (!empty($_SESSION['tg_preview'])) { // or remove preview session if no cookie unset($_SESSION['tg_preview']); } // if not admin/look page so add open dialog js or remove session and return if (strpos($_SERVER['SCRIPT_NAME'], 'tiki-admin.php') === false || strpos($_SERVER['QUERY_STRING'], 'page=look') === false) { return; } if (!empty($_SESSION['tg_preview'])) { $data = unserialize($_SESSION['tg_preview']); $this->currentTheme->setData($data); if (!empty($_SESSION['tg_css_file']) && empty($_REQUEST['tg_css_file'])) { $css_file = $_SESSION['tg_css_file']; } } else { $data = $this->currentTheme->loadPref(); } if (empty($css_file)) { if (!empty($_REQUEST['tg_css_file'])) { $css_file = $_REQUEST['tg_css_file']; } else if ($data) { $css_files = array_keys($data['files']); $css_file_found = false; foreach ( $css_files as $css_file) { foreach ( $headerlib->cssfiles as $files) { if (in_array($css_file, $files)) { $css_file_found = true; break 2; } } } if ( !$css_file_found ) { $css_file = $this->get_theme_css($prefs['theme']); } } else { $css_file = $this->get_theme_css($prefs['theme']); } } $mincss = $headerlib->minify_css($css_file); // clean out comments etc $mincss = '}' . preg_replace('/@import url(.*);/Umis', '', $mincss); foreach ($this->tg_data as $secName => &$secData) { foreach ($secData['types'] as $typeName => &$typeData) { $typeData['items'] = $this->currentTheme->findMatches($typeData['regexps']['find'], $mincss, $css_file, $typeName); $this->findContexts($typeData['items'], $mincss, $typeData['regexps']['context']); } } $smarty->assign_by_ref('tg_data', $this->tg_data); $tg_css_files = $this->setupCSSFiles(); $smarty->assign_by_ref('tg_css_files', $tg_css_files); $smarty->assign_by_ref('tg_css_file', $css_file); if (($_SERVER['REQUEST_METHOD'] == 'POST' && !empty($_REQUEST['tg_open_dialog']))) { $smarty->display('themegen.tpl'); die; } $this->currentTheme->initDone = true; } /** * @param $items * @param $haystack * @param $regexp */ private function findContexts( &$items, $haystack, $regexp) { $m = null; foreach ($items as &$item) { $c = preg_match_all(str_replace('$0', preg_quote(html_entity_decode($item['old']), '/'), $regexp), $haystack, $m); if ($c) { $item['contexts'] = htmlentities('<ul class="tgContexts"><li>' . implode('</li><li>', str_replace(',', ',<br />', $m[1])) . '</li></ul>'); } else { $item['contexts'] = '<ul><li>Not found (error)</li></ul>'; } } } /** * @return array */ public function setupCSSFiles () { global $prefs; $themelib = TikiLib::lib('theme'); $css_files = array('' => tra('Select...')); if (!empty($prefs['theme_option']) && $prefs['theme_option'] !== tra('None')) { $css_files[$themelib->get_theme_css($prefs['theme'], $prefs['theme_option'])] = $prefs['theme_option']; } $css_files[$themelib->get_theme_css($prefs['theme'])] = $prefs['theme']; return $css_files; } /** * @param $file * @param $swaps * @return mixed|string */ public function processCSSFile($file, $swaps) { $headerlib = TikiLib::lib('header'); $css = $headerlib->minify_css($file); foreach ($this->tg_data as $secName => &$secData) { foreach ($secData['types'] as $typeName => &$typeData) { if (isset($swaps[$typeName])) { foreach ($swaps[$typeName] as $old => $new) { $reg = str_replace('$0', preg_quote($old, '/'), $typeData['regexps']['replace']); if (!in_array($typeName, array( 'bordercolors' ))) { $css = preg_replace($reg, '$1 ' . html_entity_decode($new) . '$2', $css); } else { $GLOBALS['tg_old'] = $old; // for preg_replace_callback on php < 5.3file_get_contents $GLOBALS['tg_new'] = html_entity_decode($new); $css = preg_replace_callback($reg, array( $this, 'processCSSMultiVars'), $css); } } } } } // still need to deal with multi colour border defs // foreach ($swaps['bordercolors'] as $old => $new) { // $GLOBALS['tg_old'] = $old; // for preg_replace_callback on php < 5.3 // $GLOBALS['tg_new'] = $new; // $css = preg_replace_callback('/(border[^:]*:\s*)(.*)([;\}])/Umis', array( $this, 'processCSSColours'), $css); // } return $css; } /** * @param $matches * @return mixed */ private function processCSSMultiVars($matches) { $out = str_replace($GLOBALS['tg_old'], $GLOBALS['tg_new'], $matches[0]); return $out; } /** * @param $name */ public function saveNewTheme($name) { $headerlib = TikiLib::lib('header'); $headerlib->remove_themegen_files(); $this->currentTheme = new ThemeGenTheme($name); $this->currentTheme->savePref(); if (!empty($_SESSION['tg_preview'])) { unset($_SESSION['tg_preview']); } } /** * @param $css_file * @param $swaps */ public function updateCurrentTheme($css_file, $swaps) { $headerlib = TikiLib::lib('header'); $headerlib->remove_themegen_files(); $this->currentTheme->setData(array($swaps, $css_file)); $this->currentTheme->savePref(); if (!empty($_SESSION['tg_preview'])) { unset($_SESSION['tg_preview']); } } /** * @param $css_file * @param $swaps */ public function previewCurrentTheme($css_file, $swaps) { $this->currentTheme->setData(array($swaps, $css_file)); $_SESSION['tg_preview'] = serialize($this->currentTheme->getData()); $_SESSION['tg_css_file'] = $css_file; //$this->currentTheme->savePref(); } public function deleteCurrentTheme() { global $tikilib; if ($this-currentTheme) { $tikilib->set_preference('themegenerator_theme', ''); $this->currentTheme->deletePref(); } } /** * @return ThemeGenTheme */ public function getCurrentTheme() { return $this->currentTheme; } } require_once 'lib/serializedlist.php'; /** * */ class ThemeGenTheme extends SerializedList { public $initDone; /** * @param string $name */ public function __construct($name) { parent::__construct($name); } public function initData() { global $prefs; $this->data = array( 'files' => array(), 'theme' => $prefs['theme'], 'theme_option' => '', //$prefs['theme_option'], ); $this->initDone = false; } public function initPrefPrefix() { $this->prefPrefix = 'themegenerator_theme_'; } /** * @param $params */ public function setData($params) { global $prefs; list($swaps, $css_file) = $params; if (!$swaps && !$css_file && isset($params['files'])) { $this->data = $params; return; } if (!isset($this->data['files'][$css_file])) { $this->data['files'][$css_file] = array(); } foreach ($swaps as $type => $swaps2) { $this->data['files'][$css_file][$type] = array(); foreach ($swaps2 as $kswap => $swap) { if ($kswap !== $swap) { $this->data['files'][$css_file][$type][htmlentities($kswap)] = htmlentities($swap); } } } $this->data['theme'] = $prefs['theme']; if ( in_array($prefs['theme_option'], array_keys($this->data['files']))) { $this->data['theme_option'] = $prefs['theme_option']; } else { $this->data['theme_option'] = ''; } } /** * @param $regexp * @param $haystack * @param $filename * @param $type * @param bool $lower * @param int $matchNumber * @return array|null */ public function findMatches( $regexp, $haystack, $filename, $type, $lower = true, $matchNumber = 1) { $items = null; preg_match_all($regexp, $haystack, $matches); if (count($matches) > $matchNumber && count($matchNumber) > 0) { $items = $this->processMatches($matches[$matchNumber], $filename, $type, $lower); } return $items; } /** * @param $matches * @param $css_file * @param $type * @param $lower * @return array */ private function processMatches($matches, $css_file, $type, $lower) { $processed = array(); if (is_array($matches)) { $matches = array_map('trim', $matches); if ($lower) { $matches = array_map('strtolower', $matches); } $matches = array_unique($matches); // Deal with multiple border colours (widths, styles and radii still TODO but not used in tiki CSS afaik) foreach ($matches as &$m) { if (strpos($m, ' ') && in_array($type, array('bordercolors'))) { $arr = explode(' ', $m); foreach ( $arr as $a ) { if (!in_array($a, $matches)) { $matches[] = $a; } } $m = ''; } } $matches = array_filter($matches); sort($matches); foreach ($matches as $match) { $match = htmlentities($match); $processed[$match] = array(); $processed[$match]['old'] = $match; if (isset($this->data['files'][$css_file][$type][$match])) { $processed[$match]['new'] = $this->data['files'][$css_file][$type][$match]; } else { $processed[$match]['new'] = $match; } } } return $processed; } } global $themegenlib; $themegenlib = new ThemeGenLib();