Ticket #20103: 20103.3.diff
| File 20103.3.diff, 99.5 KB (added by , 14 years ago) |
|---|
-
wp-includes/class-wp-customize.php
81 81 82 82 add_filter( 'template', array( $this, 'get_template' ) ); 83 83 add_filter( 'stylesheet', array( $this, 'get_stylesheet' ) ); 84 add_filter( 'pre_option_current_theme', array( $this, 'current_theme' ) );85 84 86 85 // @link: http://core.trac.wordpress.org/ticket/20027 87 86 add_filter( 'pre_option_stylesheet', array( $this, 'get_stylesheet' ) ); … … 235 234 } 236 235 237 236 /** 238 * Filter the current theme and return the name of the previewed theme.239 *240 * @since 3.4.0241 *242 * @return string Theme name.243 */244 public function current_theme( $current_theme ) {245 $themes = get_themes();246 247 if ( ! $themes )248 return $current_theme;249 250 foreach ( $themes as $theme ) {251 if ( $theme['Stylesheet'] == $this->stylesheet && $theme['Template'] == $this->template )252 return $theme['Name'];253 }254 255 return $current_theme;256 }257 258 /**259 237 * Trigger save action and load customize controls. 260 238 * 261 239 * @since 3.4.0 -
wp-includes/update.php
235 235 if ( defined( 'WP_INSTALLING' ) ) 236 236 return false; 237 237 238 if ( !function_exists( 'get_themes' ) ) 239 require_once( ABSPATH . 'wp-includes/theme.php' ); 240 241 $installed_themes = get_themes( ); 238 $installed_themes = wp_get_themes(); 242 239 $last_update = get_site_transient( 'update_themes' ); 243 240 if ( ! is_object($last_update) ) 244 241 $last_update = new stdClass; 245 242 246 243 $themes = array(); 247 244 $checked = array(); 248 $exclude_fields = array('Template Files', 'Stylesheet Files', 'Status', 'Theme Root', 'Theme Root URI', 'Template Dir', 'Stylesheet Dir', 'Description', 'Tags', 'Screenshot');249 245 250 246 // Put slug of current theme into request. 251 247 $themes['current_theme'] = get_option( 'stylesheet' ); 252 248 253 foreach ( (array) $installed_themes as $theme_title => $theme ) { 254 $themes[$theme['Stylesheet']] = array(); 255 $checked[$theme['Stylesheet']] = $theme['Version']; 249 foreach ( $installed_themes as $theme ) { 250 $checked[ $theme->get_stylesheet() ] = $theme->get('Version'); 256 251 257 $themes[$theme['Stylesheet']]['Name'] = $theme['Name']; 258 $themes[$theme['Stylesheet']]['Version'] = $theme['Version']; 259 260 foreach ( (array) $theme as $key => $value ) { 261 if ( !in_array($key, $exclude_fields) ) 262 $themes[$theme['Stylesheet']][$key] = $value; 263 } 252 $themes[ $theme->get_stylesheet() ] = array( 253 'Name' => $theme->get('Name'), 254 'Title' => $theme->get('Name'), 255 'Version' => $theme->get('Version'), 256 'Author' => $theme->get('Author'), 257 'Author URI' => $theme->get('AuthorURI'), 258 'Template' => $theme->get_template(), 259 'Stylesheet' => $theme->get_stylesheet(), 260 ); 264 261 } 265 262 266 263 // Check for update on a different schedule, depending on the page. -
wp-includes/class-wp-theme.php
1 <?php 2 /** 3 * WP_Theme Class 4 * 5 * @package WordPress 6 * @subpackage Theme 7 */ 8 9 final class WP_Theme implements ArrayAccess { 10 11 /** 12 * Headers for style.css files. 13 * 14 * @static 15 * @access private 16 * @var array 17 */ 18 private static $file_headers = array( 19 'Name' => 'Theme Name', 20 'ThemeURI' => 'Theme URI', 21 'Description' => 'Description', 22 'Author' => 'Author', 23 'AuthorURI' => 'Author URI', 24 'Version' => 'Version', 25 'Template' => 'Template', 26 'Status' => 'Status', 27 'Tags' => 'Tags', 28 'TextDomain' => 'Text Domain', 29 'DomainPath' => 'Domain Path', 30 ); 31 32 /** 33 * Absolute path to the theme root, usually wp-content/themes 34 * 35 * @access private 36 * @var string 37 */ 38 private $theme_root; 39 40 /** 41 * Header data from the theme's style.css file. 42 * 43 * @access private 44 * @var array 45 */ 46 private $headers = array(); 47 48 /** 49 * Header data from the theme's style.css file after being sanitized. 50 * 51 * @access private 52 * @var array 53 */ 54 private $headers_sanitized; 55 56 /** 57 * Header name from the theme's style.css after being translated. 58 * 59 * Cached due to sorting functions running over the translated name. 60 */ 61 private $name_translated; 62 63 /** 64 * Errors encountered when initializing the theme. 65 * 66 * @access private 67 * @var WP_Error 68 */ 69 private $errors; 70 71 /** 72 * The directory name of the theme's files, inside the theme root. 73 * 74 * In the case of a child theme, this is directory name of the the child theme. 75 * Otherwise, 'stylesheet' is the same as 'template'. 76 * 77 * @access private 78 * @var string 79 */ 80 private $stylesheet; 81 82 /** 83 * The directory name of the theme's files, inside the theme root. 84 * 85 * In the case of a child theme, this is the directory name of the parent theme. 86 * Otherwise, 'template' is the same as 'stylesheet'. 87 * 88 * @access private 89 * @var string 90 */ 91 private $template; 92 93 /** 94 * A reference to the parent theme, in the case of a child theme. 95 * 96 * @access private 97 * @var WP_Theme 98 */ 99 private $parent; 100 101 /** 102 * Flag for whether the theme's textdomain is loaded. 103 * 104 * @access private 105 * @var bool 106 */ 107 private $textdomain_loaded; 108 109 /** 110 * Flag for whether the themes cache bucket should be persistently cached. 111 * 112 * Default is false. Can be set with the wp_cache_themes_persistently filter. 113 * 114 * @access private 115 * @var bool 116 */ 117 private static $persistently_cache; 118 119 /** 120 * Expiration time for the themes cache bucket. 121 * 122 * By default the bucket is not cached, so this value is useless. 123 * 124 * @access private 125 * @var bool 126 */ 127 private static $cache_expiration = 7200; 128 129 /** 130 * Constructor for WP_Theme. 131 * 132 * @param string $theme_dir Directory of the theme within the theme_root. 133 * @param string $theme_root Theme root. 134 * @param WP_Error|null $child If this theme is a parent theme, the child may be passed for validation purposes. 135 */ 136 public function __construct( $theme_dir, $theme_root, $child = null ) { 137 138 // Initialize caching on first run. 139 if ( ! isset( self::$persistently_cache ) ) { 140 self::$persistently_cache = apply_filters( 'wp_cache_themes_persistently', false ); 141 if ( is_int( self::$persistently_cache ) ) 142 self::$cache_expiration = self::$persistently_cache; 143 elseif ( ! self::$persistently_cache ) 144 wp_cache_add_non_persistent_groups( 'themes' ); 145 } 146 147 $this->theme_root = $theme_root; 148 $this->stylesheet = $theme_dir; 149 $theme_file = $this->stylesheet . '/style.css'; 150 151 $cache = $this->cache_get( 'theme' ); 152 153 if ( is_array( $cache ) ) { 154 foreach ( array( 'errors', 'headers', 'template' ) as $key ) { 155 if ( isset( $cache[ $key ] ) ) 156 $this->$key = $cache[ $key ]; 157 } 158 if ( $this->errors ) 159 return; 160 if ( isset( $cache['theme_root_template'] ) ) 161 $theme_root_template = $cache['theme_root_template']; 162 } elseif ( ! file_exists( $this->theme_root . '/' . $theme_file ) ) { 163 $this->headers['Name'] = $this->stylesheet; 164 $this->errors = new WP_Error( 'theme_no_stylesheet', __( 'Stylesheet is missing.' ) ); 165 $this->cache_add( 'theme', array( 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet ) ); 166 if ( ! file_exists( $this->theme_root ) ) // Don't cache this one. 167 $this->errors->add( 'theme_root_missing', __( 'ERROR: The themes directory is either empty or doesn’t exist. Please check your installation.' ) ); 168 return; 169 } elseif ( ! is_readable( $this->theme_root . '/' . $theme_file ) ) { 170 $this->headers['Name'] = $this->stylesheet; 171 $this->errors = new WP_Error( 'theme_stylesheet_not_readable', __( 'Stylesheet is not readable.' ) ); 172 $this->cache_add( 'theme', array( 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet ) ); 173 return; 174 } else { 175 $this->headers = get_file_data( $this->theme_root . '/' . $theme_file, self::$file_headers, 'theme' ); 176 } 177 178 if ( ! $this->template = $this->get('Template') ) { 179 if ( file_exists( $this->theme_root . '/' . $this->stylesheet . '/index.php' ) ) { 180 $this->template = $this->stylesheet; 181 } else { 182 $this->errors = new WP_Error( 'theme_no_index', __( 'Template is missing.' ) ); 183 $this->cache_add( 'theme', array( 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet ) ); 184 return; 185 } 186 } 187 188 // If we got our data from cache, we can trust 'template' as pointing to the right place. 189 if ( ! is_array( $cache ) && $this->template != $this->stylesheet && ! file_exists( $this->theme_root . '/' . $this->template . '/index.php' ) ) { 190 // If we're in a directory of themes inside /themes, look for the parent nearby. 191 // wp-content/themes/directory-of-themes/* 192 $parent_dir = dirname( $this->stylesheet ); 193 if ( '.' != $parent_dir && file_exists( $this->theme_root . '/' . $parent_dir . '/' . $this->template . '/index.php' ) ) { 194 $this->template = $parent_dir . '/' . $this->template; 195 } elseif ( ( $directories = search_theme_directories() ) && isset( $directories[ $this->template ] ) ) { 196 // Look for the template in the search_theme_directories() results, in case it is in another theme root. 197 // We don't look into directories of themes, just the theme root. 198 $theme_root_template = $directories[ $this->template ]['theme_root']; 199 } else { 200 // Parent theme is missing. 201 $this->errors = new WP_Error( 'theme_no_parent', sprintf( __( 'The parent theme is missing. Please install the "%s" parent theme.' ), $this->template ) ); 202 $this->cache_add( 'theme', array( 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template ) ); 203 return; 204 } 205 } 206 207 // @TODO Check for theme name collision. But guess what? We don't care anymore! We only care about clashing matches found in search_theme_directories(). 208 209 // Set the parent, if we're a child theme. 210 if ( $this->template != $this->stylesheet ) { 211 // If we are a parent, then there is a problem. Only two generations allowed! Cancel things out. 212 if ( is_a( $child, 'WP_Theme' ) && $child->template == $this->stylesheet ) { 213 $child->parent = null; 214 $child->errors = new WP_Error( 'theme_parent_invalid', sprintf( __( 'The "%s" theme is not a valid parent theme.' ), $child->template ) ); 215 $child->cache_add( 'theme', array( 'headers' => $child->headers, 'errors' => $child->errors, 'stylesheet' => $child->stylesheet, 'template' => $child->template ) ); 216 // The two themes actually reference each other with the Template header. 217 if ( $child->stylesheet == $this->template ) { 218 $this->errors = new WP_Error( 'theme_parent_invalid', sprintf( __( 'The "%s" theme is not a valid parent theme.' ), $this->template ) ); 219 $this->cache_add( 'theme', array( 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template ) ); 220 } 221 return; 222 } 223 // Set the parent. Pass the current instance so we can do the crazy checks above and assess errors. 224 $this->parent = new WP_Theme( $this->template, isset( $theme_root_template ) ? $theme_root_template : $this->theme_root, $this ); 225 } 226 227 // We're good. If we didn't retrieve from cache, set it. 228 if ( ! is_array( $cache ) ) { 229 $cache = array( 'headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template ); 230 // If the parent theme is in another root, we'll want to cache this. Avoids an entire branch of filesystem calls above. 231 if ( isset( $theme_root_template ) ) 232 $cache['theme_root_template'] = $theme_root_template; 233 $this->cache_add( 'theme', $cache ); 234 } 235 } 236 237 /** 238 * __isset() magic method for properties formerly returned by current_theme_info() 239 */ 240 public function __isset( $offset ) { 241 static $properties = array( 242 'name', 'title', 'version', 'parent_theme', 'template_dir', 'stylesheet_dir', 'template', 'stylesheet', 243 'screenshot', 'description', 'author', 'tags', 'theme_root', 'theme_root_uri', 244 ); 245 246 return in_array( $offset, $properties ); 247 } 248 249 /** 250 * __get() magic method for properties formerly returned by current_theme_info() 251 */ 252 public function __get( $offset ) { 253 switch ( $offset ) { 254 case 'name' : 255 case 'title' : 256 return $this->get('Name'); 257 case 'version' : 258 return $this->get('Version'); 259 case 'parent_theme' : 260 return $this->parent ? $this->parent->get('Name') : ''; 261 case 'template_dir' : 262 return $this->get_template_directory(); 263 case 'stylesheet_dir' : 264 return $this->get_stylesheet_directory(); 265 case 'template' : 266 return $this->get_template(); 267 case 'stylesheet' : 268 return $this->get_stylesheet(); 269 case 'screenshot' : 270 return $this->get_screenshot(); 271 // 'author' and 'description' did not previously return translated data. 272 case 'description' : 273 return $this->display('Description'); 274 case 'author' : 275 return $this->display('Author'); 276 case 'tags' : 277 return $this->get( 'Tags' ); 278 case 'theme_root' : 279 return $this->get_theme_root(); 280 case 'theme_root_uri' : 281 return $this->get_theme_root_uri(); 282 } 283 } 284 285 /** 286 * Method to implement ArrayAccess for keys formerly returned by get_themes() 287 */ 288 public function offsetSet( $offset, $value ) {} 289 290 /** 291 * Method to implement ArrayAccess for keys formerly returned by get_themes() 292 */ 293 public function offsetUnset( $offset ) {} 294 295 /** 296 * Method to implement ArrayAccess for keys formerly returned by get_themes() 297 */ 298 public function offsetExists( $offset ) { 299 static $keys = array( 300 'Name', 'Version', 'Status', 'Title', 'Author', 'Author Name', 'Author URI', 'Description', 301 'Template', 'Stylesheet', 'Template Files', 'Stylesheet Files', 'Template Dir', 'Stylesheet Dir', 302 'Screenshot', 'Tags', 'Theme Root', 'Theme Root URI', 'Parent Theme', 303 ); 304 305 return in_array( $offset, $keys ); 306 } 307 308 /** 309 * Method to implement ArrayAccess for keys formerly returned by get_themes() 310 */ 311 public function offsetGet( $offset ) { 312 switch ( $offset ) { 313 case 'Name' : 314 case 'Version' : 315 case 'Status' : 316 return $this->get( $offset ); 317 case 'Title' : 318 return $this->get('Name'); 319 // Author, Author Name, Author URI, and Description did not 320 // previously return translated data. We are doing so now. 321 // Title and Name could have been used as the key for get_themes(), 322 // so both to remain untranslated for back compatibility. 323 case 'Author' : 324 return $this->display( 'Author'); 325 case 'Author Name' : 326 return $this->display( 'Author', false); 327 case 'Author URI' : 328 return $this->display('AuthorURI'); 329 case 'Description' : 330 return $this->display( 'Description'); 331 case 'Template' : 332 return $this->get_template(); 333 case 'Stylesheet' : 334 return $this->get_stylesheet(); 335 case 'Template Files' : 336 $files = $this->get_files('php'); 337 foreach ( $files as &$file ) 338 $file = $this->theme_root . '/' . $file; 339 return $files; 340 case 'Stylesheet Files' : 341 $files = $this->get_files('css'); 342 foreach ( $files as &$file ) 343 $file = $this->theme_root . '/' . $file; 344 return $files; 345 case 'Template Dir' : 346 return $this->get_template_directory(); 347 case 'Stylesheet Dir' : 348 return $this->get_stylesheet_directory(); 349 case 'Screenshot' : 350 return $this->get_screenshot(); 351 case 'Tags' : 352 return $this->get('Tags'); 353 case 'Theme Root' : 354 return $this->get_theme_root(); 355 case 'Theme Root URI' : 356 return $this->get_theme_root_uri(); 357 case 'Parent Theme' : 358 return $this->parent ? $this->parent->get('Name') : ''; 359 default : 360 return null; 361 } 362 } 363 364 /** 365 * Returns errors property. 366 * 367 * @since 3.4.0 368 * @access public 369 * 370 * @return WP_Error|bool WP_Error if there are errors, or false. 371 */ 372 public function errors() { 373 return is_wp_error( $this->errors ) ? $this->errors : false; 374 } 375 376 /** 377 * Returns reference to the parent theme. 378 * 379 * @since 3.4.0 380 * @access public 381 * 382 * @return WP_Theme|bool Parent theme, or false if the current theme is not a child theme. 383 */ 384 public function parent() { 385 return isset( $this->parent ) ? $this->parent : false; 386 } 387 388 /** 389 * Adds theme data to cache. 390 * 391 * Cache entries keyed by the theme and the type of data. 392 * 393 * @access private 394 * @since 3.4.0 395 * 396 * @param string $key Type of data to store (theme, screenshot, screenshot_count, files, headers) 397 * @param string $data Data to store 398 * @return bool Return value from wp_cache_add() 399 */ 400 private function cache_add( $key, $data ) { 401 return wp_cache_add( $key . '-' . $this->theme_root . '/' . $this->stylesheet, $data, 'themes', self::$cache_expiration ); 402 } 403 404 /** 405 * Gets theme data from cache. 406 * 407 * Cache entries are keyed by the theme and the type of data. 408 * 409 * @access private 410 * @since 3.4.0 411 * 412 * @param string $key Type of data to retrieve (theme, screenshot, screenshot_count, files, headers) 413 * @return mixed Retrieved data 414 */ 415 private function cache_get( $key ) { 416 return wp_cache_get( $key . '-' . $this->theme_root . '/' . $this->stylesheet, 'themes' ); 417 } 418 419 /** 420 * Clears the cache for the theme. 421 * 422 * @access public 423 * @since 3.4.0 424 */ 425 public function cache_delete() { 426 wp_cache_delete( 'theme-' . $this->theme_root . '/' . $this->stylesheet, 'themes' ); 427 wp_cache_delete( 'screenshot-' . $this->theme_root . '/' . $this->stylesheet, 'themes' ); 428 wp_cache_delete( 'screenshot_count-' . $this->theme_root . '/' . $this->stylesheet, 'themes' ); 429 wp_cache_delete( 'files-' . $this->theme_root . '/' . $this->stylesheet, 'themes' ); 430 wp_cache_delete( 'headers-' . $this->theme_root . '/' . $this->stylesheet, 'themes' ); 431 } 432 433 /** 434 * Gets a theme header. 435 * 436 * The header is sanitized. 437 * 438 * @access public 439 * @since 3.4.0 440 * 441 * @param string $header Theme header. Name, Description, Author, Version, ThemeURI, AuthorURI, Status. 442 * @return string String on success, false on failure. 443 */ 444 public function get( $header ) { 445 if ( ! isset( $this->headers[ $header ] ) ) 446 return false; 447 return $this->sanitize_header( $header, $this->headers[ $header ] ); 448 449 if ( ! isset( $this->headers_sanitized ) ) { 450 $this->headers_sanitized = $this->cache_get( 'headers' ); 451 if ( ! is_array( $this->headers_sanitized ) ) 452 $headers = array(); 453 } 454 455 if ( isset( $this->headers_sanitized[ $header ] ) ) 456 return $this->headers_sanitized[ $header ]; 457 458 // If an external object cache does not consider themes to be a persistent group, sanitize everything and cache it. 459 if ( self::$persistently_cache ) { 460 foreach ( array_keys( $this->headers ) as $header ) 461 $this->headers_sanitized[ $header ] = $this->sanitize_header( $header, $this->headers[ $header ] ); 462 $this->cache_add( 'headers', $this->headers_sanitized ); 463 } else { 464 $this->headers_sanitized[ $header ] = $this->sanitize_header( $header, $this->headers[ $header ] ); 465 } 466 467 return $this->headers_sanitized[ $header ]; 468 } 469 470 /** 471 * Gets a theme header ready for display (marked up, translated). 472 * 473 * @access public 474 * @since 3.4.0 475 * 476 * @param string $header Theme header. Name, Description, Author, Version, ThemeURI, AuthorURI, Status. 477 * @param bool $markup Optional. Whether to mark up the header. Defaults to true. 478 * @param bool $translate Optional. Whether to translate the header. Defaults to true. 479 * @return string Processed header, false on failure. 480 */ 481 public function display( $header, $markup = true, $translate = true ) { 482 $value = $this->get( $header ); 483 if ( false === $value || '' === $value ) 484 return $value; 485 486 if ( ! $this->load_textdomain() ) 487 $translate = false; 488 489 if ( $translate ) 490 $value = $this->translate_header( $header, $value ); 491 492 if ( $markup ) 493 $value = $this->markup_header( $header, $value, $translate ); 494 495 return $value; 496 } 497 498 /** 499 * Sanitize a theme header. 500 * 501 * @param string $header Theme header. Name, Description, Author, Version, ThemeURI, AuthorURI, Status. 502 * @param string $value Value to sanitize. 503 */ 504 private function sanitize_header( $header, $value ) { 505 switch ( $header ) { 506 case 'Status' : 507 if ( ! $value ) { 508 $value = 'public'; 509 break; 510 } 511 // Fall through otherwise. 512 case 'Name' : 513 case 'Author' : 514 static $header_tags = array( 515 'abbr' => array( 'title' => true ), 516 'acronym' => array( 'title' => true ), 517 'code' => true, 518 'em' => true, 519 'strong' => true, 520 ); 521 $value = wp_kses( $value, $header_tags ); 522 break; 523 case 'Description' : 524 static $header_tags_with_a = array( 525 'a' => array( 'href' => true, 'title' => true ), 526 'abbr' => array( 'title' => true ), 527 'acronym' => array( 'title' => true ), 528 'code' => true, 529 'em' => true, 530 'strong' => true, 531 ); 532 $value = wp_kses( $value, $header_tags_with_a ); 533 break; 534 case 'ThemeURI' : 535 case 'AuthorURI' : 536 $value = esc_url( $value ); 537 break; 538 case 'Tags' : 539 $value = array_filter( array_map( 'trim', explode( ',', strip_tags( $value ) ) ) ); 540 break; 541 } 542 543 return $value; 544 } 545 546 /** 547 * Mark up a theme header. 548 * 549 * @access private 550 * @since 3.4.0 551 * 552 * @param string $header Theme header. Name, Description, Author, Version, ThemeURI, AuthorURI, Status. 553 * @param string $value Value to mark up. 554 * @param string $translate Whether the header has been translated. 555 * @return string Value, marked up. 556 */ 557 private function markup_header( $header, $value, $translate ) { 558 switch ( $header ) { 559 case 'Description' : 560 $value = wptexturize( $value ); 561 break; 562 case 'Author' : 563 if ( $this->get('AuthorURI') ) { 564 static $attr = null; 565 if ( ! isset( $attr ) ) 566 $attr = esc_attr__( 'Visit author homepage' ); 567 $value = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $this->display( 'AuthorURI', true, $translate ), $attr, $value ); 568 } elseif ( ! $value ) { 569 $value = __( 'Anonymous' ); 570 } 571 break; 572 case 'Tags' : 573 static $comma = null; 574 if ( ! isset( $comma ) ) { 575 /* translators: used between list items, there is a space after the comma */ 576 $comma = __( ', ' ); 577 } 578 $value = implode( $comma, $value ); 579 break; 580 } 581 582 return $value; 583 } 584 585 /** 586 * Translate a theme header. 587 * 588 * @access private 589 * @since 3.4.0 590 * 591 * @param string $header Theme header. Name, Description, Author, Version, ThemeURI, AuthorURI, Status. 592 * @param string $value Value to translate. 593 * @return string Translated value. 594 */ 595 private function translate_header( $header, $value ) { 596 switch ( $header ) { 597 case 'Name' : 598 // Cached for sorting reasons. 599 if ( isset( $this->name_translated ) ) 600 return $this->name_translated; 601 $this->name_translated = translate( $value, $this->get('TextDomain' ) ); 602 return $this->name_translated; 603 case 'Tags' : 604 if ( empty( $value ) ) 605 return $value; 606 607 static $tags_list; 608 if ( ! isset( $tags_list ) ) { 609 $tags_list = array(); 610 $feature_list = get_theme_feature_list( false ); // No API 611 foreach ( $feature_list as $tags ) 612 $tags_list += $tags; 613 } 614 615 foreach ( $value as &$tag ) { 616 if ( isset( $tags_list[ $tag ] ) ) 617 $tag = $tags_list[ $tag ]; 618 } 619 620 return $value; 621 break; 622 default : 623 $value = translate( $value, $this->get('TextDomain') ); 624 } 625 return $value; 626 } 627 628 /** 629 * The directory name of the theme's "stylesheet" files, inside the theme root. 630 * 631 * In the case of a child theme, this is directory name of the the child theme. 632 * Otherwise, get_stylesheet() is the same as get_template(). 633 * 634 * @since 3.4.0 635 * @access public 636 * 637 * @return string Stylesheet 638 */ 639 public function get_stylesheet() { 640 return $this->stylesheet; 641 } 642 643 /** 644 * The directory name of the theme's "template" files, inside the theme root. 645 * 646 * In the case of a child theme, this is the directory name of the parent theme. 647 * Otherwise, the get_template() is the same as get_stylesheet(). 648 * 649 * @since 3.4.0 650 * @access public 651 * 652 * @return string Template 653 */ 654 public function get_template() { 655 return $this->template; 656 } 657 658 /** 659 * Whether a theme is a child theme. 660 * 661 * @since 3.4.0 662 * @access public 663 * 664 * @return bool True if a theme is a child theme, false otherwise. 665 */ 666 public function is_child_theme() { 667 return $this->template !== $this->stylesheet; 668 } 669 670 /** 671 * Returns the absolute path to the directory of a theme's "stylesheet" files. 672 * 673 * In the case of a child theme, this is the absolute path to the directory 674 * of the child theme's files. 675 * 676 * @since 3.4.0 677 * @access public 678 * 679 * @return string Absolute path of the stylesheet directory. 680 */ 681 public function get_stylesheet_directory() { 682 if ( $this->errors && in_array( 'theme_root_missing', $this->errors->get_error_codes() ) ) 683 return ''; 684 685 return $this->theme_root . '/' . $this->stylesheet; 686 } 687 688 /** 689 * Returns the absolute path to the directory of a theme's "template" files. 690 * 691 * In the case of a child theme, this is the absolute path to the directory 692 * of the parent theme's files. 693 * 694 * @since 3.4.0 695 * @access public 696 * 697 * @return string Absolute path of the template directory. 698 */ 699 public function get_template_directory() { 700 if ( $this->parent ) 701 $theme_root = $this->parent->theme_root; 702 else 703 $theme_root = $this->theme_root; 704 705 return $theme_root . '/' . $this->template; 706 } 707 708 /** 709 * Returns the URL to the directory of a theme's "stylesheet" files. 710 * 711 * In the case of a child theme, this is the URL to the directory of the 712 * child theme's files. 713 * 714 * @since 3.4.0 715 * @access public 716 * 717 * @return string URL to the stylesheet directory. 718 */ 719 public function get_stylesheet_directory_uri() { 720 return $this->theme_root_uri . '/' . $this->stylesheet; 721 } 722 723 /** 724 * Returns the URL to the directory of a theme's "template" files. 725 * 726 * In the case of a child theme, this is the URL to the directory of the 727 * parent theme's files. 728 * 729 * @since 3.4.0 730 * @access public 731 * 732 * @return string URL to the template directory. 733 */ 734 public function get_template_directory_uri() { 735 if ( $this->parent ) 736 $theme_root_uri = $this->parent->theme_root_uri; 737 else 738 $theme_root_uri = $this->theme_root; 739 740 return $theme_root . '/' . $this->template; 741 } 742 743 /** 744 * The absolute path to the directory of the theme root. 745 * 746 * This is typically the absolute path to wp-content/themes. 747 * 748 * @since 3.4.0 749 * @access public 750 * 751 * @return string Theme root. 752 */ 753 public function get_theme_root() { 754 return $this->theme_root; 755 } 756 757 /** 758 * Returns the URL to the directory of the theme root. 759 * 760 * This is typically the absolute path to wp-content/themes. 761 * 762 * @since 3.4.0 763 * @access public 764 * 765 * @return string Theme root URI. 766 */ 767 public function get_theme_root_uri() { 768 return str_replace( WP_CONTENT_DIR, content_url(), $this->theme_root ); 769 } 770 771 /** 772 * Returns the main screenshot file for the theme. 773 * 774 * The main screenshot is called screenshot.png. gif and jpg extensions are also allowed. 775 * 776 * Screenshots for a theme must be in the stylesheet directory. (In the case of a child 777 * theme, a parent theme's screenshots are inherited.) 778 * 779 * @since 3.4.0 780 * @access public 781 * 782 * @param string $uri Type of URL to include, either relative or absolute. Defaults to relative. 783 * @return mixed Screenshot file. False if the theme does not have a screenshot. 784 */ 785 public function get_screenshot( $uri = 'relative' ) { 786 $screenshot = $this->cache_get( 'screenshot' ); 787 if ( $screenshot ) { 788 if ( 'absolute' == $uri ) 789 return $this->get_stylesheet_directory_uri() . '/' . $screenshot; 790 return $screenshot; 791 } elseif ( 0 === $screenshot ) { 792 return false; 793 } 794 795 foreach ( array( 'png', 'gif', 'jpg', 'jpeg' ) as $ext ) { 796 if ( file_exists( $this->get_stylesheet_directory() . "/screenshot.$ext" ) ) { 797 $this->cache_add( 'screenshot', 'screenshot.' . $ext ); 798 if ( 'absolute' == $uri ) 799 return $this->get_stylesheet_directory_uri() . '/' . 'screenshot.' . $ext; 800 return 'screenshot.' . $ext; 801 } 802 } 803 804 $this->cache_add( 'screenshot', 0 ); 805 $this->cache_add( 'screenshot_count', 0 ); 806 return false; 807 } 808 809 /** 810 * Returns the number of screenshots for a theme. 811 * 812 * The first screenshot may be called screenshot.png, .gif, or .jpg. Subsequent 813 * screenshots can be screenshot-2.png, screenshot-3.png, etc. The count must 814 * be consecutive for screenshots to be counted, and all screenshots beyond the 815 * initial one must be image/png files. 816 * 817 * @see WP_Theme::get_screenshot() 818 * @since 3.4.0 819 * @access public 820 * 821 * @return int Number of screenshots. Can be 0. 822 */ 823 public function get_screenshot_count() { 824 $screenshot_count = $this->cache_get( 'screenshot_count' ); 825 if ( is_numeric( $screenshot_count ) ) 826 return $screenshot_count; 827 828 // This will set the screenshot cache. 829 // If there is no screenshot, the screenshot_count cache will also be set. 830 if ( ! $screenshot = $this->get_screenshot() ) 831 return 0; 832 833 $prefix = $this->get_stylesheet() . '/screenshot-'; 834 $files = self::scandir( $this->get_stylesheet_directory(), $this->get_stylesheet(), 'png', 0 ); 835 836 $screenshot_count = 1; 837 while ( in_array( $prefix . ( $screenshot_count + 1 ) . '.png', $files['png'] ) ) 838 $screenshot_count++; 839 840 $this->cache_add( 'screenshot_count', $screenshot_count ); 841 return $screenshot_count; 842 } 843 844 /** 845 * Returns an array of screenshot filenames. 846 * 847 * @see WP_Theme::get_screenshot() 848 * @see WP_Theme::get_screenshot_count() 849 * @since 3.4.0 850 * @access public 851 * 852 * @return array Screenshots. 853 */ 854 public function get_screenshots() { 855 if ( ! $count = $this->get_screenshot_count() ) 856 return array(); 857 858 $screenshots = array( $this->get_screenshot() ); 859 for ( $i = 2; $i <= $count; $i++ ) 860 $screenshots[] = 'screenshot-' . $i . '.png'; 861 return $screenshots; 862 } 863 864 /** 865 * Return files in the template and stylesheet directories. 866 * 867 * @since 3.4.0 868 * @access public 869 * 870 * @param string|null $type Optional. Type of files to return, either 'php' or 'css'. Defaults to null, for both. 871 * @return array If a specific $type is requested, returns an array of PHP files. If no $type is requested, 872 * returns an array, with the keys being the file types, and the values being an array of files for those type. 873 */ 874 public function get_files( $type = null, $include_parent_files = false ) { 875 $files = $this->cache_get( 'files' ); 876 if ( ! is_array( $files ) ) { 877 if ( $include_parent_files || ! $this->is_child_theme() ) 878 // Template files can be one level down for the purposes of the theme editor, so this should be $depth = 1. 879 // Todo: We ignore this for now, but this is why the branching is weird. 880 $files = (array) self::scandir( $this->get_template_directory(), $this->get_template(), array( 'php', 'css' ) ); 881 if ( $this->is_child_theme() ) 882 $files = array_merge_recursive( $files, (array) self::scandir( $this->get_stylesheet_directory(), $this->get_stylesheet(), array( 'php', 'css' ) ) ); 883 foreach ( $files as &$group ) 884 sort( $group ); 885 $this->cache_add( 'files', $files ); 886 } 887 888 if ( null === $type ) 889 return $files; 890 elseif ( isset( $files[ $type ] ) ) 891 return $files[ $type ]; 892 893 return array(); 894 } 895 896 public function get_page_templates() { 897 // If you screw up your current theme and we invalidate your parent, most things still work. Let it slide. 898 if ( $this->errors() && $this->errors()->get_error_codes() !== array( 'theme_parent_invalid' ) ) 899 return array(); 900 901 $page_templates = $this->cache_get( 'page_templates' ); 902 if ( is_array( $page_templates ) ) 903 return $page_templates; 904 $page_templates = array(); 905 906 $files = (array) self::scandir( $this->get_template_directory(), $this->get_template_directory(), 'php' ); 907 if ( $this->is_child_theme() ) 908 $files = array_merge_recursive( $files, (array) self::scandir( $this->get_stylesheet_directory(), $this->get_stylesheet_directory(), 'php' ) ); 909 910 foreach ( $files['php'] as $file ) { 911 $headers = get_file_data( $file, array( 'Name' => 'Template Name' ) ); 912 if ( empty( $headers['Name'] ) ) 913 continue; 914 $page_templates[ $headers['Name'] ] = basename( $file ); 915 } 916 917 $this->cache_add( 'page_templates', $page_templates ); 918 return $page_templates; 919 } 920 921 /** 922 * Scans a directory for files of a certain extension. 923 * 924 * @since 3.4.0 925 * @access public 926 * 927 * @param string $path Absolute path to search. 928 * @param string $relative_path The basename of the absolute path. Used to control the returned path 929 * for the found files, particularly when this function recurses to lower depths. 930 * @param array|string $extensions Array of extensions to find, or string of a single extension. 931 * @depth int How deep to search for files. Optional, defaults to a flat scan (0 depth). 932 */ 933 private static function scandir( $path, $relative_path, $extensions, $depth = 0 ) { 934 if ( is_array( $extensions ) ) 935 $extensions = implode( '|', $extensions ); 936 937 if ( ! is_dir( $path ) ) 938 return false; 939 940 $results = scandir( $path ); 941 $files = array(); 942 943 foreach ( $results as $result ) { 944 if ( '.' == $result || '..' == $result ) 945 continue; 946 if ( is_dir( $path . '/' . $result ) ) { 947 if ( ! $depth ) 948 continue; 949 $found = self::scandir( $path . '/' . $result, $relative_path . '/' . $result, $extensions, $depth - 1 ); 950 $files = array_merge_recursive( $files, $found ); 951 } elseif ( preg_match( '~\.(' . $extensions . ')$~', $result, $match ) ) { 952 if ( ! isset( $files[ $match[1] ] ) ) 953 $files[ $match[1] ] = array( $relative_path . '/'. $result ); 954 else 955 $files[ $match[1] ][] = $relative_path . '/' . $result; 956 } 957 } 958 return $files; 959 } 960 961 /** 962 * Loads the theme's textdomain. 963 * 964 * Translation files are not inherited from the parent theme. Todo: if this fails for the 965 * child theme, it should probably try to load the parent theme's translations. 966 * 967 * @since 3.4.0 968 * @access public 969 * 970 * @return True if the textdomain was successfully loaded or has already been loaded. False if 971 * no textdomain was specified in the file headers, or if the domain could not be loaded. 972 */ 973 public function load_textdomain() { 974 if ( isset( $this->textdomain_loaded ) ) 975 return $this->textdomain_loaded; 976 977 $textdomain = $this->get('TextDomain'); 978 if ( ! $textdomain ) { 979 $this->textdomain_loaded = false; 980 return false; 981 } 982 983 if ( is_textdomain_loaded( $textdomain ) ) { 984 $this->textdomain_loaded = true; 985 return true; 986 } 987 988 $path = $this->get_stylesheet_directory(); 989 if ( $domainpath = $this->get('DomainPath') ) 990 $path .= $domainpath; 991 992 $this->textdomain_loaded = load_theme_textdomain( $textdomain, $path ); 993 return $this->textdomain_loaded; 994 } 995 996 /** 997 * Whether the theme is allowed (multisite only). 998 * 999 * @since 3.4.0 1000 * @access public 1001 * 1002 * @param string $check Optional. Whether to check only the 'network'-wide settings, the 'site' 1003 * settings, or 'both'. Defaults to 'both'. 1004 * @param int $blog_id Optional. Ignored if only network-wide settings are checked. Defaults to current blog. 1005 * @return bool Whether the theme is allowed for the network. Returns true in single-site. 1006 */ 1007 public function is_allowed( $check = 'both', $blog_id = null ) { 1008 if ( ! is_multisite() ) 1009 return true; 1010 1011 if ( 'both' == $check || 'network' == $check ) { 1012 $allowed = self::get_allowed_on_network(); 1013 if ( ! empty( $allowed[ $this->get_stylesheet() ] ) ) 1014 return true; 1015 } 1016 1017 if ( 'both' == $check || 'site' == $check ) { 1018 $allowed = self::get_allowed_on_site( $blog_id ); 1019 if ( ! empty( $allowed[ $this->get_stylesheet() ] ) ) 1020 return true; 1021 } 1022 1023 return false; 1024 } 1025 1026 /** 1027 * Returns array of stylesheet names of themes allowed on the site or network. 1028 * 1029 * @since 3.4.0 1030 * @access public 1031 * 1032 * @param int $blog_id Optional. Defaults to current blog. 1033 * @return array Array of stylesheet names. 1034 */ 1035 public static function get_allowed( $blog_id = null ) { 1036 return array_merge( self::get_allowed_on_network(), self::get_allowed_on_site( $blog_id ) ); 1037 } 1038 1039 /** 1040 * Returns array of stylesheet names of themes allowed on the network. 1041 * 1042 * @since 3.4.0 1043 * @access public 1044 * 1045 * @return array Array of stylesheet names. 1046 */ 1047 public static function get_allowed_on_network() { 1048 static $allowed_themes; 1049 if ( ! isset( $allowed_themes ) ) 1050 $allowed_themes = (array) get_site_option( 'allowedthemes' ); 1051 return $allowed_themes; 1052 } 1053 1054 /** 1055 * Returns array of stylesheet names of themes allowed on the site. 1056 * 1057 * @since 3.4.0 1058 * @access public 1059 * 1060 * @param int $blog_id Optional. Defaults to current blog. 1061 * @return array Array of stylesheet names. 1062 */ 1063 public static function get_allowed_on_site( $blog_id = null ) { 1064 static $allowed_themes = array(); 1065 if ( ! $blog_id ) 1066 $blog_id = get_current_blog_id(); 1067 1068 if ( ! isset( $allowed_themes[ $blog_id ] ) ) { 1069 if ( $blog_id == get_current_blog_id() ) 1070 $allowed_themes[ $blog_id ] = (array) get_option( 'allowedthemes' ); 1071 else 1072 $allowed_themes[ $blog_id ] = (array) get_blog_option( $blog_id, 'allowedthemes' ); 1073 } 1074 1075 return $allowed_themes[ $blog_id ]; 1076 } 1077 1078 /** 1079 * Sort themes by name. 1080 */ 1081 public static function sort_by_name( &$themes ) { 1082 if ( 0 === strpos( get_locale(), 'en_' ) ) { 1083 uasort( $themes, array( 'WP_Theme', '_name_sort' ) ); 1084 } else { 1085 uasort( $themes, array( 'WP_Theme', '_name_sort_i18n' ) ); 1086 } 1087 } 1088 1089 /** 1090 * Callback function for usort() to naturally sort themes by name. 1091 * 1092 * Accesses the Name header directly from the class for maximum speed. 1093 * Would choke on HTML but we don't care enough to slow it down with strip_tags(). 1094 * 1095 * @since 3.4.0 1096 * @access public 1097 */ 1098 private static function _name_sort( $a, $b ) { 1099 return strnatcasecmp( $a->headers['Name'], $b->headers['Name'] ); 1100 } 1101 1102 /** 1103 * Name sort (with translation). 1104 * 1105 * @since 3.4.0 1106 * @access public 1107 */ 1108 private static function _name_sort_i18n( $a, $b ) { 1109 // Don't mark up; Do translate. 1110 return strnatcasecmp( $a->display( 'Name', false, true ), $b->display( 'Name', false, true ) ); 1111 } 1112 } 1113 No newline at end of file -
wp-includes/theme.php
7 7 */ 8 8 9 9 /** 10 * Returns an array of WP_Theme objects based on the arguments. 11 * 12 * Despite advances over get_themes(), this function is still quite expensive, and grows 13 * linearly with additional themes. Stick to wp_get_theme() if possible. 14 * 15 * @since 3.4.0 16 * 17 * @param array $args Arguments. Currently 'errors' (defaults to false), 'allowed' 18 * (true, false; null for either; defaults to null; only applies to multisite), and 'blog_id' 19 * (defaults to current blog; used to find allowed themes; only applies to multisite). 20 * @return Array of WP_Theme objects. 21 */ 22 function wp_get_themes( $args = array() ) { 23 $defaults = array( 'errors' => false, 'allowed' => null, 'blog_id' => 0 ); 24 $args = wp_parse_args( $args, $defaults ); 25 26 static $_themes; 27 if ( ! isset( $_themes ) ) { 28 $theme_data = search_theme_directories(); 29 // Make sure the current theme wins out, in case search_theme_directories() picks the wrong 30 // one in the case of a conflict. (Normally, last registered theme root wins.) 31 $current_theme = get_stylesheet(); 32 $current_theme_root = get_raw_theme_root( $current_theme ); 33 foreach ( $theme_data as $theme_slug => $data ) { 34 if ( $current_theme == $theme_slug && $current_theme_root != $data['theme_root'] ) 35 $_themes[ $theme_slug ] = new WP_Theme( $theme_slug, $current_theme_root ); 36 else 37 $_themes[ $theme_slug ] = new WP_Theme( $theme_slug, $data['theme_root'] ); 38 } 39 } 40 41 $themes = $_themes; 42 43 if ( null !== $args['errors'] ) { 44 foreach ( $themes as $theme_slug => $theme ) { 45 if ( $theme->errors() != $args['errors'] ) 46 unset( $themes[ $theme_slug ] ); 47 } 48 } 49 50 if ( is_multisite() && null !== $args['allowed'] ) { 51 if ( $allowed = $args['allowed'] ) { 52 $allowed = 'network' == $allowed || 'site' == $allowed ? $allowed : 'both'; 53 $themes = array_intersect_key( $themes, WP_Theme::get_allowed( $allowed, $args['blog_id'] ) ); 54 } else { 55 $themes = array_diff_key( $themes, WP_Theme::get_allowed( 'both', $args['blog_id'] ) ); 56 } 57 } 58 59 return $themes; 60 } 61 62 /** 63 * Gets a WP_Theme object for a theme. 64 * 65 * @since 3.4.0 66 * 67 * @param string $stylesheet Directory name for the theme. Optional. Defaults to current theme. 68 * @param string $theme_root Theme root to look in. Optional. If not specified, get_raw_theme_root() 69 * is used for the $stylesheet provided (or current theme). 70 * @return WP_Theme 71 */ 72 function wp_get_theme( $stylesheet = null, $theme_root = null ) { 73 if ( empty( $stylesheet ) ) 74 $stylesheet = get_stylesheet(); 75 76 if ( empty( $theme_root ) ) 77 $theme_root = get_raw_theme_root( $stylesheet ); 78 79 return new WP_Theme( $stylesheet, $theme_root ); 80 } 81 82 /** 10 83 * Whether a child theme is in use. 11 84 * 12 85 * @since 3.0.0 … … 247 320 } 248 321 249 322 /** 250 * Retrieve list of themes with theme data in theme directory.251 *252 * The theme is broken, if it doesn't have a parent theme and is missing either253 * style.css and, or index.php. If the theme has a parent theme then it is254 * broken, if it is missing style.css; index.php is optional. The broken theme255 * list is saved in the {@link $wp_broken_themes} global, which is displayed on256 * the theme list in the administration panels.257 *258 * @since 1.5.0259 * @global array $wp_broken_themes Stores the broken themes.260 * @global array $wp_themes Stores the working themes.261 *262 * @return array Theme list with theme data.263 */264 function get_themes() {265 global $wp_themes, $wp_broken_themes;266 267 if ( isset($wp_themes) )268 return $wp_themes;269 270 if ( !$theme_files = search_theme_directories() )271 return false;272 273 asort( $theme_files );274 275 $wp_themes = array();276 277 foreach ( (array) $theme_files as $theme_file ) {278 $theme_root = $theme_file['theme_root'];279 $theme_file = $theme_file['theme_file'];280 281 if ( !is_readable("$theme_root/$theme_file") ) {282 $wp_broken_themes[$theme_file] = array('Name' => $theme_file, 'Title' => $theme_file, 'Description' => __('File not readable.'));283 continue;284 }285 286 $theme_data = get_theme_data("$theme_root/$theme_file");287 288 $name = $theme_data['Name'];289 $title = $theme_data['Title'];290 $description = wptexturize($theme_data['Description']);291 $version = $theme_data['Version'];292 $author = $theme_data['Author'];293 $template = $theme_data['Template'];294 $stylesheet = dirname($theme_file);295 296 $screenshot = false;297 foreach ( array('png', 'gif', 'jpg', 'jpeg') as $ext ) {298 if (file_exists("$theme_root/$stylesheet/screenshot.$ext")) {299 $screenshot = "screenshot.$ext";300 break;301 }302 }303 304 if ( empty($name) ) {305 $name = dirname($theme_file);306 $title = $name;307 }308 309 $parent_template = $template;310 311 if ( empty($template) ) {312 if ( file_exists("$theme_root/$stylesheet/index.php") )313 $template = $stylesheet;314 else315 continue;316 }317 318 $template = trim( $template );319 320 if ( !file_exists("$theme_root/$template/index.php") ) {321 $parent_dir = dirname(dirname($theme_file));322 if ( file_exists("$theme_root/$parent_dir/$template/index.php") ) {323 $template = "$parent_dir/$template";324 $template_directory = "$theme_root/$template";325 } else {326 /**327 * The parent theme doesn't exist in the current theme's folder or sub folder328 * so lets use the theme root for the parent template.329 */330 if ( isset($theme_files[$template]) && file_exists( $theme_files[$template]['theme_root'] . "/$template/index.php" ) ) {331 $template_directory = $theme_files[$template]['theme_root'] . "/$template";332 } else {333 if ( empty( $parent_template) )334 $wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => __('Template is missing.'), 'error' => 'no_template');335 else336 $wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => sprintf( __('The parent theme is missing. Please install the "%s" parent theme.'), $parent_template ), 'error' => 'no_parent', 'parent' => $parent_template );337 continue;338 }339 340 }341 } else {342 $template_directory = trim( $theme_root . '/' . $template );343 }344 345 $stylesheet_files = array();346 $template_files = array();347 348 $stylesheet_dir = @ dir("$theme_root/$stylesheet");349 if ( $stylesheet_dir ) {350 while ( ($file = $stylesheet_dir->read()) !== false ) {351 if ( !preg_match('|^\.+$|', $file) ) {352 if ( preg_match('|\.css$|', $file) )353 $stylesheet_files[] = "$theme_root/$stylesheet/$file";354 elseif ( preg_match('|\.php$|', $file) )355 $template_files[] = "$theme_root/$stylesheet/$file";356 }357 }358 @ $stylesheet_dir->close();359 }360 361 $template_dir = @ dir("$template_directory");362 if ( $template_dir ) {363 while ( ($file = $template_dir->read()) !== false ) {364 if ( preg_match('|^\.+$|', $file) )365 continue;366 if ( preg_match('|\.php$|', $file) ) {367 $template_files[] = "$template_directory/$file";368 } elseif ( is_dir("$template_directory/$file") ) {369 $template_subdir = @ dir("$template_directory/$file");370 if ( !$template_subdir )371 continue;372 while ( ($subfile = $template_subdir->read()) !== false ) {373 if ( preg_match('|^\.+$|', $subfile) )374 continue;375 if ( preg_match('|\.php$|', $subfile) )376 $template_files[] = "$template_directory/$file/$subfile";377 }378 @ $template_subdir->close();379 }380 }381 @ $template_dir->close();382 }383 384 //Make unique and remove duplicates when stylesheet and template are the same i.e. most themes385 $template_files = array_unique($template_files);386 $stylesheet_files = array_unique($stylesheet_files);387 388 $template_dir = $template_directory;389 $stylesheet_dir = $theme_root . '/' . $stylesheet;390 391 if ( empty($template_dir) )392 $template_dir = '/';393 if ( empty($stylesheet_dir) )394 $stylesheet_dir = '/';395 396 // Check for theme name collision. This occurs if a theme is copied to397 // a new theme directory and the theme header is not updated. Whichever398 // theme is first keeps the name. Subsequent themes get a suffix applied.399 // Default themes themes always trump their pretenders.400 if ( isset($wp_themes[$name]) ) {401 $trump_cards = array(402 'classic' => 'WordPress Classic',403 'default' => 'WordPress Default',404 'twentyten' => 'Twenty Ten',405 'twentyeleven' => 'Twenty Eleven',406 'twentytwelve' => 'Twenty Twelve',407 );408 if ( isset( $trump_cards[ $stylesheet ] ) && $name == $trump_cards[ $stylesheet ] ) {409 // If another theme has claimed to be one of our default themes, move410 // them aside.411 $suffix = $wp_themes[$name]['Stylesheet'];412 $new_name = "$name/$suffix";413 $wp_themes[$new_name] = $wp_themes[$name];414 $wp_themes[$new_name]['Name'] = $new_name;415 } else {416 $name = "$name/$stylesheet";417 }418 }419 420 $theme_roots[$stylesheet] = str_replace( WP_CONTENT_DIR, '', $theme_root );421 $wp_themes[$name] = array(422 'Name' => $name,423 'Title' => $title,424 'Description' => $description,425 'Author' => $author,426 'Author Name' => $theme_data['AuthorName'],427 'Author URI' => $theme_data['AuthorURI'],428 'Version' => $version,429 'Template' => $template,430 'Stylesheet' => $stylesheet,431 'Template Files' => $template_files,432 'Stylesheet Files' => $stylesheet_files,433 'Template Dir' => $template_dir,434 'Stylesheet Dir' => $stylesheet_dir,435 'Status' => $theme_data['Status'],436 'Screenshot' => $screenshot,437 'Tags' => $theme_data['Tags'],438 'Theme Root' => $theme_root,439 'Theme Root URI' => str_replace( WP_CONTENT_DIR, content_url(), $theme_root ),440 );441 }442 443 unset($theme_files);444 445 /* Store theme roots in the DB */446 if ( get_site_transient( 'theme_roots' ) != $theme_roots )447 set_site_transient( 'theme_roots', $theme_roots, 7200 ); // cache for two hours448 unset($theme_roots);449 450 /* Resolve theme dependencies. */451 $theme_names = array_keys( $wp_themes );452 foreach ( (array) $theme_names as $theme_name ) {453 $wp_themes[$theme_name]['Parent Theme'] = '';454 if ( $wp_themes[$theme_name]['Stylesheet'] != $wp_themes[$theme_name]['Template'] ) {455 foreach ( (array) $theme_names as $parent_theme_name ) {456 if ( ($wp_themes[$parent_theme_name]['Stylesheet'] == $wp_themes[$parent_theme_name]['Template']) && ($wp_themes[$parent_theme_name]['Template'] == $wp_themes[$theme_name]['Template']) ) {457 $wp_themes[$theme_name]['Parent Theme'] = $wp_themes[$parent_theme_name]['Name'];458 break;459 }460 }461 }462 }463 464 return $wp_themes;465 }466 467 /**468 323 * Retrieve theme roots. 469 324 * 470 325 * @since 2.9.0 … … 479 334 480 335 $theme_roots = get_site_transient( 'theme_roots' ); 481 336 if ( false === $theme_roots ) { 482 get_themes();483 $theme_roots = get_site_transient( 'theme_roots' ); // this is set in get_theme()337 search_theme_directories(); // Regenerated the transient. 338 $theme_roots = get_site_transient( 'theme_roots' ); 484 339 } 485 340 return $theme_roots; 486 341 } 487 342 488 343 /** 489 * Retrieve theme data.490 *491 * @since 1.5.0492 *493 * @param string $theme Theme name.494 * @return array|null Null, if theme name does not exist. Theme data, if exists.495 */496 function get_theme($theme) {497 $themes = get_themes();498 499 if ( is_array( $themes ) && array_key_exists( $theme, $themes ) )500 return $themes[$theme];501 502 return null;503 }504 505 /**506 344 * Retrieve current theme display name. 507 345 * 508 * If the 'current_theme' option has already been set, then it will be returned509 * instead. If it is not set, then each theme will be iterated over until both510 * the current stylesheet and current template name.511 *512 346 * @since 1.5.0 513 347 * 514 348 * @return string 515 349 */ 516 350 function get_current_theme() { 517 if ( $theme = get_option('current_theme') ) 518 return $theme; 519 520 $themes = get_themes(); 521 $current_theme = 'Twenty Eleven'; 522 523 if ( $themes ) { 524 $theme_names = array_keys( $themes ); 525 $current_template = get_option( 'template' ); 526 $current_stylesheet = get_option( 'stylesheet' ); 527 528 foreach ( (array) $theme_names as $theme_name ) { 529 if ( $themes[$theme_name]['Stylesheet'] == $current_stylesheet && 530 $themes[$theme_name]['Template'] == $current_template ) { 531 $current_theme = $themes[$theme_name]['Name']; 532 break; 533 } 534 } 535 } 536 537 update_option('current_theme', $current_theme); 538 539 return $current_theme; 351 $theme = wp_get_theme(); 352 return $theme->get('Name'); 540 353 } 541 354 542 355 /** … … 571 384 * @return array Valid themes found 572 385 */ 573 386 function search_theme_directories() { 574 global $wp_theme_directories , $wp_broken_themes;387 global $wp_theme_directories; 575 388 if ( empty( $wp_theme_directories ) ) 576 389 return false; 577 390 578 $theme_files = array(); 579 $wp_broken_themes = array(); 391 static $found_themes; 392 if ( isset( $found_themes ) ) 393 return $found_themes; 394 $found_themes = array(); 580 395 396 if ( apply_filters( 'wp_cache_themes_persistently', false ) ) { 397 $cached_roots = get_site_transient( 'theme_roots' ); 398 if ( is_array( $cached_roots ) ) { 399 foreach ( $cached_roots as $theme_dir => $theme_root ) { 400 $found_themes[ $theme_dir ] = array( 401 'theme_file' => $theme_dir . '/style.css', 402 'theme_root' => $theme_root, 403 ); 404 } 405 return $found_themes; 406 } 407 } 408 581 409 /* Loop the registered theme directories and extract all themes */ 582 410 foreach ( (array) $wp_theme_directories as $theme_root ) { 583 $theme_loc = $theme_root;584 411 585 /* We don't want to replace all forward slashes, see Trac #4541 */ 586 if ( '/' != WP_CONTENT_DIR ) 587 $theme_loc = str_replace(WP_CONTENT_DIR, '', $theme_root); 588 589 /* Files in the root of the current theme directory and one subdir down */ 590 $themes_dir = @ opendir($theme_root); 591 592 if ( !$themes_dir ) 412 // Start with directories in the root of the current theme directory. 413 $dirs = @ scandir( $theme_root ); 414 if ( ! $dirs ) 593 415 return false; 594 595 while ( ($theme_dir = readdir($themes_dir)) !== false ) { 596 if ( is_dir($theme_root . '/' . $theme_dir) && is_readable($theme_root . '/' . $theme_dir) ) { 597 if ( $theme_dir[0] == '.' || $theme_dir == 'CVS' ) 598 continue; 599 600 $stylish_dir = @opendir($theme_root . '/' . $theme_dir); 601 $found_stylesheet = false; 602 603 while ( ($theme_file = readdir($stylish_dir)) !== false ) { 604 if ( $theme_file == 'style.css' ) { 605 $theme_files[$theme_dir] = array( 'theme_file' => $theme_dir . '/' . $theme_file, 'theme_root' => $theme_root ); 606 $found_stylesheet = true; 607 break; 608 } 416 foreach ( $dirs as $dir ) { 417 if ( ! is_dir( $theme_root . '/' . $dir ) || $dir[0] == '.' || $dir == 'CVS' ) 418 continue; 419 if ( file_exists( $theme_root . '/' . $dir . '/style.css' ) ) { 420 // wp-content/themes/a-single-theme 421 // wp-content/themes is $theme_root, a-single-theme is $dir 422 $found_themes[ $dir ] = array( 423 'theme_file' => $dir . '/style.css', 424 'theme_root' => $theme_root, 425 ); 426 } else { 427 $found_theme = false; 428 // wp-content/themes/a-folder-of-themes/* 429 // wp-content/themes is $theme_root, a-folder-of-themes is $dir, then themes are $sub_dirs 430 $sub_dirs = @ scandir( $theme_root . '/' . $dir ); 431 if ( ! $sub_dirs ) 432 return false; 433 foreach ( $sub_dirs as $sub_dir ) { 434 if ( ! is_dir( $theme_root . '/' . $dir ) || $dir[0] == '.' || $dir == 'CVS' ) 435 continue; 436 if ( ! file_exists( $theme_root . '/' . $dir . '/' . $sub_dir . '/style.css' ) ) 437 continue; 438 $found_themes[ $dir . '/' . $sub_dir ] = array( 439 'theme_file' => $dir . '/' . $sub_dir . '/style.css', 440 'theme_root' => $theme_root, 441 ); 442 $found_theme = true; 609 443 } 610 @closedir($stylish_dir); 444 // Never mind the above, it's just a theme missing a style.css. 445 // Return it; WP_Theme will catch the error. 446 if ( ! $found_theme ) 447 $found_themes[ $dir ] = array( 448 'theme_file' => $dir . '/style.css', 449 'theme_root' => $theme_root, 450 ); 451 } 452 } 453 } 611 454 612 if ( !$found_stylesheet ) { // look for themes in that dir 613 $subdir = "$theme_root/$theme_dir"; 614 $subdir_name = $theme_dir; 615 $theme_subdirs = @opendir( $subdir ); 455 asort( $found_themes ); 616 456 617 $found_subdir_themes = false; 618 while ( ($theme_subdir = readdir($theme_subdirs)) !== false ) { 619 if ( is_dir( $subdir . '/' . $theme_subdir) && is_readable($subdir . '/' . $theme_subdir) ) { 620 if ( $theme_subdir[0] == '.' || $theme_subdir == 'CVS' ) 621 continue; 457 $theme_roots = array(); 458 foreach ( $found_themes as $theme_dir => $theme_data ) { 459 $theme_roots[ $theme_dir ] = $theme_data['theme_root']; 460 } 622 461 623 $stylish_dir = @opendir($subdir . '/' . $theme_subdir);624 $found_stylesheet = false;462 if ( $theme_roots != get_site_transient( 'theme_roots' ) ) 463 set_site_transient( 'theme_roots', $theme_roots, 7200 ); // cache for two hours 625 464 626 while ( ($theme_file = readdir($stylish_dir)) !== false ) { 627 if ( $theme_file == 'style.css' ) { 628 $theme_files["$theme_dir/$theme_subdir"] = array( 'theme_file' => $subdir_name . '/' . $theme_subdir . '/' . $theme_file, 'theme_root' => $theme_root ); 629 $found_stylesheet = true; 630 $found_subdir_themes = true; 631 break; 632 } 633 } 634 @closedir($stylish_dir); 635 } 636 } 637 @closedir($theme_subdirs); 638 if ( !$found_subdir_themes ) 639 $wp_broken_themes[$theme_dir] = array('Name' => $theme_dir, 'Title' => $theme_dir, 'Description' => __('Stylesheet is missing.')); 640 } 641 } 642 } 643 @closedir( $themes_dir ); 644 } 645 return $theme_files; 465 return $found_themes; 646 466 } 647 467 648 468 /** -
wp-includes/deprecated.php
2906 2906 */ 2907 2907 function debug_fclose( $fp ) { 2908 2908 _deprecated_function( __FUNCTION__, 'error_log()' ); 2909 } 2910 2911 /** 2912 * Retrieve list of themes with theme data in theme directory. 2913 * 2914 * The theme is broken, if it doesn't have a parent theme and is missing either 2915 * style.css and, or index.php. If the theme has a parent theme then it is 2916 * broken, if it is missing style.css; index.php is optional. 2917 * 2918 * @since 1.5.0 2919 * @global array $wp_themes Stores the working themes. 2920 * 2921 * @return array Theme list with theme data. 2922 */ 2923 function get_themes() { 2924 _deprecated_function( __FUNCTION__, '3.4', 'wp_get_themes()' ); 2925 2926 global $wp_themes; 2927 if ( isset( $wp_themes ) ) 2928 return $wp_themes; 2929 2930 $themes = wp_get_themes(); 2931 $wp_themes = array(); 2932 2933 foreach ( $themes as $theme ) { 2934 $wp_themes[ $theme->get('Name') ] = $theme; 2935 } 2936 2937 return $wp_themes; 2938 } 2939 2940 /** 2941 * Retrieve theme data. 2942 * 2943 * @since 1.5.0 2944 * 2945 * @param string $theme Theme name. 2946 * @return array|null Null, if theme name does not exist. Theme data, if exists. 2947 */ 2948 function get_theme( $theme ) { 2949 _deprecated_function( __FUNCTION__, '3.4', 'wp_get_theme($stylesheet)' ); 2950 2951 $themes = get_themes(); 2952 if ( is_array( $themes ) && array_key_exists( $theme, $themes ) ) 2953 return $themes[$theme]; 2954 return null; 2909 2955 } 2956 No newline at end of file -
wp-settings.php
112 112 require( ABSPATH . WPINC . '/capabilities.php' ); 113 113 require( ABSPATH . WPINC . '/query.php' ); 114 114 require( ABSPATH . WPINC . '/theme.php' ); 115 require( ABSPATH . WPINC . '/class-wp-theme.php' ); 115 116 require( ABSPATH . WPINC . '/template.php' ); 116 117 require( ABSPATH . WPINC . '/user.php' ); 117 118 require( ABSPATH . WPINC . '/meta.php' ); -
wp-admin/includes/ms-deprecated.php
64 64 _deprecated_function(__FUNCTION__, '3.0', 'is_network_only_plugin()' ); 65 65 return is_network_only_plugin( $file ); 66 66 } 67 68 function get_site_allowed_themes() { 69 _deprecated_function( __FUNCTION__, '3.4', 'WP_Theme::get_allowed_on_network()' ); 70 return array_map( 'intval', WP_Theme::get_allowed_on_network() ); 71 } 72 73 function wpmu_get_blog_allowedthemes( $blog_id = 0 ) { 74 _deprecated_function( __FUNCTION__, '3.4', 'WP_Theme::get_allowed_on_site()' ); 75 return array_map( 'intval', WP_Theme::get_allowed_on_site( $blog_id ) ); 76 } 77 No newline at end of file -
wp-admin/includes/update.php
217 217 } 218 218 219 219 function get_theme_updates() { 220 $themes = get_themes();220 $themes = wp_get_themes(); 221 221 $current = get_site_transient('update_themes'); 222 222 $update_themes = array(); 223 223 224 foreach ( $themes as $theme ) { 225 $theme = (object) $theme; 226 if ( isset($current->response[ $theme->Stylesheet ]) ) { 227 $update_themes[$theme->Stylesheet] = $theme; 228 $update_themes[$theme->Stylesheet]->update = $current->response[ $theme->Stylesheet ]; 229 } 224 foreach ( $current->response as $stylesheet => $data ) { 225 $update_themes[ $stylesheet ] = wp_get_theme( $stylesheet ); 226 $update_themes[ $stylesheet ]->update = $data; 230 227 } 231 228 232 229 return $update_themes; -
wp-admin/includes/upgrade.php
459 459 if ( $wp_current_db_version < 19389 ) 460 460 upgrade_330(); 461 461 462 if ( $wp_current_db_version < 19799)462 if ( $wp_current_db_version < 20002 ) 463 463 upgrade_340(); 464 464 465 465 maybe_disable_automattic_widgets(); … … 1154 1154 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key IN ('show_admin_bar_admin', 'plugins_last_view')" ); 1155 1155 } 1156 1156 1157 // 3.3-beta. Can remove before release.1158 if ( $wp_current_db_version > 18715 && $wp_current_db_version < 193891159 && is_main_site() && ! defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) )1160 delete_metadata( 'user', 0, 'dismissed_wp_pointers', '', true );1161 1162 1157 if ( $wp_current_db_version >= 11548 ) 1163 1158 return; 1164 1159 … … 1235 1230 $wpdb->query("ALTER TABLE $wpdb->comments DROP INDEX comment_approved"); 1236 1231 $wpdb->show_errors(); 1237 1232 } 1233 1234 if ( $wp_current_db_version < 20002 && is_main_site() && ! defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) { 1235 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key = 'themes_last_view'" ); 1236 } 1238 1237 } 1239 1238 1240 1239 /** -
wp-admin/includes/class-wp-ms-themes-list-table.php
15 15 function __construct() { 16 16 global $status, $page; 17 17 18 $default_status = get_user_option( 'themes_last_view' ); 19 if ( empty( $default_status ) ) 20 $default_status = 'all'; 21 $status = isset( $_REQUEST['theme_status'] ) ? $_REQUEST['theme_status'] : $default_status; 22 if ( !in_array( $status, array( 'all', 'enabled', 'disabled', 'upgrade', 'search' ) ) ) 18 $status = isset( $_REQUEST['theme_status'] ) ? $_REQUEST['theme_status'] : 'all'; 19 if ( ! in_array( $status, array( 'all', 'enabled', 'disabled', 'upgrade', 'search' ) ) ) 23 20 $status = 'all'; 24 if ( $status != $default_status && 'search' != $status )25 update_user_meta( get_current_user_id(), 'themes_last_view', $status );26 21 27 22 $page = $this->get_pagenum(); 28 23 … … 55 50 } 56 51 57 52 function prepare_items() { 58 global $status, $t hemes, $totals, $page, $orderby, $order, $s;53 global $status, $totals, $page, $orderby, $order, $s; 59 54 60 55 wp_reset_vars( array( 'orderby', 'order', 's' ) ); 61 56 62 57 $themes = array( 63 'all' => apply_filters( 'all_themes', get_themes() ),58 'all' => apply_filters( 'all_themes', wp_get_themes() ), 64 59 'search' => array(), 65 60 'enabled' => array(), 66 61 'disabled' => array(), 67 62 'upgrade' => array() 68 63 ); 69 64 70 $site_allowed_themes = get_site_allowed_themes(); 71 if ( !$this->is_site_themes ) { 72 $allowed_themes = $site_allowed_themes; 73 $themes_per_page = $this->get_items_per_page( 'themes_network_per_page' ); 74 } else { 75 $allowed_themes = wpmu_get_blog_allowedthemes( $this->site_id ); 65 if ( $this->is_site_themes ) { 76 66 $themes_per_page = $this->get_items_per_page( 'site_themes_network_per_page' ); 67 $allowed_where = 'site'; 68 } else { 69 $themes_per_page = $this->get_items_per_page( 'themes_network_per_page' ); 70 $allowed_where = 'network'; 77 71 } 78 72 79 $current = get_site_transient( 'update_themes' );73 $current = current_user_can( 'update_themes' ) && ! $this->is_site_themes && get_site_transient( 'update_themes' ); 80 74 81 75 foreach ( (array) $themes['all'] as $key => $theme ) { 82 $theme_key = $theme['Stylesheet']; 83 84 if ( isset( $allowed_themes [ $theme_key ] ) ) { 85 $themes['all'][$key]['enabled'] = true; 86 $themes['enabled'][$key] = $themes['all'][$key]; 76 if ( $this->is_site_themes && $theme->is_allowed( 'network' ) ) { 77 unset( $themes['all'][ $key ] ); 78 continue; 87 79 } 88 else {89 $themes['all'][$key]['enabled'] = false;90 $themes['disabled'][$key] = $themes['all'][$key];91 }92 if ( isset( $current->response[ $theme['Template'] ] ) )93 $themes['upgrade'][$key] = $themes['all'][$key];94 80 95 if ( $this->is_site_themes && isset( $site_allowed_themes[$theme_key] ) ) {96 unset( $themes['all'][$key] );97 unset( $themes['enabled'][$key] ); 98 unset( $themes['disabled'][$key] );99 }81 $filter = $theme->is_allowed( $allowed_where, $this->site_id ) ? 'enabled' : 'disabled'; 82 $themes[ $filter ][ $key ] = $themes['all'][ $key ]; 83 84 if ( $current && isset( $current->response[ $key ] ) ) 85 $themes['upgrade'][ $key ] = $themes['all'][ $key ]; 100 86 } 101 87 102 if ( !current_user_can( 'update_themes' ) || $this->is_site_themes )103 $themes['upgrade'] = array();104 105 88 if ( $s ) { 106 89 $status = 'search'; 107 90 $themes['search'] = array_filter( $themes['all'], array( &$this, '_search_callback' ) ); … … 115 98 $status = 'all'; 116 99 117 100 $this->items = $themes[ $status ]; 101 WP_Theme::sort_by_name( $this->items ); 102 103 $this->has_items = ! empty( $themes['all'] ); 118 104 $total_this_page = $totals[ $status ]; 119 105 120 106 if ( $orderby ) { 121 107 $orderby = ucfirst( $orderby ); 122 108 $order = strtoupper( $order ); 123 109 124 uasort( $this->items, array( &$this, '_order_callback' ) ); 110 if ( $orderby == 'Name' ) { 111 if ( 'ASC' == $order ) 112 $this->items = array_reverse( $this->items ); 113 } else { 114 uasort( $this->items, array( &$this, '_order_callback' ) ); 115 } 125 116 } 126 117 127 118 $start = ( $page - 1 ) * $themes_per_page; 128 119 129 120 if ( $total_this_page > $themes_per_page ) 130 $this->items = array_slice( $this->items, $start, $themes_per_page );121 $this->items = array_slice( $this->items, $start, $themes_per_page, true ); 131 122 132 123 $this->set_pagination_args( array( 133 124 'total_items' => $total_this_page, … … 140 131 if ( is_null( $term ) ) 141 132 $term = stripslashes( $_REQUEST['s'] ); 142 133 143 $search_fields = array( 'Name', 'Title', 'Description', 'Author', 'Author Name', 'Author URI', 'Template', 'Stylesheet' );144 foreach ( $search_fields as $field )145 if ( stripos( $theme[ $field ], $term ) !== false)134 foreach ( array( 'Name', 'Description', 'Author', 'Author', 'AuthorURI' ) as $field ) { 135 // Don't mark up; Do translate. 136 if ( false !== stripos( $theme->display( $field, false, true ), $term ) ) 146 137 return true; 138 } 147 139 140 if ( false !== stripos( $theme->get_stylesheet(), $term ) ) 141 return true; 142 143 if ( false !== stripos( $theme->get_template(), $term ) ) 144 return true; 145 148 146 return false; 149 147 } 150 148 149 // Not used by any core columns. 151 150 function _order_callback( $theme_a, $theme_b ) { 152 151 global $orderby, $order; 153 152 154 $a = $theme_a[ $orderby];155 $b = $theme_b[ $orderby];153 $a = $theme_a[ $orderby ]; 154 $b = $theme_b[ $orderby ]; 156 155 157 156 if ( $a == $b ) 158 157 return 0; … … 164 163 } 165 164 166 165 function no_items() { 167 global $themes; 168 169 if ( !empty( $themes['all'] ) ) 166 if ( ! $$this->has_items ) 170 167 _e( 'No themes found.' ); 171 168 else 172 169 _e( 'You do not appear to have any themes available at this time.' ); … … 264 261 265 262 $context = $status; 266 263 267 if ( $this->is_site_themes ) 264 if ( $this->is_site_themes ) { 268 265 $url = "site-themes.php?id={$this->site_id}&"; 269 else 266 $allowed = $theme->is_allowed( 'site', $this->site_id ); 267 } else { 270 268 $url = 'themes.php?'; 269 $allowed = $theme->is_allowed( 'network' ); 270 } 271 271 272 272 // preorder 273 273 $actions = array( … … 277 277 'delete' => '' 278 278 ); 279 279 280 $theme_key = $theme ['Stylesheet'];280 $theme_key = $theme->get_stylesheet(); 281 281 282 if ( empty( $theme['enabled'] ))282 if ( ! $allowed ) 283 283 $actions['enable'] = '<a href="' . esc_url( wp_nonce_url($url . 'action=enable&theme=' . $theme_key . '&paged=' . $page . '&s=' . $s, 'enable-theme_' . $theme_key) ) . '" title="' . esc_attr__('Enable this theme') . '" class="edit">' . ( $this->is_site_themes ? __( 'Enable' ) : __( 'Network Enable' ) ) . '</a>'; 284 284 else 285 285 $actions['disable'] = '<a href="' . esc_url( wp_nonce_url($url . 'action=disable&theme=' . $theme_key . '&paged=' . $page . '&s=' . $s, 'disable-theme_' . $theme_key) ) . '" title="' . esc_attr__('Disable this theme') . '">' . ( $this->is_site_themes ? __( 'Disable' ) : __( 'Network Disable' ) ) . '</a>'; 286 286 287 287 if ( current_user_can('edit_themes') ) 288 $actions['edit'] = '<a href="' . esc_url('theme-editor.php?theme=' . urlencode( $theme['Name'] )) . '" title="' . esc_attr__('Open this theme in the Theme Editor') . '" class="edit">' . __('Edit') . '</a>';288 $actions['edit'] = '<a href="' . esc_url('theme-editor.php?theme=' . $theme_key ) . '" title="' . esc_attr__('Open this theme in the Theme Editor') . '" class="edit">' . __('Edit') . '</a>'; 289 289 290 if ( empty( $theme['enabled'] )&& current_user_can( 'delete_themes' ) && ! $this->is_site_themes && $theme_key != get_option( 'stylesheet' ) && $theme_key != get_option( 'template' ) )290 if ( ! $allowed && current_user_can( 'delete_themes' ) && ! $this->is_site_themes && $theme_key != get_option( 'stylesheet' ) && $theme_key != get_option( 'template' ) ) 291 291 $actions['delete'] = '<a href="' . esc_url( wp_nonce_url( 'themes.php?action=delete-selected&checked[]=' . $theme_key . '&theme_status=' . $context . '&paged=' . $page . '&s=' . $s, 'bulk-themes' ) ) . '" title="' . esc_attr__( 'Delete this theme' ) . '" class="delete">' . __( 'Delete' ) . '</a>'; 292 292 293 293 $actions = apply_filters( 'theme_action_links', array_filter( $actions ), $theme_key, $theme, $context ); 294 294 $actions = apply_filters( "theme_action_links_$theme_key", $actions, $theme_key, $theme, $context ); 295 295 296 $class = empty( $theme['enabled'] )? 'inactive' : 'active';297 $checkbox_id = "checkbox_" . md5( $theme['Name']);298 $checkbox = "<input type='checkbox' name='checked[]' value='" . esc_attr( $theme_key ) . "' id='" . $checkbox_id . "' /><label class='screen-reader-text' for='" . $checkbox_id . "' >" . __('Select') . " " . $theme ['Name']. "</label>";296 $class = ! $allowed ? 'inactive' : 'active'; 297 $checkbox_id = "checkbox_" . md5( $theme->get('Name') ); 298 $checkbox = "<input type='checkbox' name='checked[]' value='" . esc_attr( $theme_key ) . "' id='" . $checkbox_id . "' /><label class='screen-reader-text' for='" . $checkbox_id . "' >" . __('Select') . " " . $theme->display('Name') . "</label>"; 299 299 300 $description = '<p>' . $theme['Description'] . '</p>'; 301 $theme_name = $theme['Name']; 300 $description = '<p>' . $theme->display( 'Description' ) . '</p>'; 302 301 303 $id = sanitize_ title( $theme_name);302 $id = sanitize_html_class( $theme->get_stylesheet() ); 304 303 305 304 echo "<tr id='$id' class='$class'>"; 306 305 … … 316 315 echo "<th scope='row' class='check-column'>$checkbox</th>"; 317 316 break; 318 317 case 'name': 319 echo "<td class='theme-title'$style><strong> $theme_name</strong>";318 echo "<td class='theme-title'$style><strong>" . $theme->display('Name') . "</strong>"; 320 319 echo $this->row_actions( $actions, true ); 321 320 echo "</td>"; 322 321 break; 323 322 case 'description': 324 323 echo "<td class='column-description desc'$style> 325 <div class='theme-description'> $description</div>324 <div class='theme-description'>" . $theme->display( 'Description' ) . "</div> 326 325 <div class='$class second theme-version-author-uri'>"; 327 326 328 327 $theme_meta = array(); 329 328 330 if ( !empty( $theme['Version']) )331 $theme_meta[] = sprintf( __( 'Version %s' ), $theme ['Version']);329 if ( $theme->get('Version') ) 330 $theme_meta[] = sprintf( __( 'Version %s' ), $theme->display('Version') ); 332 331 333 if ( !empty( $theme['Author']) )334 $theme_meta[] = sprintf( __( 'By %s' ), $theme ['Author']);332 if ( $theme->get('Author') ) 333 $theme_meta[] = sprintf( __( 'By %s' ), $theme->display('Author') ); 335 334 336 if ( !empty( $theme['Theme URI']) )337 $theme_meta[] = '<a href="' . $theme ['Theme URI']. '" title="' . esc_attr__( 'Visit theme homepage' ) . '">' . __( 'Visit Theme Site' ) . '</a>';335 if ( $theme->get('ThemeURI') ) 336 $theme_meta[] = '<a href="' . $theme->display('ThemeURI') . '" title="' . esc_attr__( 'Visit theme homepage' ) . '">' . __( 'Visit Theme Site' ) . '</a>'; 338 337 339 338 $theme_meta = apply_filters( 'theme_row_meta', $theme_meta, $theme_key, $theme, $status ); 340 339 echo implode( ' | ', $theme_meta ); -
wp-admin/includes/dashboard.php
383 383 echo "\n\t</table>\n\t</div>"; 384 384 385 385 echo "\n\t".'<div class="versions">'; 386 $ ct = current_theme_info();386 $theme = wp_get_theme(); 387 387 388 388 echo "\n\t<p>"; 389 389 390 if ( empty( $ct->stylesheet_dir) ) {390 if ( $theme->errors() ) { 391 391 if ( ! is_multisite() || is_super_admin() ) 392 392 echo '<span class="error-message">' . __('ERROR: The themes directory is either empty or doesn’t exist. Please check your installation.') . '</span>'; 393 393 } elseif ( ! empty($wp_registered_sidebars) ) { … … 401 401 } 402 402 $num = number_format_i18n( $num_widgets ); 403 403 404 $switch_themes = $ ct->title;404 $switch_themes = $theme->display('Name'); 405 405 if ( current_user_can( 'switch_themes') ) 406 406 $switch_themes = '<a href="themes.php">' . $switch_themes . '</a>'; 407 407 if ( current_user_can( 'edit_theme_options' ) ) { … … 411 411 } 412 412 } else { 413 413 if ( current_user_can( 'switch_themes' ) ) 414 printf( __('Theme <span class="b"><a href="themes.php">%1$s</a></span>'), $ ct->title);414 printf( __('Theme <span class="b"><a href="themes.php">%1$s</a></span>'), $theme->display('Name') ); 415 415 else 416 printf( __('Theme <span class="b">%1$s</span>'), $ ct->title);416 printf( __('Theme <span class="b">%1$s</span>'), $theme->display('Name') ); 417 417 } 418 418 echo '</p>'; 419 419 … … 1313 1313 <div class="welcome-panel-column welcome-panel-last"> 1314 1314 <h4><span class="icon16 icon-appearance"></span> <?php _e( 'Customize Your Site' ); ?></h4> 1315 1315 <?php 1316 $ ct = current_theme_info();1317 if ( empty ( $ct->stylesheet_dir) ) :1316 $theme = wp_get_theme(); 1317 if ( $theme->errors() ) : 1318 1318 echo '<p>'; 1319 1319 printf( __( '<a href="%s">Install a theme</a> to get started customizing your site.' ), esc_url( admin_url( 'themes.php' ) ) ); 1320 1320 echo '</p>'; 1321 1321 else: 1322 1322 $customize_links = array(); 1323 if ( 'twentyeleven' == $ ct->stylesheet)1323 if ( 'twentyeleven' == $theme->get_stylesheet() ) 1324 1324 $customize_links[] = sprintf( __( '<a href="%s">Choose light or dark</a>' ), esc_url( admin_url( 'themes.php?page=theme_options' ) ) ); 1325 1325 1326 1326 if ( current_theme_supports( 'custom-background' ) ) … … 1334 1334 1335 1335 if ( ! empty( $customize_links ) ) { 1336 1336 echo '<p>'; 1337 printf( __( 'Use the current theme — %1$s — or <a href="%2$s">choose a new one</a>. If you stick with % 3$s, here are a few ways to make your site look unique.' ), $ct->title, esc_url( admin_url( 'themes.php' ) ), $ct->title);1337 printf( __( 'Use the current theme — %1$s — or <a href="%2$s">choose a new one</a>. If you stick with %1$s, here are a few ways to make your site look unique.' ), $theme->display('Name'), esc_url( admin_url( 'themes.php' ) ) ); 1338 1338 echo '</p>'; 1339 1339 ?> 1340 1340 <ul> … … 1345 1345 <?php 1346 1346 } else { 1347 1347 echo '<p>'; 1348 printf( __( 'Use the current theme — %1$s — or <a href="%2$s">choose a new one</a>.' ), $ ct->title, esc_url( admin_url( 'themes.php' ) ) );1348 printf( __( 'Use the current theme — %1$s — or <a href="%2$s">choose a new one</a>.' ), $this->display('Name'), esc_url( admin_url( 'themes.php' ) ) ); 1349 1349 echo '</p>'; 1350 1350 } 1351 1351 endif; ?> -
wp-admin/includes/deprecated.php
879 879 $screen = convert_to_screen( $screen ); 880 880 881 881 WP_Screen::add_old_compat_help( $screen, $help ); 882 } 883 884 /** 885 * Get the allowed themes for the current blog. 886 * 887 * @since 3.0.0 888 * @deprecated 3.4.0 889 * @deprecated Use wp_get_themes() 890 * @see wp_get_themes() 891 * 892 * @return array $themes Array of allowed themes. 893 */ 894 function get_allowed_themes() { 895 _deprecated_function( __FUNCTION__, '3.4', "wp_get_themes( array( 'allowed' => true ) )" ); 896 897 $themes = wp_get_themes( array( 'allowed' => true ) ); 898 899 $wp_themes = array(); 900 foreach ( $themes as $theme ) { 901 $wp_themes[ $theme->get('Name') ] = $theme; 902 } 903 904 return $wp_themes; 905 } 906 907 /** 908 * {@internal Missing Short Description}} 909 * 910 * @since 1.5.0 911 * 912 * @return unknown 913 */ 914 function get_broken_themes() { 915 _deprecated_function( __FUNCTION__, '3.4', "wp_get_themes( array( 'errors' => true )" ); 916 917 $themes = wp_get_themes( array( 'errors' => true ) ); 918 $broken = array(); 919 foreach ( $themes as $theme ) { 920 $broken[ $theme->get('Name') ] = array( 921 'Title' => $theme->get('Name'), 922 'Description' => $theme->errors()->get_error_message(), 923 ); 924 } 925 return $broken; 926 } 927 928 /** 929 * {@internal Missing Short Description}} 930 * 931 * @since 2.0.0 932 * 933 * @return unknown 934 */ 935 function current_theme_info() { 936 _deprecated_function( __FUNCTION__, '3.4', 'wp_get_theme()' ); 937 938 return wp_get_theme(); 882 939 } 940 No newline at end of file -
wp-admin/includes/schema.php
343 343 344 344 $template = WP_DEFAULT_THEME; 345 345 // If default theme is a child theme, we need to get its template 346 foreach ( (array) get_themes() as $theme ) { 347 if ( WP_DEFAULT_THEME == $theme['Stylesheet'] ) { 348 $template = $theme['Template']; 349 break; 350 } 351 } 346 $theme = wp_get_theme( $template ); 347 if ( ! $theme->errors() ) 348 $template = $theme->get_template(); 352 349 353 350 $timezone_string = ''; 354 351 $gmt_offset = 0; -
wp-admin/includes/theme.php
7 7 */ 8 8 9 9 /** 10 * {@internal Missing Short Description}}11 *12 * @since 2.0.013 *14 * @return unknown15 */16 function current_theme_info() {17 $themes = get_themes();18 $current_theme = get_current_theme();19 20 if ( ! $themes ) {21 $ct = new stdClass;22 $ct->name = $current_theme;23 return $ct;24 }25 26 if ( ! isset( $themes[$current_theme] ) ) {27 delete_option( 'current_theme' );28 $current_theme = get_current_theme();29 }30 31 $ct = new stdClass;32 $ct->name = $current_theme;33 $ct->title = $themes[$current_theme]['Title'];34 $ct->version = $themes[$current_theme]['Version'];35 $ct->parent_theme = $themes[$current_theme]['Parent Theme'];36 $ct->template_dir = $themes[$current_theme]['Template Dir'];37 $ct->stylesheet_dir = $themes[$current_theme]['Stylesheet Dir'];38 $ct->template = $themes[$current_theme]['Template'];39 $ct->stylesheet = $themes[$current_theme]['Stylesheet'];40 $ct->screenshot = $themes[$current_theme]['Screenshot'];41 $ct->description = $themes[$current_theme]['Description'];42 $ct->author = $themes[$current_theme]['Author'];43 $ct->tags = $themes[$current_theme]['Tags'];44 $ct->theme_root = $themes[$current_theme]['Theme Root'];45 $ct->theme_root_uri = $themes[$current_theme]['Theme Root URI'];46 return $ct;47 }48 49 /**50 10 * Remove a theme 51 11 * 52 12 * @since 2.8.0 … … 114 74 } 115 75 116 76 /** 117 * {@internal Missing Short Description}}118 *119 * @since 1.5.0120 *121 * @return unknown122 */123 function get_broken_themes() {124 global $wp_broken_themes;125 126 get_themes();127 return $wp_broken_themes;128 }129 130 /**131 * Get the allowed themes for the current blog.132 *133 * @since 3.0.0134 *135 * @uses get_themes()136 * @uses current_theme_info()137 * @uses get_site_allowed_themes()138 * @uses wpmu_get_blog_allowedthemes139 *140 * @return array $themes Array of allowed themes.141 */142 function get_allowed_themes() {143 if ( !is_multisite() )144 return get_themes();145 146 $themes = get_themes();147 $ct = current_theme_info();148 $allowed_themes = apply_filters("allowed_themes", get_site_allowed_themes() );149 if ( $allowed_themes == false )150 $allowed_themes = array();151 152 $blog_allowed_themes = wpmu_get_blog_allowedthemes();153 if ( is_array( $blog_allowed_themes ) )154 $allowed_themes = array_merge( $allowed_themes, $blog_allowed_themes );155 156 if ( isset( $allowed_themes[ esc_html( $ct->stylesheet ) ] ) == false )157 $allowed_themes[ esc_html( $ct->stylesheet ) ] = true;158 159 reset( $themes );160 foreach ( $themes as $key => $theme ) {161 if ( isset( $allowed_themes[ esc_html( $theme[ 'Stylesheet' ] ) ] ) == false )162 unset( $themes[ $key ] );163 }164 reset( $themes );165 166 return $themes;167 }168 169 /**170 77 * Get the Page Templates available in this theme 171 78 * 172 79 * @since 1.5.0 … … 174 81 * @return array Key is the template name, value is the filename of the template 175 82 */ 176 83 function get_page_templates() { 177 $themes = get_themes(); 178 $theme = get_current_theme(); 179 $templates = $themes[$theme]['Template Files']; 180 $page_templates = array(); 181 182 if ( is_array( $templates ) ) { 183 $base = array( trailingslashit(get_template_directory()), trailingslashit(get_stylesheet_directory()) ); 184 185 foreach ( $templates as $template ) { 186 $basename = str_replace($base, '', $template); 187 188 // don't allow template files in subdirectories 189 if ( false !== strpos($basename, '/') ) 190 continue; 191 192 if ( 'functions.php' == $basename ) 193 continue; 194 195 $template_data = implode( '', file( $template )); 196 197 $name = ''; 198 if ( preg_match( '|Template Name:(.*)$|mi', $template_data, $name ) ) 199 $name = _cleanup_header_comment($name[1]); 200 201 if ( !empty( $name ) ) { 202 $page_templates[trim( $name )] = $basename; 203 } 204 } 205 } 206 207 return $page_templates; 84 return wp_get_theme()->get_page_templates(); 208 85 } 209 86 210 87 /** … … 240 117 if ( !isset($themes_update) ) 241 118 $themes_update = get_site_transient('update_themes'); 242 119 243 if ( is_object($theme) && isset($theme->stylesheet) ) 244 $stylesheet = $theme->stylesheet; 245 elseif ( is_array($theme) && isset($theme['Stylesheet']) ) 246 $stylesheet = $theme['Stylesheet']; 247 else 248 return false; //No valid info passed. 120 if ( ! is_a( $theme, 'WP_Theme' ) ) 121 return; 249 122 123 $stylesheet = $theme->get_stylesheet(); 124 250 125 if ( isset($themes_update->response[ $stylesheet ]) ) { 251 126 $update = $themes_update->response[ $stylesheet ]; 252 $theme_name = is_object($theme) ? $theme->name : (is_array($theme) ? $theme['Name'] : '');127 $theme_name = $theme->get('Name'); 253 128 $details_url = add_query_arg(array('TB_iframe' => 'true', 'width' => 1024, 'height' => 800), $update['url']); //Theme browser inside WP? replace this, Also, theme preview JS will override this on the available list. 254 129 $update_url = wp_nonce_url('update.php?action=upgrade-theme&theme=' . urlencode($stylesheet), 'upgrade-theme_' . $stylesheet); 255 130 $update_onclick = 'onclick="if ( confirm(\'' . esc_js( __("Updating this theme will lose any customizations you have made. 'Cancel' to stop, 'OK' to update.") ) . '\') ) {return true;}return false;"'; … … 270 145 * 271 146 * @since 3.1.0 272 147 * 148 * @param bool $api Optional. Whether to hit the API for tags. Defaults to true. 273 149 * @return array Array of features keyed by category with translations keyed by slug. 274 150 */ 275 function get_theme_feature_list( ) {151 function get_theme_feature_list( $api = true ) { 276 152 // Hard-coded list is used if api not accessible. 277 153 $features = array( 278 154 __('Colors') => array( … … 290 166 'white' => __( 'White' ), 291 167 'yellow' => __( 'Yellow' ), 292 168 'dark' => __( 'Dark' ), 293 'light' => __( 'Light ')169 'light' => __( 'Light' ) 294 170 ), 295 171 296 172 __('Columns') => array( … … 335 211 ) 336 212 ); 337 213 338 if ( ! current_user_can('install_themes') )214 if ( ! $api || !current_user_can('install_themes') ) 339 215 return $features; 340 216 341 217 if ( !$feature_list = get_site_transient( 'wporg_theme_feature_list' ) ) -
wp-admin/includes/theme-install.php
265 265 } 266 266 } 267 267 268 $theme s = get_themes();269 foreach ( (array) $themes as $this_theme) {270 if ( is_array($this_theme) && $this_theme['Stylesheet'] == $api->slug) {271 if ( version_compare( $this_theme['Version'], $api->version, '=' ) ) {268 $theme = wp_get_theme( $api->slug ); 269 if ( is_a( $theme, 'WP_Theme' ) ) { 270 switch ( version_compare( $theme->get('Version'), $api->version ) ) { 271 case 0; // equal 272 272 $type = 'latest_installed'; 273 } elseif ( version_compare( $this_theme['Version'], $api->version, '>' ) ) {273 case 1: // installed theme > api version 274 274 $type = 'newer_installed'; 275 $newer_version = $this_theme['Version']; 276 } 277 break; 275 $newer_version = $theme->get('Version'); 278 276 } 279 277 } 280 278 ?> -
wp-admin/includes/class-wp-themes-list-table.php
24 24 } 25 25 26 26 function prepare_items() { 27 global $ct;27 $themes = wp_get_themes( array( 'allowed' => true ) ); 28 28 29 $ct = current_theme_info();30 31 $themes = get_allowed_themes();32 33 29 if ( ! empty( $_REQUEST['s'] ) ) { 34 30 $search = strtolower( stripslashes( $_REQUEST['s'] ) ); 35 31 $this->search = array_merge( $this->search, array_filter( array_map( 'trim', explode( ',', $search ) ) ) ); … … 45 41 46 42 if ( $this->search || $this->features ) { 47 43 foreach ( $themes as $key => $theme ) { 48 if ( ! $this->search_theme( $theme ) )44 if ( ! $this->search_theme( $theme ) ) 49 45 unset( $themes[ $key ] ); 50 46 } 51 47 } 52 48 53 unset( $themes[ $ct->name] );54 uksort( $themes, "strnatcasecmp");49 unset( $themes[ get_option( 'stylesheet' ) ] ); 50 WP_Theme::sort_by_name( $themes ); 55 51 56 52 $per_page = 999; 57 53 $page = $this->get_pagenum(); … … 125 121 126 122 function display_rows() { 127 123 $themes = $this->items; 128 $theme_names = array_keys( $themes );129 natcasesort( $theme_names );130 124 131 foreach ( $theme_names as $theme_name ) { 132 $class = array( 'available-theme' ); 133 ?> 134 <div class="<?php echo join( ' ', $class ); ?>"> 135 <?php if ( !empty( $theme_name ) ) : 136 $template = $themes[$theme_name]['Template']; 137 $stylesheet = $themes[$theme_name]['Stylesheet']; 138 $title = $themes[$theme_name]['Title']; 139 $version = $themes[$theme_name]['Version']; 140 $description = $themes[$theme_name]['Description']; 141 $author = $themes[$theme_name]['Author']; 142 $screenshot = $themes[$theme_name]['Screenshot']; 143 $stylesheet_dir = $themes[$theme_name]['Stylesheet Dir']; 144 $template_dir = $themes[$theme_name]['Template Dir']; 145 $parent_theme = $themes[$theme_name]['Parent Theme']; 146 $theme_root = $themes[$theme_name]['Theme Root']; 147 $theme_root_uri = $themes[$theme_name]['Theme Root URI']; 148 $preview_link = esc_url( add_query_arg( array( 'preview' => 1, 'template' => $template, 'stylesheet' => $stylesheet, 'preview_iframe' => true, 'TB_iframe' => 'true' ), home_url( '/' ) ) ); 149 $preview_text = esc_attr( sprintf( __( 'Preview of “%s”' ), $title ) ); 150 $tags = $themes[$theme_name]['Tags']; 151 $thickbox_class = 'thickbox thickbox-preview'; 152 $activate_link = wp_nonce_url( "themes.php?action=activate&template=" . urlencode( $template ) . "&stylesheet=" . urlencode( $stylesheet ), 'switch-theme_' . $template ); 153 $activate_text = esc_attr( sprintf( __( 'Activate “%s”' ), $title ) ); 154 $actions = array(); 155 $actions[] = '<a href="' . $activate_link . '" class="activatelink" title="' . $activate_text . '">' . __( 'Activate' ) . '</a>'; 156 $actions[] = '<a href="' . $preview_link . '" class="thickbox thickbox-preview" title="' . esc_attr( sprintf( __( 'Preview “%s”' ), $theme_name ) ) . '">' . __( 'Preview' ) . '</a>'; 157 if ( ! is_multisite() && current_user_can( 'delete_themes' ) ) 158 $actions[] = '<a class="submitdelete deletion" href="' . wp_nonce_url( "themes.php?action=delete&template=$stylesheet", 'delete-theme_' . $stylesheet ) . '" onclick="' . "return confirm( '" . esc_js( sprintf( __( "You are about to delete this theme '%s'\n 'Cancel' to stop, 'OK' to delete." ), $theme_name ) ) . "' );" . '">' . __( 'Delete' ) . '</a>'; 159 $actions = apply_filters( 'theme_action_links', $actions, $themes[$theme_name] ); 125 foreach ( $themes as $theme ) { 126 echo '<div class="available-theme">'; 160 127 161 $actions = implode ( ' | ', $actions ); 162 ?> 163 <a href="<?php echo $preview_link; ?>" class="<?php echo $thickbox_class; ?> screenshot"> 164 <?php if ( $screenshot ) : ?> 165 <img src="<?php echo $theme_root_uri . '/' . $stylesheet . '/' . $screenshot; ?>" alt="" /> 166 <?php endif; ?> 167 </a> 168 <h3><?php 169 /* translators: 1: theme title, 2: theme version, 3: theme author */ 170 printf( __( '%1$s %2$s by %3$s' ), $title, $version, $author ) ; ?></h3> 128 $template = $theme->get_template(); 129 $stylesheet = $theme->get_stylesheet(); 171 130 172 <span class='action-links'><?php echo $actions ?></span> 173 <span class="separator hide-if-no-js">| </span><a href="#" class="theme-detail hide-if-no-js" tabindex='4'><?php _e('Details') ?></a> 174 <div class="themedetaildiv hide-if-js"> 175 <p><?php echo $description; ?></p> 176 <?php if ( current_user_can( 'edit_themes' ) && $parent_theme ) { 177 /* translators: 1: theme title, 2: template dir, 3: stylesheet_dir, 4: theme title, 5: parent_theme */ ?> 178 <p><?php printf( __( 'The template files are located in <code>%2$s</code>. The stylesheet files are located in <code>%3$s</code>. <strong>%4$s</strong> uses templates from <strong>%5$s</strong>. Changes made to the templates will affect both themes.' ), $title, str_replace( WP_CONTENT_DIR, '', $template_dir ), str_replace( WP_CONTENT_DIR, '', $stylesheet_dir ), $title, $parent_theme ); ?></p> 179 <?php } else { ?> 180 <p><?php printf( __( 'All of this theme’s files are located in <code>%2$s</code>.' ), $title, str_replace( WP_CONTENT_DIR, '', $template_dir ), str_replace( WP_CONTENT_DIR, '', $stylesheet_dir ) ); ?></p> 181 <?php } ?> 182 <?php if ( $tags ) : ?> 183 <p><?php _e( 'Tags:' ); ?> <?php echo join( ', ', $tags ); ?></p> 184 <?php endif; ?> 185 <?php endif; // end if not empty theme_name ?> 186 </div> 187 <?php theme_update_available( $themes[$theme_name] ); ?> 188 </div> 189 <?php } // end foreach $theme_names 131 $title = $theme->display('Name'); 132 $version = $theme->display('Version'); 133 $author = $theme->display('Author'); 134 135 $activate_link = wp_nonce_url( "themes.php?action=activate&template=" . urlencode( $template ) . "&stylesheet=" . urlencode( $stylesheet ), 'switch-theme_' . $template ); 136 $preview_link = esc_url( add_query_arg( 137 array( 'preview' => 1, 'template' => $template, 'stylesheet' => $stylesheet, 'preview_iframe' => true, 'TB_iframe' => 'true' ), 138 home_url( '/' ) ) ); 139 140 $actions = array(); 141 $actions[] = '<a href="' . $activate_link . '" class="activatelink" title="' 142 . esc_attr( sprintf( __( 'Activate “%s”' ), $title ) ) . '">' . __( 'Activate' ) . '</a>'; 143 $actions[] = '<a href="' . $preview_link . '" class="thickbox thickbox-preview" title="' 144 . esc_attr( sprintf( __( 'Preview “%s”' ), $title ) ) . '">' . __( 'Preview' ) . '</a>'; 145 if ( ! is_multisite() && current_user_can( 'delete_themes' ) ) 146 $actions[] = '<a class="submitdelete deletion" href="' . wp_nonce_url( "themes.php?action=delete&template=$stylesheet", 'delete-theme_' . $stylesheet ) 147 . '" onclick="' . "return confirm( '" . esc_js( sprintf( __( "You are about to delete this theme '%s'\n 'Cancel' to stop, 'OK' to delete." ), $title ) ) 148 . "' );" . '">' . __( 'Delete' ) . '</a>'; 149 150 $actions = apply_filters( 'theme_action_links', $actions, $theme ); 151 152 $actions = implode ( ' | ', $actions ); 153 ?> 154 <a href="<?php echo $preview_link; ?>" class="thickbox thickbox-preview screenshot"> 155 <?php if ( $theme->get_screenshot() ) : ?> 156 <img src="<?php echo esc_url( $theme->get_screenshot( 'absolute' ) ); ?>" alt="" /> 157 <?php endif; ?> 158 </a> 159 <h3><?php 160 /* translators: 1: theme title, 2: theme version, 3: theme author */ 161 printf( __( '%1$s %2$s by %3$s' ), $title, $version, $author ) ; ?></h3> 162 163 <span class='action-links'><?php echo $actions ?></span> 164 <span class="separator hide-if-no-js">| </span><a href="#" class="theme-detail hide-if-no-js" tabindex='4'><?php _e('Details') ?></a> 165 <div class="themedetaildiv hide-if-js"> 166 <p><?php echo $theme->display('Description'); ?></p> 167 <?php if ( current_user_can( 'edit_themes' ) && $theme->parent() ) : 168 /* translators: 1: theme title, 2: template dir, 3: stylesheet_dir, 4: theme title, 5: parent_theme */ ?> 169 <p><?php printf( __( 'The template files are located in <code>%2$s</code>. The stylesheet files are located in <code>%3$s</code>. <strong>%4$s</strong> uses templates from <strong>%5$s</strong>. Changes made to the templates will affect both themes.' ), 170 $title, str_replace( WP_CONTENT_DIR, '', $theme->get_template_directory() ), str_replace( WP_CONTENT_DIR, '', $theme->get_stylesheet_directory() ), $title, $theme->parent()->display('Name') ); ?></p> 171 <?php else : 172 /* translators: 1: theme title, 2: template dir, 3: stylesheet_dir */ ?> 173 <p><?php printf( __( 'All of this theme’s files are located in <code>%2$s</code>.' ), 174 $title, str_replace( WP_CONTENT_DIR, '', $theme->get_template_directory() ), str_replace( WP_CONTENT_DIR, '', $theme->get_stylesheet_directory() ) ); ?></p> 175 <?php endif; ?> 176 <?php 177 if ( $theme->get('Tags') ) 178 printf( '<p>' . __( 'Tags: %s.' ) . '</p>', $theme->display('Tags') ); 179 ?> 180 </div> 181 <?php theme_update_available( $theme ); ?> 182 </div> 183 <?php 184 } 190 185 } 191 186 192 187 function search_theme( $theme ) { 193 $matched = 0; 188 // Search the features 189 if ( $this->features ) { 190 foreach ( $this->features as $word ) { 191 if ( ! in_array( $word, $theme->get('Tags') ) ) 192 return false; 193 } 194 } 194 195 195 196 // Match all phrases 196 if ( count( $this->search ) > 0) {197 if ( $this->search ) { 197 198 foreach ( $this->search as $word ) { 198 $matched = 0; 199 if ( in_array( $word, $theme->get('Tags') ) ) 200 continue; 199 201 200 // In a tag? 201 if ( in_array( $word, array_map( 'sanitize_title_with_dashes', $theme['Tags'] ) ) ) 202 $matched = 1; 203 204 // In one of the fields? 205 foreach ( array( 'Name', 'Title', 'Description', 'Author', 'Template', 'Stylesheet' ) AS $field ) { 206 if ( stripos( $theme[$field], $word ) !== false ) 207 $matched++; 202 foreach ( array( 'Name', 'Description', 'Author', 'AuthorURI' ) as $header ) { 203 // Don't mark up; Do translate. 204 if ( false !== stripos( $theme->display( $header, false, true ), $word ) ) 205 continue 2; 208 206 } 209 207 210 if ( $matched == 0 ) 211 return false; 212 } 213 } 208 if ( false !== stripos( $theme->get_stylesheet(), $word ) ) 209 continue; 214 210 215 // Now search the features 216 if ( count( $this->features ) > 0 ) { 217 foreach ( $this->features as $word ) { 218 // In a tag? 219 if ( !in_array( $word, array_map( 'sanitize_title_with_dashes', $theme['Tags'] ) ) ) 220 return false; 211 if ( false !== stripos( $theme->get_template(), $word ) ) 212 continue; 213 214 return false; 221 215 } 222 216 } 223 217 224 // Only get here if each word exists in the tags or one of the fields225 218 return true; 226 219 } 227 220 } -
wp-admin/includes/ms.php
169 169 return true; 170 170 } 171 171 172 function wpmu_get_blog_allowedthemes( $blog_id = 0 ) {173 $themes = get_themes();174 175 if ( $blog_id != 0 )176 switch_to_blog( $blog_id );177 178 $blog_allowed_themes = get_option( 'allowedthemes' );179 if ( !is_array( $blog_allowed_themes ) || empty( $blog_allowed_themes ) ) { // convert old allowed_themes to new allowedthemes180 $blog_allowed_themes = get_option( 'allowed_themes' );181 182 if ( is_array( $blog_allowed_themes ) ) {183 foreach( (array) $themes as $key => $theme ) {184 $theme_key = esc_html( $theme['Stylesheet'] );185 if ( isset( $blog_allowed_themes[$key] ) == true ) {186 $blog_allowedthemes[$theme_key] = 1;187 }188 }189 $blog_allowed_themes = $blog_allowedthemes;190 add_option( 'allowedthemes', $blog_allowed_themes );191 delete_option( 'allowed_themes' );192 }193 }194 195 if ( $blog_id != 0 )196 restore_current_blog();197 198 return $blog_allowed_themes;199 }200 201 172 function update_option_new_admin_email( $old_value, $value ) { 202 173 $email = get_option( 'admin_email' ); 203 174 if ( $value == get_option( 'admin_email' ) || !is_email( $value ) ) … … 296 267 } 297 268 add_action( 'admin_notices', 'new_user_email_admin_notice' ); 298 269 299 function get_site_allowed_themes() {300 $themes = get_themes();301 $allowed_themes = get_site_option( 'allowedthemes' );302 if ( !is_array( $allowed_themes ) || empty( $allowed_themes ) ) {303 $allowed_themes = get_site_option( 'allowed_themes' ); // convert old allowed_themes format304 if ( !is_array( $allowed_themes ) ) {305 $allowed_themes = array();306 } else {307 foreach( (array) $themes as $key => $theme ) {308 $theme_key = esc_html( $theme['Stylesheet'] );309 if ( isset( $allowed_themes[ $key ] ) == true ) {310 $allowedthemes[ $theme_key ] = 1;311 }312 }313 $allowed_themes = $allowedthemes;314 }315 }316 return $allowed_themes;317 }318 319 270 /** 320 271 * Determines if there is any upload space left in the current blog's quota. 321 272 * -
wp-admin/themes.php
96 96 <h2><?php echo esc_html( $title ); ?> 97 97 <?php endif; ?> 98 98 </h2> 99 100 <h3><?php _e( 'Current Theme'); ?></h3>99 <?php $ct = wp_get_theme(); ?> 100 <h3><?php _e( 'Current Theme' ); ?></h3> 101 101 <div id="current-theme"> 102 <?php if ( $ct-> screenshot) : ?>103 <img src="<?php echo $ct-> theme_root_uri . '/' . $ct->stylesheet . '/' . $ct->screenshot; ?>" alt="<?php esc_attr_e('Current theme preview'); ?>" />102 <?php if ( $ct->get_screenshot() ) : ?> 103 <img src="<?php echo $ct->get_screenshot( 'absolute' ); ?>" alt="<?php esc_attr_e( 'Current theme preview'); ?>" /> 104 104 <?php endif; ?> 105 105 <h4><?php 106 106 /* translators: 1: theme title, 2: theme version, 3: theme author */ 107 printf( __('%1$s %2$s by %3$s'), $ct->title, $ct->version, $ct->author) ; ?></h4>108 <p class="theme-description"><?php echo $ct->d escription; ?></p>107 printf( __( '%1$s %2$s by %3$s' ), $ct->display('Name'), $ct->display('Version'), $ct->display('Author') ) ; ?></h4> 108 <p class="theme-description"><?php echo $ct->display('Description'); ?></p> 109 109 <div class="theme-options"> 110 110 <span><?php _e( 'Options:' )?></span> 111 111 <?php … … 117 117 if ( 'themes.php' == $item[2] || 'theme-editor.php' == $item[2] ) 118 118 continue; 119 119 // 0 = name, 1 = capability, 2 = file 120 if ( ( strcmp($self, $item[2]) == 0 && empty($parent_file)) || ($parent_file && ($item[2] == $parent_file)) ) $class = ' class="current"';121 120 if ( ( strcmp($self, $item[2]) == 0 && empty($parent_file)) || ($parent_file && ($item[2] == $parent_file)) ) 121 $class = ' class="current"'; 122 122 if ( !empty($submenu[$item[2]]) ) { 123 123 $submenu[$item[2]] = array_values($submenu[$item[2]]); // Re-index. 124 124 $menu_hook = get_plugin_page_hook($submenu[$item[2]][0][2], $item[2]); … … 137 137 } 138 138 echo implode ( ' | ', $options ); 139 139 140 if ( $ct-> tags) : ?>141 <p><?php _e('Tags:'); ?> <?php echo join(', ', $ct->tags); ?></p>140 if ( $ct->get('Tags') ) : ?> 141 <p><?php _e('Tags:'); ?> <?php echo $ct->display('Tags'); ?></p> 142 142 <?php endif; ?> 143 143 </div> 144 144 <?php theme_update_available($ct); ?> … … 218 218 219 219 <?php 220 220 // List broken themes, if any. 221 $broken_themes = get_broken_themes(); 222 if ( current_user_can('edit_themes') && count( $broken_themes ) ) { 221 if ( current_user_can('edit_themes') && $broken_themes = wp_get_themes( array( 'errors' => true ) ) ) { 223 222 ?> 224 223 225 224 <h3><?php _e('Broken Themes'); ?></h3> … … 231 230 <th><?php _e('Description'); ?></th> 232 231 </tr> 233 232 <?php 234 $theme = ''; 235 236 $theme_names = array_keys($broken_themes); 237 natcasesort($theme_names); 238 239 foreach ($theme_names as $theme_name) { 240 $name = $broken_themes[$theme_name]['Title']; 241 $description = $broken_themes[$theme_name]['Description']; 242 243 $theme = ('class="alternate"' == $theme) ? '' : 'class="alternate"'; 233 $alt = ''; 234 foreach ( $broken_themes as $broken_theme ) { 235 $alt = ('class="alternate"' == $alt) ? '' : 'class="alternate"'; 244 236 echo " 245 <tr $ theme>246 <td> $name</td>247 <td> $description</td>237 <tr $alt> 238 <td>" . $broken_theme->get('Name') ."</td> 239 <td>" . $broken_theme->errors()->get_error_message() . "</td> 248 240 </tr>"; 249 241 } 250 242 ?> … … 254 246 ?> 255 247 </div> 256 248 257 <?php require('./admin-footer.php'); ?> 249 <?php require('./admin-footer.php'); ?> 250 No newline at end of file