918 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			918 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| require_once('global.php');
 | |
| require_once(CRAYON_PARSER_PHP);
 | |
| require_once(CRAYON_THEMES_PHP);
 | |
| 
 | |
| /**
 | |
|  * Stores CrayonSetting objects.
 | |
|  * Each Crayon instance stores an instance of this class containing its specific settings.
 | |
|  */
 | |
| class CrayonSettings {
 | |
|     // Properties and Constants ===============================================
 | |
|     const INVALID = -1; // Used for invalid dropdown index
 | |
|     // Plugin data
 | |
|     const VERSION = 'version';
 | |
| 
 | |
|     // Added when used in HTML to avoid id conflicts
 | |
|     const PREFIX = 'crayon-';
 | |
|     const SETTING = 'crayon-setting';
 | |
|     const SETTING_SELECTED = 'crayon-setting-selected';
 | |
|     const SETTING_CHANGED = 'crayon-setting-changed';
 | |
|     const SETTING_SPECIAL = 'crayon-setting-special';
 | |
|     const SETTING_ORIG_VALUE = 'data-orig-value';
 | |
| 
 | |
|     // Global names for settings
 | |
|     const THEME = 'theme';
 | |
|     const FONT = 'font';
 | |
|     const FONT_SIZE_ENABLE = 'font-size-enable';
 | |
|     const FONT_SIZE = 'font-size';
 | |
|     const LINE_HEIGHT = 'line-height';
 | |
|     const PREVIEW = 'preview';
 | |
|     const HEIGHT_SET = 'height-set';
 | |
|     const HEIGHT_MODE = 'height-mode';
 | |
|     const HEIGHT = 'height';
 | |
|     const HEIGHT_UNIT = 'height-unit';
 | |
|     const WIDTH_SET = 'width-set';
 | |
|     const WIDTH_MODE = 'width-mode';
 | |
|     const WIDTH = 'width';
 | |
|     const WIDTH_UNIT = 'width-unit';
 | |
|     const TOP_SET = 'top-set';
 | |
|     const TOP_MARGIN = 'top-margin';
 | |
|     const LEFT_SET = 'left-set';
 | |
|     const LEFT_MARGIN = 'left-margin';
 | |
|     const BOTTOM_SET = 'bottom-set';
 | |
|     const BOTTOM_MARGIN = 'bottom-margin';
 | |
|     const RIGHT_SET = 'right-set';
 | |
|     const RIGHT_MARGIN = 'right-margin';
 | |
|     const H_ALIGN = 'h-align';
 | |
|     const FLOAT_ENABLE = 'float-enable';
 | |
|     const TOOLBAR = 'toolbar';
 | |
|     const TOOLBAR_OVERLAY = 'toolbar-overlay';
 | |
|     const TOOLBAR_HIDE = 'toolbar-hide';
 | |
|     const TOOLBAR_DELAY = 'toolbar-delay';
 | |
|     const COPY = 'copy';
 | |
|     const POPUP = 'popup';
 | |
|     const SHOW_LANG = 'show-lang';
 | |
|     const SHOW_TITLE = 'show-title';
 | |
|     const STRIPED = 'striped';
 | |
|     const MARKING = 'marking';
 | |
|     const START_LINE = 'start-line';
 | |
|     const NUMS = 'nums';
 | |
|     const NUMS_TOGGLE = 'nums-toggle';
 | |
|     const TRIM_WHITESPACE = 'trim-whitespace';
 | |
|     const WHITESPACE_BEFORE = 'whitespace-before';
 | |
|     const WHITESPACE_AFTER = 'whitespace-after';
 | |
|     const TRIM_CODE_TAG = 'trim-code-tag';
 | |
|     const TAB_SIZE = 'tab-size';
 | |
|     const TAB_CONVERT = 'tab-convert';
 | |
|     const FALLBACK_LANG = 'fallback-lang';
 | |
|     const LOCAL_PATH = 'local-path';
 | |
|     const SCROLL = 'scroll';
 | |
|     const PLAIN = 'plain';
 | |
|     const PLAIN_TOGGLE = 'plain-toggle';
 | |
|     const SHOW_PLAIN = 'show-plain';
 | |
|     const DISABLE_RUNTIME = 'runtime';
 | |
|     const DISABLE_DATE = 'disable-date';
 | |
|     const TOUCHSCREEN = 'touchscreen';
 | |
|     const DISABLE_ANIM = 'disable-anim';
 | |
|     const ERROR_LOG = 'error-log';
 | |
|     const ERROR_LOG_SYS = 'error-log-sys';
 | |
|     const ERROR_MSG_SHOW = 'error-msg-show';
 | |
|     const ERROR_MSG = 'error-msg';
 | |
|     const HIDE_HELP = 'hide-help';
 | |
|     const CACHE = 'cache';
 | |
|     const EFFICIENT_ENQUEUE = 'efficient-enqueue';
 | |
|     const CAPTURE_PRE = 'capture-pre';
 | |
|     const CAPTURE_MINI_TAG = 'capture-mini-tag';
 | |
|     const MIXED = 'mixed';
 | |
|     const SHOW_MIXED = 'show_mixed';
 | |
|     const PLAIN_TAG = 'plain_tag';
 | |
|     const SHOW_PLAIN_DEFAULT = 'show-plain-default';
 | |
|     const ENQUEUE_THEMES = 'enqueque-themes';
 | |
|     const ENQUEUE_FONTS = 'enqueque-fonts';
 | |
|     const MAIN_QUERY = 'main-query';
 | |
|     const SAFE_ENQUEUE = 'safe-enqueue';
 | |
|     const INLINE_TAG = 'inline-tag';
 | |
|     const INLINE_TAG_CAPTURE = 'inline-tag-capture';
 | |
|     const CODE_TAG_CAPTURE = 'code-tag-capture';
 | |
|     const CODE_TAG_CAPTURE_TYPE = 'code-tag-capture-type';
 | |
|     const INLINE_MARGIN = 'inline-margin';
 | |
|     const INLINE_WRAP = 'inline-wrap';
 | |
|     const BACKQUOTE = 'backquote';
 | |
|     const COMMENTS = 'comments';
 | |
|     const DECODE = 'decode';
 | |
|     const DECODE_ATTRIBUTES = 'decode-attributes';
 | |
| // 	const TINYMCE_USED = 'tinymce-used';
 | |
|     const ATTR_SEP = 'attr-sep';
 | |
|     const EXCERPT_STRIP = 'excerpt-strip';
 | |
|     const RANGES = 'ranges';
 | |
|     const TAG_EDITOR_FRONT = 'tag-editor-front';
 | |
|     const TAG_EDITOR_SETTINGS = 'tag-editor-front-hide';
 | |
|     const TAG_EDITOR_ADD_BUTTON_TEXT = 'tag-editor-button-add-text';
 | |
|     const TAG_EDITOR_EDIT_BUTTON_TEXT = 'tag-editor-button-edit-text';
 | |
|     const TAG_EDITOR_QUICKTAG_BUTTON_TEXT = 'tag-editor-quicktag-button-text';
 | |
|     const WRAP_TOGGLE = 'wrap-toggle';
 | |
|     const WRAP = 'wrap';
 | |
|     const EXPAND = 'expand';
 | |
|     const EXPAND_TOGGLE = 'expand-toggle';
 | |
|     const MINIMIZE = 'minimize';
 | |
|     const IGNORE = 'ignore';
 | |
|     const DELAY_LOAD_JS = 'delay-load-js';
 | |
| 
 | |
|     private static $cache_array;
 | |
| 
 | |
|     public static function get_cache_sec($cache) {
 | |
|         $values = array_values(self::$cache_array);
 | |
|         if (array_key_exists($cache, $values)) {
 | |
|             return $values[$cache];
 | |
|         } else {
 | |
|             return $values[0];
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // The current settings, should be loaded with default if none exists
 | |
|     private $settings = array();
 | |
| 
 | |
|     // The settings with default values
 | |
|     private static $default = NULL;
 | |
| 
 | |
|     function __construct() {
 | |
|         $this->init();
 | |
|     }
 | |
| 
 | |
|     function copy() {
 | |
|         $settings = new CrayonSettings();
 | |
|         foreach ($this->settings as $setting) {
 | |
|             $settings->set($setting); // Overuse of set?
 | |
|         }
 | |
|         return $settings;
 | |
|     }
 | |
| 
 | |
|     // Methods ================================================================
 | |
| 
 | |
|     private function init() {
 | |
|         global $CRAYON_VERSION;
 | |
| 
 | |
|         crayon_load_plugin_textdomain();
 | |
| 
 | |
|         self::$cache_array = array(crayon__('Hourly') => 3600, crayon__('Daily') => 86400,
 | |
|             crayon__('Weekly') => 604800, crayon__('Monthly') => 18144000,
 | |
|             crayon__('Immediately') => 1);
 | |
| 
 | |
|         $settings = array(
 | |
|             new CrayonSetting(self::VERSION, $CRAYON_VERSION, NULL, TRUE),
 | |
|             new CrayonSetting(self::THEME, CrayonThemes::DEFAULT_THEME),
 | |
|             new CrayonSetting(self::FONT, CrayonFonts::DEFAULT_FONT),
 | |
|             new CrayonSetting(self::FONT_SIZE_ENABLE, TRUE),
 | |
|             new CrayonSetting(self::FONT_SIZE, 12),
 | |
|             new CrayonSetting(self::LINE_HEIGHT, 15),
 | |
|             new CrayonSetting(self::PREVIEW, TRUE),
 | |
|             new CrayonSetting(self::HEIGHT_SET, FALSE),
 | |
|             new CrayonSetting(self::HEIGHT_MODE, array(crayon__('Max'), crayon__('Min'), crayon__('Static'))),
 | |
|             new CrayonSetting(self::HEIGHT, '500'),
 | |
|             new CrayonSetting(self::HEIGHT_UNIT, array(crayon__('Pixels'), crayon__('Percent'))),
 | |
|             new CrayonSetting(self::WIDTH_SET, FALSE),
 | |
|             new CrayonSetting(self::WIDTH_MODE, array(crayon__('Max'), crayon__('Min'), crayon__('Static'))),
 | |
|             new CrayonSetting(self::WIDTH, '500'),
 | |
|             new CrayonSetting(self::WIDTH_UNIT, array(crayon__('Pixels'), crayon__('Percent'))),
 | |
|             new CrayonSetting(self::TOP_SET, TRUE),
 | |
|             new CrayonSetting(self::TOP_MARGIN, 12),
 | |
|             new CrayonSetting(self::BOTTOM_SET, TRUE),
 | |
|             new CrayonSetting(self::BOTTOM_MARGIN, 12),
 | |
|             new CrayonSetting(self::LEFT_SET, FALSE),
 | |
|             new CrayonSetting(self::LEFT_MARGIN, 12),
 | |
|             new CrayonSetting(self::RIGHT_SET, FALSE),
 | |
|             new CrayonSetting(self::RIGHT_MARGIN, 12),
 | |
|             new CrayonSetting(self::H_ALIGN, array(crayon__('None'), crayon__('Left'), crayon__('Center'), crayon__('Right'))),
 | |
|             new CrayonSetting(self::FLOAT_ENABLE, FALSE),
 | |
|             new CrayonSetting(self::TOOLBAR, array(crayon__('On MouseOver'), crayon__('Always'), crayon__('Never'))),
 | |
|             new CrayonSetting(self::TOOLBAR_OVERLAY, TRUE),
 | |
|             new CrayonSetting(self::TOOLBAR_HIDE, TRUE),
 | |
|             new CrayonSetting(self::TOOLBAR_DELAY, TRUE),
 | |
|             new CrayonSetting(self::COPY, TRUE),
 | |
|             new CrayonSetting(self::POPUP, TRUE),
 | |
|             new CrayonSetting(self::SHOW_LANG, array(crayon__('When Found'), crayon__('Always'), crayon__('Never'))),
 | |
|             new CrayonSetting(self::SHOW_TITLE, TRUE),
 | |
|             new CrayonSetting(self::STRIPED, TRUE),
 | |
|             new CrayonSetting(self::MARKING, TRUE),
 | |
|             new CrayonSetting(self::START_LINE, 1),
 | |
|             new CrayonSetting(self::NUMS, TRUE),
 | |
|             new CrayonSetting(self::NUMS_TOGGLE, TRUE),
 | |
|             new CrayonSetting(self::TRIM_WHITESPACE, TRUE),
 | |
|             new CrayonSetting(self::WHITESPACE_BEFORE, 0),
 | |
|             new CrayonSetting(self::WHITESPACE_AFTER, 0),
 | |
|             new CrayonSetting(self::TRIM_CODE_TAG, TRUE),
 | |
|             new CrayonSetting(self::TAB_CONVERT, FALSE),
 | |
|             new CrayonSetting(self::TAB_SIZE, 4),
 | |
|             new CrayonSetting(self::FALLBACK_LANG, CrayonLangs::DEFAULT_LANG),
 | |
|             new CrayonSetting(self::LOCAL_PATH, ''),
 | |
|             new CrayonSetting(self::SCROLL, FALSE),
 | |
|             new CrayonSetting(self::PLAIN, TRUE),
 | |
|             new CrayonSetting(self::PLAIN_TOGGLE, TRUE),
 | |
|             new CrayonSetting(self::SHOW_PLAIN_DEFAULT, FALSE),
 | |
|             new CrayonSetting(self::SHOW_PLAIN,
 | |
|                 array(crayon__('On Double Click'), crayon__('On Single Click'), crayon__('On MouseOver'), crayon__('Disable Mouse Events'))),
 | |
|             new CrayonSetting(self::DISABLE_ANIM, FALSE),
 | |
|             new CrayonSetting(self::TOUCHSCREEN, TRUE),
 | |
|             new CrayonSetting(self::DISABLE_RUNTIME, FALSE),
 | |
|             new CrayonSetting(self::DISABLE_DATE, ''),
 | |
|             new CrayonSetting(self::ERROR_LOG, TRUE),
 | |
|             new CrayonSetting(self::ERROR_LOG_SYS, TRUE),
 | |
|             new CrayonSetting(self::ERROR_MSG_SHOW, TRUE),
 | |
|             new CrayonSetting(self::ERROR_MSG, crayon__('An error has occurred. Please try again later.')),
 | |
|             new CrayonSetting(self::HIDE_HELP, FALSE),
 | |
|             new CrayonSetting(self::CACHE, array_keys(self::$cache_array), 1),
 | |
|             new CrayonSetting(self::EFFICIENT_ENQUEUE, FALSE),
 | |
|             new CrayonSetting(self::CAPTURE_PRE, TRUE),
 | |
|             new CrayonSetting(self::CAPTURE_MINI_TAG, FALSE),
 | |
|             new CrayonSetting(self::MIXED, TRUE),
 | |
|             new CrayonSetting(self::SHOW_MIXED, TRUE),
 | |
|             new CrayonSetting(self::PLAIN_TAG, FALSE),
 | |
|             new CrayonSetting(self::ENQUEUE_THEMES, TRUE),
 | |
|             new CrayonSetting(self::ENQUEUE_FONTS, TRUE),
 | |
|             new CrayonSetting(self::MAIN_QUERY, FALSE),
 | |
|             new CrayonSetting(self::SAFE_ENQUEUE, TRUE),
 | |
|             new CrayonSetting(self::INLINE_TAG, TRUE),
 | |
|             new CrayonSetting(self::INLINE_TAG_CAPTURE, FALSE),
 | |
|             new CrayonSetting(self::CODE_TAG_CAPTURE, FALSE),
 | |
|             new CrayonSetting(self::CODE_TAG_CAPTURE_TYPE, array(crayon__('Inline Tag'), crayon__('Block Tag'))),
 | |
|             new CrayonSetting(self::INLINE_MARGIN, 5),
 | |
|             new CrayonSetting(self::INLINE_WRAP, TRUE),
 | |
|             new CrayonSetting(self::BACKQUOTE, TRUE),
 | |
|             new CrayonSetting(self::COMMENTS, TRUE),
 | |
|             new CrayonSetting(self::DECODE, FALSE),
 | |
|             new CrayonSetting(self::DECODE_ATTRIBUTES, TRUE),
 | |
| // 			new CrayonSetting(self::TINYMCE_USED, FALSE),
 | |
|             new CrayonSetting(self::ATTR_SEP, array(':', '_')),
 | |
|             new CrayonSetting(self::EXCERPT_STRIP, FALSE),
 | |
|             new CrayonSetting(self::RANGES, TRUE),
 | |
|             new CrayonSetting(self::TAG_EDITOR_FRONT, FALSE),
 | |
|             new CrayonSetting(self::TAG_EDITOR_SETTINGS, TRUE),
 | |
|             new CrayonSetting(self::TAG_EDITOR_ADD_BUTTON_TEXT, crayon__('Add Code')),
 | |
|             new CrayonSetting(self::TAG_EDITOR_EDIT_BUTTON_TEXT, crayon__('Edit Code')),
 | |
|             new CrayonSetting(self::TAG_EDITOR_QUICKTAG_BUTTON_TEXT, 'crayon'),
 | |
|             new CrayonSetting(self::WRAP_TOGGLE, TRUE),
 | |
|             new CrayonSetting(self::WRAP, FALSE),
 | |
|             new CrayonSetting(self::EXPAND, FALSE),
 | |
|             new CrayonSetting(self::EXPAND_TOGGLE, TRUE),
 | |
|             new CrayonSetting(self::MINIMIZE, FALSE),
 | |
|             new CrayonSetting(self::DELAY_LOAD_JS, FALSE)
 | |
|         );
 | |
| 
 | |
|         $this->set($settings);
 | |
| 
 | |
|         $nonNegs = array(self::FONT_SIZE, self::LINE_HEIGHT, self::HEIGHT, self::WIDTH, self::START_LINE, self::WHITESPACE_BEFORE, self::WHITESPACE_AFTER, self::TAB_SIZE, self::INLINE_MARGIN);
 | |
|         $intNonNegValid = new CrayonNonNegIntValidator();
 | |
|         foreach ($nonNegs as $name) {
 | |
|             $this->get($name)->validator($intNonNegValid);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // Getter and Setter ======================================================
 | |
| 
 | |
|     // TODO this needs simplification
 | |
|     function set($name, $value = NULL, $replace = FALSE) {
 | |
|         // Set associative array of settings
 | |
|         if (is_array($name)) {
 | |
|             $keys = array_keys($name);
 | |
|             foreach ($keys as $key) {
 | |
|                 if (is_string($key)) {
 | |
|                     // Associative value
 | |
|                     $this->set($key, $name[$key], $replace);
 | |
|                 } else if (is_int($key)) {
 | |
|                     $setting = $name[$key];
 | |
|                     $this->set($setting, NULL, $replace);
 | |
|                 }
 | |
|             }
 | |
|         } else if (is_string($name) && !empty($name) && $value !== NULL) {
 | |
|             $value = CrayonSettings::validate($name, $value);
 | |
|             if ($replace || !$this->is_setting($name)) {
 | |
|                 // Replace/Create
 | |
|                 $this->settings[$name] = new CrayonSetting($name, $value);
 | |
|             } else {
 | |
|                 // Update
 | |
|                 $this->settings[$name]->value($value);
 | |
|             }
 | |
|         } else if (is_object($name) && get_class($name) == CRAYON_SETTING_CLASS) {
 | |
|             $setting = $name; // Semantics
 | |
|             if ($replace || !$this->is_setting($setting->name())) {
 | |
|                 // Replace/Create
 | |
|                 $this->settings[$setting->name()] = $setting->copy();
 | |
|             } else {
 | |
|                 // Update
 | |
|                 if ($setting->is_array()) {
 | |
|                     $this->settings[$setting->name()]->index($setting->index());
 | |
|                 } else {
 | |
|                     $this->settings[$setting->name()]->value($setting->value());
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     function get($name = NULL) {
 | |
|         if ($name === NULL) {
 | |
|             $copy = array();
 | |
|             foreach ($this->settings as $name => $setting) {
 | |
|                 $copy[$name] = $setting->copy(); // Deep copy
 | |
|             }
 | |
|             return $copy;
 | |
|         } else if (is_string($name)) {
 | |
|             if ($this->is_setting($name)) {
 | |
|                 return $this->settings[$name];
 | |
|             }
 | |
|         }
 | |
|         return FALSE;
 | |
|     }
 | |
| 
 | |
|     function val($name = NULL) {
 | |
|         if (($setting = self::get($name)) != FALSE) {
 | |
|             return $setting->value();
 | |
|         } else {
 | |
|             return NULL;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     function val_str($name) {
 | |
|         if (($setting = self::get($name)) != FALSE) {
 | |
|             $def = $setting->def();
 | |
|             $index = $setting->value();
 | |
|             if (array_key_exists($index, $def)) {
 | |
|                 return $def[$index];
 | |
|             } else {
 | |
|                 return NULL;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     function get_array() {
 | |
|         $array = array();
 | |
|         foreach ($this->settings as $setting) {
 | |
|             $array[$setting->name()] = $setting->value();
 | |
|         }
 | |
|         return $array;
 | |
|     }
 | |
| 
 | |
|     function is_setting($name) {
 | |
|         return (is_string($name) && array_key_exists($name, $this->settings));
 | |
|     }
 | |
| 
 | |
|     /* Gets default settings, either as associative array of name=>value or CrayonSetting
 | |
|      objects */
 | |
|     public static function get_defaults($name = NULL, $objects = TRUE) {
 | |
|         if (self::$default === NULL) {
 | |
|             self::$default = new CrayonSettings();
 | |
|         }
 | |
|         if ($name === NULL) {
 | |
|             // Get all settings
 | |
|             if ($objects) {
 | |
|                 // Return array of objects
 | |
|                 return self::$default->get();
 | |
|             } else {
 | |
|                 // Return associative array of name=>value
 | |
|                 $settings = self::$default->get();
 | |
|                 $defaults = array();
 | |
|                 foreach ($settings as $setting) {
 | |
|                     $defaults[$setting->name()] = $setting->value();
 | |
|                 }
 | |
|                 return $defaults;
 | |
|             }
 | |
|         } else {
 | |
|             // Return specific setting
 | |
|             if ($objects) {
 | |
|                 return self::$default->get($name);
 | |
|             } else {
 | |
|                 return self::$default->get($name)->value();
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public static function get_defaults_array() {
 | |
|         return self::get_defaults(NULL, FALSE);
 | |
|     }
 | |
| 
 | |
|     // Validation =============================================================
 | |
| 
 | |
|     /**
 | |
|      * Validates settings coming from an HTML form and also for internal use.
 | |
|      * This is used when saving form an HTML form to the db, and also when reading from the db
 | |
|      * back into the global settings.
 | |
|      * @param string $name
 | |
|      * @param mixed $value
 | |
|      */
 | |
|     public static function validate($name, $value) {
 | |
|         if (!is_string($name)) {
 | |
|             return '';
 | |
|         }
 | |
| 
 | |
|         // Type-cast to correct value for known settings
 | |
|         if (($setting = CrayonGlobalSettings::get($name)) != FALSE) {
 | |
|             // Booleans settings that are sent as string are allowed to have "false" == false
 | |
|             if (is_bool($setting->def())) {
 | |
|                 if (is_string($value)) {
 | |
|                     $value = CrayonUtil::str_to_bool($value);
 | |
|                 }
 | |
|             } else {
 | |
|                 // Ensure we don't cast integer settings to 0 because $value doesn't have any numbers in it
 | |
|                 $value = strval($value);
 | |
|                 // Only occurs when saving from the form ($_POST values are strings)
 | |
|                 if ($value == '' || ($cleaned = $setting->sanitize($value, FALSE)) == '') {
 | |
|                     // The value sent has no integers, change to default
 | |
|                     $value = $setting->def();
 | |
|                 } else {
 | |
|                     // Cleaned value is int
 | |
|                     $value = $cleaned;
 | |
|                 }
 | |
|                 // Cast all other settings as usual
 | |
|                 if (!settype($value, $setting->type())) {
 | |
|                     // If we can't cast, then use default value
 | |
|                     if ($setting->is_array()) {
 | |
|                         $value = 0; // default index
 | |
|                     } else {
 | |
|                         $value = $setting->def();
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         } else {
 | |
|             // If setting not found, remove value
 | |
|             return '';
 | |
|         }
 | |
| 
 | |
|         switch ($name) {
 | |
|             case CrayonSettings::LOCAL_PATH:
 | |
|                 $path = parse_url($value, PHP_URL_PATH);
 | |
|                 // Remove all spaces, prefixed and trailing forward slashes
 | |
|                 $path = preg_replace('#^/*|/*$|\s*#', '', $path);
 | |
|                 // Replace backslashes
 | |
|                 $path = preg_replace('#\\\\#', '/', $path);
 | |
|                 // Append trailing forward slash
 | |
|                 if (!empty($path)) {
 | |
|                     $path .= '/';
 | |
|                 }
 | |
|                 return $path;
 | |
|             case CrayonSettings::FONT_SIZE:
 | |
|                 if ($value < 1) {
 | |
|                     $value = 1;
 | |
|                 }
 | |
|                 break;
 | |
|             case CrayonSettings::LINE_HEIGHT:
 | |
|                 $font_size = CrayonGlobalSettings::val(CrayonSettings::FONT_SIZE);
 | |
|                 $value = $value >= $font_size ? $value : $font_size;
 | |
|                 break;
 | |
|             case CrayonSettings::THEME:
 | |
|                 $value = strtolower($value);
 | |
|             // XXX validate settings here
 | |
|         }
 | |
| 
 | |
|         // If no validation occurs, return value
 | |
|         return $value;
 | |
|     }
 | |
| 
 | |
|     // Takes an associative array of "smart settings" and regular settings. Smart settings can be used
 | |
|     // to configure regular settings quickly.
 | |
|     // E.g. 'max_height="20px"' will set 'height="20"', 'height_mode="0", height_unit="0"'
 | |
|     public static function smart_settings($settings) {
 | |
|         if (!is_array($settings)) {
 | |
|             return FALSE;
 | |
|         }
 | |
| 
 | |
|         // If a setting is given, it is automatically enabled
 | |
|         foreach ($settings as $name => $value) {
 | |
|             if (($setting = CrayonGlobalSettings::get($name)) !== FALSE && is_bool($setting->def())) {
 | |
|                 $value = CrayonUtil::str_to_bool($value);
 | |
|             }
 | |
| 
 | |
|             // XXX removed height and width, since it wasn't using the global settings for mode if only height was provided
 | |
|             if ($name == 'min-height' || $name == 'max-height' /* || $name == 'height'*/) {
 | |
|                 self::smart_hw($name, CrayonSettings::HEIGHT_SET, CrayonSettings::HEIGHT_MODE, CrayonSettings::HEIGHT_UNIT, $settings);
 | |
|             } else if ($name == 'min-width' || $name == 'max-width' /* || $name == 'width'*/) {
 | |
|                 self::smart_hw($name, CrayonSettings::WIDTH_SET, CrayonSettings::WIDTH_MODE, CrayonSettings::WIDTH_UNIT, $settings);
 | |
|             } else if ($name == CrayonSettings::FONT_SIZE) {
 | |
|                 $settings[CrayonSettings::FONT_SIZE_ENABLE] = TRUE;
 | |
|             } else if ($name == CrayonSettings::TOP_MARGIN) {
 | |
|                 $settings[CrayonSettings::TOP_SET] = TRUE;
 | |
|             } else if ($name == CrayonSettings::LEFT_MARGIN) {
 | |
|                 $settings[CrayonSettings::LEFT_SET] = TRUE;
 | |
|             } else if ($name == CrayonSettings::BOTTOM_MARGIN) {
 | |
|                 $settings[CrayonSettings::BOTTOM_SET] = TRUE;
 | |
|             } else if ($name == CrayonSettings::RIGHT_MARGIN) {
 | |
|                 $settings[CrayonSettings::RIGHT_SET] = TRUE;
 | |
|             } else if ($name == CrayonSettings::ERROR_MSG) {
 | |
|                 $settings[CrayonSettings::ERROR_MSG_SHOW] = TRUE;
 | |
|             } else if ($name == CrayonSettings::H_ALIGN) {
 | |
|                 $settings[CrayonSettings::FLOAT_ENABLE] = TRUE;
 | |
|                 $value = CrayonUtil::tlower($value);
 | |
|                 $values = array('none' => 0, 'left' => 1, 'center' => 2, 'right' => 3);
 | |
|                 if (array_key_exists($value, $values)) {
 | |
|                     $settings[CrayonSettings::H_ALIGN] = $values[$value];
 | |
|                 }
 | |
|             } else if ($name == CrayonSettings::SHOW_LANG) {
 | |
|                 $value = CrayonUtil::tlower($value);
 | |
|                 $values = array('found' => 0, 'always' => 1, 'true' => 1, 'never' => 2, 'false' => 2);
 | |
|                 if (array_key_exists($value, $values)) {
 | |
|                     $settings[CrayonSettings::SHOW_LANG] = $values[$value];
 | |
|                 }
 | |
|             } else if ($name == CrayonSettings::TOOLBAR) {
 | |
|                 if (CrayonUtil::tlower($value) == 'always') {
 | |
|                     $settings[CrayonSettings::TOOLBAR] = 1;
 | |
|                 } else if (CrayonUtil::str_to_bool($value) === FALSE) {
 | |
|                     $settings[CrayonSettings::TOOLBAR] = 2;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return $settings;
 | |
|     }
 | |
| 
 | |
|     // Used for height and width smart settings, I couldn't bear to copy paste code twice...
 | |
|     private static function smart_hw($name, $set, $mode, $unit, &$settings) {
 | |
|         if (!is_string($name) || !is_string($set) || !is_string($mode) || !is_string($unit) || !is_array($settings)) {
 | |
|             return;
 | |
|         }
 | |
|         $settings[$set] = TRUE;
 | |
|         if (strpos($name, 'max-') !== FALSE) {
 | |
|             $settings[$mode] = 0;
 | |
|         } else if (strpos($name, 'min-') !== FALSE) {
 | |
|             $settings[$mode] = 1;
 | |
|         } else {
 | |
|             $settings[$mode] = 2;
 | |
|         }
 | |
|         preg_match('#(\d+)\s*([^\s]*)#', $settings[$name], $match);
 | |
|         if (count($match) == 3) {
 | |
|             $name = str_replace(array('max-', 'min-'), '', $name);
 | |
|             $settings[$name] = $match[1];
 | |
|             switch (strtolower($match[2])) {
 | |
|                 case 'px':
 | |
|                     $settings[$unit] = 0;
 | |
|                     break;
 | |
|                 case '%':
 | |
|                     $settings[$unit] = 1;
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Stores global/static copy of CrayonSettings loaded from db.
 | |
|  * These settings can be overriden by individual Crayons.
 | |
|  * Also manages global site settings and paths.
 | |
|  */
 | |
| class CrayonGlobalSettings {
 | |
|     // The global settings stored as a CrayonSettings object.
 | |
|     private static $global = NULL;
 | |
|     /* These are used to load local files reliably and prevent scripts like PHP from executing
 | |
|      when attempting to load their code. */
 | |
|     // The URL of the site (eg. http://localhost/example/)
 | |
|     private static $site_http = '';
 | |
|     // The absolute root directory of the site (eg. /User/example/)
 | |
|     private static $site_path = '';
 | |
|     // The absolute root directory of the plugins (eg. /User/example/plugins)
 | |
|     private static $plugin_path = '';
 | |
|     private static $upload_path = '';
 | |
|     private static $upload_url = '';
 | |
|     private static $mkdir = NULL;
 | |
| 
 | |
|     private function __construct() {
 | |
|     }
 | |
| 
 | |
|     private static function init() {
 | |
|         if (self::$global === NULL) {
 | |
|             self::$global = new CrayonSettings();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public static function get($name = NULL) {
 | |
|         self::init();
 | |
|         return self::$global->get($name);
 | |
|     }
 | |
| 
 | |
|     public static function get_array() {
 | |
|         self::init();
 | |
|         return self::$global->get_array();
 | |
|     }
 | |
| 
 | |
|     public static function get_obj() {
 | |
|         self::init();
 | |
|         return self::$global->copy();
 | |
|     }
 | |
| 
 | |
|     public static function val($name = NULL) {
 | |
|         self::init();
 | |
|         return self::$global->val($name);
 | |
|     }
 | |
| 
 | |
|     public static function val_str($name = NULL) {
 | |
|         self::init();
 | |
|         return self::$global->val_str($name);
 | |
|     }
 | |
| 
 | |
|     public static function has_changed($input, $setting, $value) {
 | |
|         return $input == $setting && $value != CrayonGlobalSettings::val($setting);
 | |
|     }
 | |
| 
 | |
|     public static function set($name, $value = NULL, $replace = FALSE) {
 | |
|         self::init();
 | |
|         self::$global->set($name, $value, $replace);
 | |
|     }
 | |
| 
 | |
|     public static function site_url($site_http = NULL) {
 | |
|         if ($site_http === NULL) {
 | |
|             return self::$site_http;
 | |
|         } else {
 | |
|             self::$site_http = CrayonUtil::url_slash($site_http);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public static function site_path($site_path = NULL) {
 | |
|         if ($site_path === NULL) {
 | |
|             return self::$site_path;
 | |
|         } else {
 | |
|             self::$site_path = CrayonUtil::path_slash($site_path);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public static function plugin_path($plugin_path = NULL) {
 | |
|         if ($plugin_path === NULL) {
 | |
|             return self::$plugin_path;
 | |
|         } else {
 | |
|             self::$plugin_path = CrayonUtil::path_slash($plugin_path);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public static function upload_path($upload_path = NULL) {
 | |
|         if ($upload_path === NULL) {
 | |
|             return self::$upload_path;
 | |
|         } else {
 | |
|             self::$upload_path = CrayonUtil::path_slash($upload_path);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public static function upload_url($upload_url = NULL) {
 | |
|         if ($upload_url === NULL) {
 | |
|             return self::$upload_url;
 | |
|         } else {
 | |
|             self::$upload_url = CrayonUtil::url_slash($upload_url);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public static function set_mkdir($mkdir = NULL) {
 | |
|         if ($mkdir === NULL) {
 | |
|             return self::$mkdir;
 | |
|         } else {
 | |
|             self::$mkdir = $mkdir;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public static function mkdir($dir = NULL) {
 | |
|         if (self::$mkdir) {
 | |
|             call_user_func(self::$mkdir, $dir);
 | |
|         } else {
 | |
|             @mkdir($dir, 0777, TRUE);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| $INT = new CrayonValidator('#\d+#');
 | |
| 
 | |
| /**
 | |
|  * Validation class.
 | |
|  */
 | |
| class CrayonValidator {
 | |
|     private $pattern = '#*#msi';
 | |
| 
 | |
|     public function __construct($pattern) {
 | |
|         $this->pattern($pattern);
 | |
|     }
 | |
| 
 | |
|     public function pattern($pattern) {
 | |
|         if ($pattern === NULL) {
 | |
|             return $pattern;
 | |
|         } else {
 | |
|             $this->pattern = $pattern;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public function validate($str) {
 | |
|         return preg_match($this->pattern, $str) !== FALSE;
 | |
|     }
 | |
| 
 | |
|     public function sanitize($str) {
 | |
|         preg_match_all($this->pattern, $str, $matches);
 | |
|         $result = '';
 | |
|         foreach ($matches as $match) {
 | |
|             $result .= $match[0];
 | |
|         }
 | |
|         return $result;
 | |
|     }
 | |
| }
 | |
| 
 | |
| class CrayonNonNegIntValidator extends CrayonValidator {
 | |
|     public function __construct() {
 | |
|         parent::__construct('#\d+#');
 | |
|     }
 | |
| }
 | |
| 
 | |
| class CrayonIntValidator extends CrayonValidator {
 | |
|     public function __construct() {
 | |
|         parent::__construct('#-?\d+#');
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Individual setting.
 | |
|  * Can store boolean, string, dropdown (with array of strings), etc.
 | |
|  */
 | |
| class CrayonSetting {
 | |
|     private $name = '';
 | |
|     /* The type of variables that can be set as the value.
 | |
|      * For dropdown settings, value is int, even though value() will return a string. */
 | |
|     private $type = NULL;
 | |
|     private $default = NULL; // stores string array for dropdown settings
 | |
| 
 | |
|     private $value = NULL; // stores index int for dropdown settings
 | |
| 
 | |
|     private $is_array = FALSE; // only TRUE for dropdown settings
 | |
|     private $locked = FALSE;
 | |
| 
 | |
|     private $validator = NULL;
 | |
| 
 | |
| 
 | |
|     public function __construct($name, $default = '', $value = NULL, $locked = NULL) {
 | |
|         $this->name($name);
 | |
|         if ($default !== NULL) {
 | |
|             $this->def($default); // Perform first to set type
 | |
|         }
 | |
|         if ($value !== NULL) {
 | |
|             $this->value($value);
 | |
|         }
 | |
|         if ($locked !== NULL) {
 | |
|             $this->locked($locked);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     function __tostring() {
 | |
|         return $this->name;
 | |
|     }
 | |
| 
 | |
|     function copy() {
 | |
|         return new CrayonSetting($this->name, $this->default, $this->value, $this->locked);
 | |
|     }
 | |
| 
 | |
|     function name($name = NULL) {
 | |
|         if (!CrayonUtil::str($this->name, $name)) {
 | |
|             return $this->name;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     function type() {
 | |
|         return $this->type;
 | |
|     }
 | |
| 
 | |
|     function is_array() {
 | |
|         return $this->is_array;
 | |
|     }
 | |
| 
 | |
|     function locked($locked = NULL) {
 | |
|         if ($locked === NULL) {
 | |
|             return $this->locked;
 | |
|         } else {
 | |
|             $this->locked = ($locked == TRUE);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Sets/gets value;
 | |
|      * Value is index (int) in default value (array) for dropdown settings.
 | |
|      * value($value) is alias for index($index) if dropdown setting.
 | |
|      * value() returns string value at current index for dropdown settings.
 | |
|      * @param $value
 | |
|      */
 | |
|     function value($value = NULL) {
 | |
|         if ($value === NULL) {
 | |
|             /*if ($this->is_array) {
 | |
|                 return $this->default[$this->value]; // value at index
 | |
|             } else */
 | |
|             if ($this->value !== NULL) {
 | |
|                 return $this->value;
 | |
|             } else {
 | |
|                 if ($this->is_array) {
 | |
|                     return 0;
 | |
|                 } else {
 | |
|                     return $this->default;
 | |
|                 }
 | |
|             }
 | |
|         } else if ($this->locked === FALSE) {
 | |
|             if ($this->is_array) {
 | |
|                 $this->index($value); // $value is index
 | |
|             } else {
 | |
|                 settype($value, $this->type); // Type cast
 | |
|                 $this->value = $value;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     function array_value() {
 | |
|         if ($this->is_array) {
 | |
|             return NULL;
 | |
|         }
 | |
|         return $this->default[$this->value];
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Sets/gets default value.
 | |
|      * For dropdown settings, default value is array of all possible value strings.
 | |
|      * @param $default
 | |
|      */
 | |
|     function def($default = NULL) {
 | |
|         // Only allow default to be set once
 | |
| 
 | |
|         if ($this->type === NULL && $default !== NULL) {
 | |
|             // For dropdown settings
 | |
| 
 | |
|             if (is_array($default)) { // The only time we don't use $this->is_array
 | |
| 
 | |
|                 // If empty, set to blank array
 | |
| 
 | |
|                 if (empty($default)) {
 | |
|                     $default = array('');
 | |
|                 } else {
 | |
|                     // Ensure all values are unique strings
 | |
| 
 | |
|                     $default = CrayonUtil::array_unique_str($default);
 | |
|                 }
 | |
|                 $this->value = 0; // initial index
 | |
| 
 | |
|                 $this->is_array = TRUE;
 | |
|                 $this->type = gettype(0); // Type is int (index)
 | |
| 
 | |
|             } else {
 | |
|                 $this->is_array = FALSE;
 | |
|                 $this->type = gettype($default);
 | |
|                 if (is_int($default)) {
 | |
|                     $this->validator(new CrayonIntValidator());
 | |
|                 }
 | |
|             }
 | |
|             $this->default = $default;
 | |
|         } else {
 | |
|             return $this->default;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Sets/gets index.
 | |
|      * @param int|string $index
 | |
|      * @return FALSE if not dropdown setting
 | |
|      */
 | |
|     function index($index = NULL) {
 | |
|         if (!$this->is_array) {
 | |
|             return FALSE;
 | |
|         } else if ($index === NULL) {
 | |
|             return $this->value; // return current index
 | |
|         } else {
 | |
|             if (!is_int($index)) {
 | |
|                 // Ensure $value is int for index
 | |
|                 $index = intval($index);
 | |
|             }
 | |
|             // Validate index
 | |
|             if ($index < 0 || $index > count($this->default) - 1) {
 | |
|                 $index = 0;
 | |
|             }
 | |
|             $this->value = $index;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Finds the index of a string in an array setting
 | |
|      */
 | |
|     function find_index($str) {
 | |
|         if (!$this->is_array || is_string($str)) {
 | |
|             return FALSE;
 | |
|         }
 | |
|         for ($i = 0; $i < count($this->default); $i++) {
 | |
|             if ($this->default[$i] == $str) {
 | |
|                 return $i;
 | |
|             }
 | |
|         }
 | |
|         return FALSE;
 | |
|     }
 | |
| 
 | |
|     function validator($validator) {
 | |
|         if ($validator === NULL) {
 | |
|             return $this->validator;
 | |
|         } else {
 | |
|             $this->validator = $validator;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     function sanitize($str) {
 | |
|         if ($this->validator != NULL) {
 | |
|             return $this->validator->sanitize($str);
 | |
|         } else {
 | |
|             return $str;
 | |
|         }
 | |
|     }
 | |
| 
 | |
| }
 | |
| 
 | |
| ?>
 |