| Textpattern | PHP Cross Reference | Content Management Systems |
1 <?php 2 3 /* 4 $HeadURL: https://textpattern.googlecode.com/svn/releases/4.5.4/source/textpattern/lib/txplib_theme.php $ 5 $LastChangedRevision: 3944 $ 6 */ 7 8 if (!defined ('THEME')) define('THEME', 'theme/'); 9 10 class theme 11 { 12 var $name, $menu, $url, $is_popup, $message; 13 14 //---------------------------------------- 15 // Theme engine methods 16 //---------------------------------------- 17 18 /** 19 * Constructor 20 * @param string $name Theme name 21 */ 22 function theme($name) 23 { 24 $this->name = $name; 25 $this->menu = array(); 26 $this->url = THEME.rawurlencode($name).'/'; 27 $this->is_popup = false; 28 $this->message = ''; 29 } 30 31 /** 32 * Get a theme's source path 33 * @param string $name Theme name 34 * @return string Source file path for named theme 35 */ 36 static function path($name) 37 { 38 return txpath.DS.THEME.$name.DS.$name.'.php'; 39 } 40 41 /** 42 * Theme factory 43 * @param string $name Theme name 44 * @return object|boolean An initialised theme object, or false on failure 45 */ 46 static function factory($name) 47 { 48 $path = theme::path($name); 49 if (is_readable($path)) 50 { 51 require_once($path); 52 } 53 else 54 { 55 return false; 56 } 57 58 $t = "{$name}_theme"; 59 if (class_exists($t)) 60 { 61 return new $t($name); 62 } 63 else 64 { 65 return false; 66 } 67 } 68 69 /** 70 * Initialise the theme singleton 71 * @param string $name Theme name 72 * @return object A valid theme object 73 */ 74 static function init($name = '') 75 { 76 static $instance; 77 78 if ($name === '') 79 { 80 $name = pluggable_ui('admin_side', 'theme_name', get_pref('theme_name', 'classic')); 81 } 82 83 if ($instance && is_object($instance) && ($name == $instance->name)) 84 { 85 return $instance; 86 } 87 else 88 { 89 $instance = null; 90 } 91 92 $instance = theme::factory($name); 93 if (!$instance) 94 { 95 set_pref('theme_name', 'classic'); 96 die(gTxt('cannot_instantiate_theme', array('{name}' => $name, '{class}' => "{$name}_theme", '{path}' => theme::path($name)))); 97 } 98 99 return $instance; 100 } 101 102 /** 103 * Get a list of all theme names 104 * @return array Alphabetically sorted array of all available theme names 105 */ 106 static function names() 107 { 108 $dirs = glob(txpath.DS.THEME.'*'); 109 if (is_array($dirs)) 110 { 111 foreach ($dirs as $d) 112 { 113 // extract trailing directory name 114 preg_match('#(.*)[\\/]+(.*)$#', $d, $m); 115 $name = $m[2]; 116 117 // accept directories containing an equally named .php file 118 if (is_dir($d) && ($d != '.') && ($d != '..') && isset($name) && is_file($d.DS.$name.'.php')) 119 { 120 $out[] = $name; 121 } 122 } 123 sort($out, SORT_STRING); 124 return $out; 125 } 126 else 127 return array(); 128 } 129 130 /** 131 * Inherit from an ancestor theme 132 * @param string $name Name of ancestor theme 133 * @return boolean True on success, false on unavailable/invalid ancestor theme 134 */ 135 static function based_on($name) 136 { 137 global $production_status; 138 $theme = theme::factory($name); 139 if (!$theme) 140 { 141 set_pref('theme_name', 'classic'); 142 if ($production_status === 'debug') 143 { 144 echo gTxt('cannot_instantiate_theme', array('{name}' => $name, '{class}' => "{$name}_theme", '{path}' => theme::path($name))); 145 } 146 return false; 147 } 148 return true; 149 } 150 151 /** 152 * Sets Textpatterns menu structure, message contents and other application states 153 * @param string $area Currently active top level menu 154 * @param string $event Currently active second level menu 155 * @param boolean $is_popup Just a popup window for tag builder et cetera 156 * @param array $message The contents of the notification message pane 157 * @return object This theme object 158 */ 159 function set_state($area, $event, $is_popup, $message) 160 { 161 $this->is_popup = $is_popup; 162 $this->message = $message; 163 164 if ($is_popup) return $this; 165 166 // use legacy areas() for b/c 167 $areas = areas(); 168 $defaults = array( 169 'content' => 'article', 170 'presentation' => 'page', 171 'admin' => 'admin' 172 ); 173 174 if(empty($areas['start'])) 175 { 176 unset($areas['start']); 177 } 178 179 if(empty($areas['extensions'])) 180 { 181 unset($areas['extensions']); 182 } 183 184 $dflt_tab = get_pref('default_event', ''); 185 186 foreach ($areas as $ar => $items) 187 { 188 $l_ = gTxt('tab_'.$ar); 189 $e_ = (array_key_exists($ar,$defaults)) ? $defaults[$ar] : reset($areas[$ar]); 190 $i_ = array(); 191 192 if (has_privs('tab.'.$ar)) 193 { 194 195 if (!has_privs($e_)) 196 { 197 $e_ = ''; 198 } 199 200 foreach ($items as $a => $b) 201 { 202 if (has_privs($b)) 203 { 204 205 if ($e_ === '') { 206 $e_ = $b; 207 } 208 209 if ($b == $dflt_tab) 210 { 211 $this->menu[$ar]['event'] = $dflt_tab; 212 } 213 214 $i_[] = array('label' => $a, 'event' => $b, 'active' => ($b == $event)); 215 } 216 } 217 218 if ($e_) 219 { 220 $this->menu[$ar] = array( 221 'label' => $l_, 222 'event' => $e_, 223 'active' => ($ar == $area), 224 'items' => $i_, 225 ); 226 } 227 } 228 } 229 return $this; 230 } 231 232 //---------------------------------------- 233 // Overrideable methods for custom themes 234 //---------------------------------------- 235 236 /** 237 * Output HEAD element contents. Returned value is rendered into the HEAD element of all admin side pages by core. 238 * @return string 239 */ 240 function html_head() 241 { 242 trigger_error(__FUNCTION__.' is abstract.', E_USER_ERROR); 243 } 244 245 /** 246 * Draw the theme's header 247 * @return string 248 */ 249 function header() 250 { 251 trigger_error(__FUNCTION__.' is abstract.', E_USER_ERROR); 252 } 253 254 /** 255 * Draw the theme's footer 256 * @return string 257 */ 258 function footer() 259 { 260 trigger_error(__FUNCTION__.' is abstract.', E_USER_ERROR); 261 } 262 263 /** 264 * Output notification message for synchronous HTML views 265 * @param array $thing Message text and status flag 266 * @param boolean $modal true: Immediate user interaction suggested 267 */ 268 function announce($thing=array('', 0), $modal = false) 269 { 270 trigger_error(__FUNCTION__.' is abstract.', E_USER_ERROR); 271 } 272 273 /** 274 * Output notification message for asynchronous Javascript views 275 * @param array $thing Message text and status flag 276 * @param boolean $modal true: Immediate user interaction suggested 277 * @since 4.5.0 278 */ 279 function announce_async($thing=array('', 0), $modal = false) 280 { 281 trigger_error(__FUNCTION__.' is abstract.', E_USER_ERROR); 282 } 283 284 /** 285 * Define bureaucratic details of this theme. All returned items are optional. 286 * @return array 287 */ 288 function manifest() 289 { 290 return array( 291 'title' => '', // Human-readable title of this theme. No HTML, keep it short. 292 'author' => '', // Name(s) of this theme's creator(s). 293 'author_uri' => '', // URI of the theme's site. Decent vanity is accepted. 294 'version' => '', // Version numbering. Mind version_compare(). 295 'description' => '', // Human readable short description. No HTML. 296 'help' => '', // URI of the theme's help and docs. Strictly optional. 297 ); 298 } 299 } 300 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
title