160 * |
168 * |
161 * @param string $theme_file Theme file path. |
169 * @param string $theme_file Theme file path. |
162 * @return array Theme data. |
170 * @return array Theme data. |
163 */ |
171 */ |
164 function get_theme_data( $theme_file ) { |
172 function get_theme_data( $theme_file ) { |
|
173 $default_headers = array( |
|
174 'Name' => 'Theme Name', |
|
175 'URI' => 'Theme URI', |
|
176 'Description' => 'Description', |
|
177 'Author' => 'Author', |
|
178 'AuthorURI' => 'Author URI', |
|
179 'Version' => 'Version', |
|
180 'Template' => 'Template', |
|
181 'Status' => 'Status', |
|
182 'Tags' => 'Tags' |
|
183 ); |
|
184 |
165 $themes_allowed_tags = array( |
185 $themes_allowed_tags = array( |
166 'a' => array( |
186 'a' => array( |
167 'href' => array(),'title' => array() |
187 'href' => array(),'title' => array() |
168 ), |
188 ), |
169 'abbr' => array( |
189 'abbr' => array( |
175 'code' => array(), |
195 'code' => array(), |
176 'em' => array(), |
196 'em' => array(), |
177 'strong' => array() |
197 'strong' => array() |
178 ); |
198 ); |
179 |
199 |
180 $theme_data = implode( '', file( $theme_file ) ); |
200 $theme_data = get_file_data( $theme_file, $default_headers, 'theme' ); |
181 $theme_data = str_replace ( '\r', '\n', $theme_data ); |
201 |
182 if ( preg_match( '|Theme Name:(.*)$|mi', $theme_data, $theme_name ) ) |
202 $theme_data['Name'] = $theme_data['Title'] = wp_kses( $theme_data['Name'], $themes_allowed_tags ); |
183 $name = $theme = wp_kses( _cleanup_header_comment($theme_name[1]), $themes_allowed_tags ); |
203 |
|
204 $theme_data['URI'] = esc_url( $theme_data['URI'] ); |
|
205 |
|
206 $theme_data['Description'] = wptexturize( wp_kses( $theme_data['Description'], $themes_allowed_tags ) ); |
|
207 |
|
208 $theme_data['AuthorURI'] = esc_url( $theme_data['AuthorURI'] ); |
|
209 |
|
210 $theme_data['Template'] = wp_kses( $theme_data['Template'], $themes_allowed_tags ); |
|
211 |
|
212 $theme_data['Version'] = wp_kses( $theme_data['Version'], $themes_allowed_tags ); |
|
213 |
|
214 if ( $theme_data['Status'] == '' ) |
|
215 $theme_data['Status'] = 'publish'; |
184 else |
216 else |
185 $name = $theme = ''; |
217 $theme_data['Status'] = wp_kses( $theme_data['Status'], $themes_allowed_tags ); |
186 |
218 |
187 if ( preg_match( '|Theme URI:(.*)$|mi', $theme_data, $theme_uri ) ) |
219 if ( $theme_data['Tags'] == '' ) |
188 $theme_uri = esc_url( _cleanup_header_comment($theme_uri[1]) ); |
220 $theme_data['Tags'] = array(); |
189 else |
221 else |
190 $theme_uri = ''; |
222 $theme_data['Tags'] = array_map( 'trim', explode( ',', wp_kses( $theme_data['Tags'], array() ) ) ); |
191 |
223 |
192 if ( preg_match( '|Description:(.*)$|mi', $theme_data, $description ) ) |
224 if ( $theme_data['Author'] == '' ) { |
193 $description = wptexturize( wp_kses( _cleanup_header_comment($description[1]), $themes_allowed_tags ) ); |
225 $theme_data['Author'] = __('Anonymous'); |
194 else |
226 } else { |
195 $description = ''; |
227 if ( empty( $theme_data['AuthorURI'] ) ) { |
196 |
228 $theme_data['Author'] = wp_kses( $theme_data['Author'], $themes_allowed_tags ); |
197 if ( preg_match( '|Author URI:(.*)$|mi', $theme_data, $author_uri ) ) |
|
198 $author_uri = esc_url( _cleanup_header_comment($author_uri[1]) ); |
|
199 else |
|
200 $author_uri = ''; |
|
201 |
|
202 if ( preg_match( '|Template:(.*)$|mi', $theme_data, $template ) ) |
|
203 $template = wp_kses( _cleanup_header_comment($template[1]), $themes_allowed_tags ); |
|
204 else |
|
205 $template = ''; |
|
206 |
|
207 if ( preg_match( '|Version:(.*)|i', $theme_data, $version ) ) |
|
208 $version = wp_kses( _cleanup_header_comment($version[1]), $themes_allowed_tags ); |
|
209 else |
|
210 $version = ''; |
|
211 |
|
212 if ( preg_match('|Status:(.*)|i', $theme_data, $status) ) |
|
213 $status = wp_kses( _cleanup_header_comment($status[1]), $themes_allowed_tags ); |
|
214 else |
|
215 $status = 'publish'; |
|
216 |
|
217 if ( preg_match('|Tags:(.*)|i', $theme_data, $tags) ) |
|
218 $tags = array_map( 'trim', explode( ',', wp_kses( _cleanup_header_comment($tags[1]), array() ) ) ); |
|
219 else |
|
220 $tags = array(); |
|
221 |
|
222 if ( preg_match( '|Author:(.*)$|mi', $theme_data, $author_name ) ) { |
|
223 if ( empty( $author_uri ) ) { |
|
224 $author = wp_kses( _cleanup_header_comment($author_name[1]), $themes_allowed_tags ); |
|
225 } else { |
229 } else { |
226 $author = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $author_uri, __( 'Visit author homepage' ), wp_kses( _cleanup_header_comment($author_name[1]), $themes_allowed_tags ) ); |
230 $theme_data['Author'] = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $theme_data['AuthorURI'], __( 'Visit author homepage' ), wp_kses( $theme_data['Author'], $themes_allowed_tags ) ); |
227 } |
231 } |
228 } else { |
|
229 $author = __('Anonymous'); |
|
230 } |
232 } |
231 |
233 |
232 return array( 'Name' => $name, 'Title' => $theme, 'URI' => $theme_uri, 'Description' => $description, 'Author' => $author, 'Version' => $version, 'Template' => $template, 'Status' => $status, 'Tags' => $tags ); |
234 return $theme_data; |
233 } |
235 } |
234 |
236 |
235 /** |
237 /** |
236 * Retrieve list of themes with theme data in theme directory. |
238 * Retrieve list of themes with theme data in theme directory. |
237 * |
239 * |
251 global $wp_themes, $wp_broken_themes; |
253 global $wp_themes, $wp_broken_themes; |
252 |
254 |
253 if ( isset($wp_themes) ) |
255 if ( isset($wp_themes) ) |
254 return $wp_themes; |
256 return $wp_themes; |
255 |
257 |
256 $themes = array(); |
258 /* Register the default root as a theme directory */ |
257 $wp_broken_themes = array(); |
259 register_theme_directory( get_theme_root() ); |
258 $theme_loc = $theme_root = get_theme_root(); |
260 |
259 if ( '/' != WP_CONTENT_DIR ) // don't want to replace all forward slashes, see Trac #4541 |
261 if ( !$theme_files = search_theme_directories() ) |
260 $theme_loc = str_replace(WP_CONTENT_DIR, '', $theme_root); |
|
261 |
|
262 // Files in wp-content/themes directory and one subdir down |
|
263 $themes_dir = @ opendir($theme_root); |
|
264 if ( !$themes_dir ) |
|
265 return false; |
262 return false; |
266 |
263 |
267 while ( ($theme_dir = readdir($themes_dir)) !== false ) { |
264 asort( $theme_files ); |
268 if ( is_dir($theme_root . '/' . $theme_dir) && is_readable($theme_root . '/' . $theme_dir) ) { |
265 |
269 if ( $theme_dir{0} == '.' || $theme_dir == '..' || $theme_dir == 'CVS' ) |
266 $wp_themes = array(); |
270 continue; |
|
271 $stylish_dir = @ opendir($theme_root . '/' . $theme_dir); |
|
272 $found_stylesheet = false; |
|
273 while ( ($theme_file = readdir($stylish_dir)) !== false ) { |
|
274 if ( $theme_file == 'style.css' ) { |
|
275 $theme_files[] = $theme_dir . '/' . $theme_file; |
|
276 $found_stylesheet = true; |
|
277 break; |
|
278 } |
|
279 } |
|
280 @closedir($stylish_dir); |
|
281 if ( !$found_stylesheet ) { // look for themes in that dir |
|
282 $subdir = "$theme_root/$theme_dir"; |
|
283 $subdir_name = $theme_dir; |
|
284 $theme_subdir = @ opendir( $subdir ); |
|
285 while ( ($theme_dir = readdir($theme_subdir)) !== false ) { |
|
286 if ( is_dir( $subdir . '/' . $theme_dir) && is_readable($subdir . '/' . $theme_dir) ) { |
|
287 if ( $theme_dir{0} == '.' || $theme_dir == '..' || $theme_dir == 'CVS' ) |
|
288 continue; |
|
289 $stylish_dir = @ opendir($subdir . '/' . $theme_dir); |
|
290 $found_stylesheet = false; |
|
291 while ( ($theme_file = readdir($stylish_dir)) !== false ) { |
|
292 if ( $theme_file == 'style.css' ) { |
|
293 $theme_files[] = $subdir_name . '/' . $theme_dir . '/' . $theme_file; |
|
294 $found_stylesheet = true; |
|
295 break; |
|
296 } |
|
297 } |
|
298 @closedir($stylish_dir); |
|
299 } |
|
300 } |
|
301 @closedir($theme_subdir); |
|
302 $wp_broken_themes[$theme_dir] = array('Name' => $theme_dir, 'Title' => $theme_dir, 'Description' => __('Stylesheet is missing.')); |
|
303 } |
|
304 } |
|
305 } |
|
306 if ( is_dir( $theme_dir ) ) |
|
307 @closedir( $theme_dir ); |
|
308 |
|
309 if ( !$themes_dir || !$theme_files ) |
|
310 return $themes; |
|
311 |
|
312 sort($theme_files); |
|
313 |
267 |
314 foreach ( (array) $theme_files as $theme_file ) { |
268 foreach ( (array) $theme_files as $theme_file ) { |
|
269 $theme_root = $theme_file['theme_root']; |
|
270 $theme_file = $theme_file['theme_file']; |
|
271 |
315 if ( !is_readable("$theme_root/$theme_file") ) { |
272 if ( !is_readable("$theme_root/$theme_file") ) { |
316 $wp_broken_themes[$theme_file] = array('Name' => $theme_file, 'Title' => $theme_file, 'Description' => __('File not readable.')); |
273 $wp_broken_themes[$theme_file] = array('Name' => $theme_file, 'Title' => $theme_file, 'Description' => __('File not readable.')); |
317 continue; |
274 continue; |
318 } |
275 } |
319 |
276 |
339 $name = dirname($theme_file); |
296 $name = dirname($theme_file); |
340 $title = $name; |
297 $title = $name; |
341 } |
298 } |
342 |
299 |
343 if ( empty($template) ) { |
300 if ( empty($template) ) { |
344 if ( file_exists(dirname("$theme_root/$theme_file/index.php")) ) |
301 if ( file_exists("$theme_root/$stylesheet/index.php") ) |
345 $template = dirname($theme_file); |
302 $template = $stylesheet; |
346 else |
303 else |
347 continue; |
304 continue; |
348 } |
305 } |
349 |
306 |
350 $template = trim($template); |
307 $template = trim( $template ); |
351 |
308 |
352 if ( !file_exists("$theme_root/$template/index.php") ) { |
309 if ( !file_exists("$theme_root/$template/index.php") ) { |
353 $parent_dir = dirname(dirname($theme_file)); |
310 $parent_dir = dirname(dirname($theme_file)); |
354 if ( file_exists("$theme_root/$parent_dir/$template/index.php") ) { |
311 if ( file_exists("$theme_root/$parent_dir/$template/index.php") ) { |
355 $template = "$parent_dir/$template"; |
312 $template = "$parent_dir/$template"; |
|
313 $template_directory = "$theme_root/$template"; |
356 } else { |
314 } else { |
357 $wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => __('Template is missing.')); |
315 /** |
358 continue; |
316 * The parent theme doesn't exist in the current theme's folder or sub folder |
|
317 * so lets use the theme root for the parent template. |
|
318 */ |
|
319 if ( isset($theme_files[$template]) && file_exists( $theme_files[$template]['theme_root'] . "/$template/index.php" ) ) { |
|
320 $template_directory = $theme_files[$template]['theme_root'] . "/$template"; |
|
321 } else { |
|
322 $wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => __('Template is missing.')); |
|
323 continue; |
|
324 } |
|
325 |
359 } |
326 } |
|
327 } else { |
|
328 $template_directory = trim( $theme_root . '/' . $template ); |
360 } |
329 } |
361 |
330 |
362 $stylesheet_files = array(); |
331 $stylesheet_files = array(); |
363 $template_files = array(); |
332 $template_files = array(); |
364 |
333 |
365 $stylesheet_dir = @ dir("$theme_root/$stylesheet"); |
334 $stylesheet_dir = @ dir("$theme_root/$stylesheet"); |
366 if ( $stylesheet_dir ) { |
335 if ( $stylesheet_dir ) { |
367 while ( ($file = $stylesheet_dir->read()) !== false ) { |
336 while ( ($file = $stylesheet_dir->read()) !== false ) { |
368 if ( !preg_match('|^\.+$|', $file) ) { |
337 if ( !preg_match('|^\.+$|', $file) ) { |
369 if ( preg_match('|\.css$|', $file) ) |
338 if ( preg_match('|\.css$|', $file) ) |
370 $stylesheet_files[] = "$theme_loc/$stylesheet/$file"; |
339 $stylesheet_files[] = "$theme_root/$stylesheet/$file"; |
371 elseif ( preg_match('|\.php$|', $file) ) |
340 elseif ( preg_match('|\.php$|', $file) ) |
372 $template_files[] = "$theme_loc/$stylesheet/$file"; |
341 $template_files[] = "$theme_root/$stylesheet/$file"; |
373 } |
342 } |
374 } |
343 } |
375 @ $stylesheet_dir->close(); |
344 @ $stylesheet_dir->close(); |
376 } |
345 } |
377 |
346 |
378 $template_dir = @ dir("$theme_root/$template"); |
347 $template_dir = @ dir("$template_directory"); |
379 if ( $template_dir ) { |
348 if ( $template_dir ) { |
380 while ( ($file = $template_dir->read()) !== false ) { |
349 while ( ($file = $template_dir->read()) !== false ) { |
381 if ( preg_match('|^\.+$|', $file) ) |
350 if ( preg_match('|^\.+$|', $file) ) |
382 continue; |
351 continue; |
383 if ( preg_match('|\.php$|', $file) ) { |
352 if ( preg_match('|\.php$|', $file) ) { |
384 $template_files[] = "$theme_loc/$template/$file"; |
353 $template_files[] = "$template_directory/$file"; |
385 } elseif ( is_dir("$theme_root/$template/$file") ) { |
354 } elseif ( is_dir("$template_directory/$file") ) { |
386 $template_subdir = @ dir("$theme_root/$template/$file"); |
355 $template_subdir = @ dir("$template_directory/$file"); |
|
356 if ( !$template_subdir ) |
|
357 continue; |
387 while ( ($subfile = $template_subdir->read()) !== false ) { |
358 while ( ($subfile = $template_subdir->read()) !== false ) { |
388 if ( preg_match('|^\.+$|', $subfile) ) |
359 if ( preg_match('|^\.+$|', $subfile) ) |
389 continue; |
360 continue; |
390 if ( preg_match('|\.php$|', $subfile) ) |
361 if ( preg_match('|\.php$|', $subfile) ) |
391 $template_files[] = "$theme_loc/$template/$file/$subfile"; |
362 $template_files[] = "$template_directory/$file/$subfile"; |
392 } |
363 } |
393 @ $template_subdir->close(); |
364 @ $template_subdir->close(); |
394 } |
365 } |
395 } |
366 } |
396 @ $template_dir->close(); |
367 @ $template_dir->close(); |
397 } |
368 } |
398 |
369 |
|
370 //Make unique and remove duplicates when stylesheet and template are the same i.e. most themes |
|
371 $template_files = array_unique($template_files); |
|
372 $stylesheet_files = array_unique($stylesheet_files); |
|
373 |
399 $template_dir = dirname($template_files[0]); |
374 $template_dir = dirname($template_files[0]); |
400 $stylesheet_dir = dirname($stylesheet_files[0]); |
375 $stylesheet_dir = dirname($stylesheet_files[0]); |
401 |
376 |
402 if ( empty($template_dir) ) |
377 if ( empty($template_dir) ) |
403 $template_dir = '/'; |
378 $template_dir = '/'; |
406 |
381 |
407 // Check for theme name collision. This occurs if a theme is copied to |
382 // Check for theme name collision. This occurs if a theme is copied to |
408 // a new theme directory and the theme header is not updated. Whichever |
383 // a new theme directory and the theme header is not updated. Whichever |
409 // theme is first keeps the name. Subsequent themes get a suffix applied. |
384 // theme is first keeps the name. Subsequent themes get a suffix applied. |
410 // The Default and Classic themes always trump their pretenders. |
385 // The Default and Classic themes always trump their pretenders. |
411 if ( isset($themes[$name]) ) { |
386 if ( isset($wp_themes[$name]) ) { |
412 if ( ('WordPress Default' == $name || 'WordPress Classic' == $name) && |
387 if ( ('WordPress Default' == $name || 'WordPress Classic' == $name) && |
413 ('default' == $stylesheet || 'classic' == $stylesheet) ) { |
388 ('default' == $stylesheet || 'classic' == $stylesheet) ) { |
414 // If another theme has claimed to be one of our default themes, move |
389 // If another theme has claimed to be one of our default themes, move |
415 // them aside. |
390 // them aside. |
416 $suffix = $themes[$name]['Stylesheet']; |
391 $suffix = $wp_themes[$name]['Stylesheet']; |
417 $new_name = "$name/$suffix"; |
392 $new_name = "$name/$suffix"; |
418 $themes[$new_name] = $themes[$name]; |
393 $wp_themes[$new_name] = $wp_themes[$name]; |
419 $themes[$new_name]['Name'] = $new_name; |
394 $wp_themes[$new_name]['Name'] = $new_name; |
420 } else { |
395 } else { |
421 $name = "$name/$stylesheet"; |
396 $name = "$name/$stylesheet"; |
422 } |
397 } |
423 } |
398 } |
424 |
399 |
425 $themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => $description, 'Author' => $author, 'Version' => $version, 'Template' => $template, 'Stylesheet' => $stylesheet, 'Template Files' => $template_files, 'Stylesheet Files' => $stylesheet_files, 'Template Dir' => $template_dir, 'Stylesheet Dir' => $stylesheet_dir, 'Status' => $theme_data['Status'], 'Screenshot' => $screenshot, 'Tags' => $theme_data['Tags']); |
400 $theme_roots[$stylesheet] = str_replace( WP_CONTENT_DIR, '', $theme_root ); |
|
401 $wp_themes[$name] = array( 'Name' => $name, 'Title' => $title, 'Description' => $description, 'Author' => $author, 'Version' => $version, 'Template' => $template, 'Stylesheet' => $stylesheet, 'Template Files' => $template_files, 'Stylesheet Files' => $stylesheet_files, 'Template Dir' => $template_dir, 'Stylesheet Dir' => $stylesheet_dir, 'Status' => $theme_data['Status'], 'Screenshot' => $screenshot, 'Tags' => $theme_data['Tags'], 'Theme Root' => $theme_root, 'Theme Root URI' => str_replace( WP_CONTENT_DIR, content_url(), $theme_root ) ); |
426 } |
402 } |
427 |
403 |
428 // Resolve theme dependencies. |
404 unset($theme_files); |
429 $theme_names = array_keys($themes); |
405 |
430 |
406 /* Store theme roots in the DB */ |
|
407 if ( get_site_transient( 'theme_roots' ) != $theme_roots ) |
|
408 set_site_transient( 'theme_roots', $theme_roots, 7200 ); // cache for two hours |
|
409 unset($theme_roots); |
|
410 |
|
411 /* Resolve theme dependencies. */ |
|
412 $theme_names = array_keys( $wp_themes ); |
431 foreach ( (array) $theme_names as $theme_name ) { |
413 foreach ( (array) $theme_names as $theme_name ) { |
432 $themes[$theme_name]['Parent Theme'] = ''; |
414 $wp_themes[$theme_name]['Parent Theme'] = ''; |
433 if ( $themes[$theme_name]['Stylesheet'] != $themes[$theme_name]['Template'] ) { |
415 if ( $wp_themes[$theme_name]['Stylesheet'] != $wp_themes[$theme_name]['Template'] ) { |
434 foreach ( (array) $theme_names as $parent_theme_name ) { |
416 foreach ( (array) $theme_names as $parent_theme_name ) { |
435 if ( ($themes[$parent_theme_name]['Stylesheet'] == $themes[$parent_theme_name]['Template']) && ($themes[$parent_theme_name]['Template'] == $themes[$theme_name]['Template']) ) { |
417 if ( ($wp_themes[$parent_theme_name]['Stylesheet'] == $wp_themes[$parent_theme_name]['Template']) && ($wp_themes[$parent_theme_name]['Template'] == $wp_themes[$theme_name]['Template']) ) { |
436 $themes[$theme_name]['Parent Theme'] = $themes[$parent_theme_name]['Name']; |
418 $wp_themes[$theme_name]['Parent Theme'] = $wp_themes[$parent_theme_name]['Name']; |
437 break; |
419 break; |
438 } |
420 } |
439 } |
421 } |
440 } |
422 } |
441 } |
423 } |
442 |
424 |
443 $wp_themes = $themes; |
425 return $wp_themes; |
444 |
426 } |
445 return $themes; |
427 |
|
428 /** |
|
429 * Retrieve theme roots. |
|
430 * |
|
431 * @since 2.9.0 |
|
432 * |
|
433 * @return array Theme roots |
|
434 */ |
|
435 function get_theme_roots() { |
|
436 $theme_roots = get_site_transient( 'theme_roots' ); |
|
437 if ( false === $theme_roots ) { |
|
438 get_themes(); |
|
439 $theme_roots = get_site_transient( 'theme_roots' ); // this is set in get_theme() |
|
440 } |
|
441 return $theme_roots; |
446 } |
442 } |
447 |
443 |
448 /** |
444 /** |
449 * Retrieve theme data. |
445 * Retrieve theme data. |
450 * |
446 * |
497 |
493 |
498 return $current_theme; |
494 return $current_theme; |
499 } |
495 } |
500 |
496 |
501 /** |
497 /** |
|
498 * Register a directory that contains themes. |
|
499 * |
|
500 * @since 2.9.0 |
|
501 * |
|
502 * @param string $directory Either the full filesystem path to a theme folder or a folder within WP_CONTENT_DIR |
|
503 * @return bool |
|
504 */ |
|
505 function register_theme_directory( $directory) { |
|
506 global $wp_theme_directories; |
|
507 |
|
508 /* If this folder does not exist, return and do not register */ |
|
509 if ( !file_exists( $directory ) ) |
|
510 /* Try prepending as the theme directory could be relative to the content directory */ |
|
511 $registered_directory = WP_CONTENT_DIR . '/' . $directory; |
|
512 else |
|
513 $registered_directory = $directory; |
|
514 |
|
515 /* If this folder does not exist, return and do not register */ |
|
516 if ( !file_exists( $registered_directory ) ) |
|
517 return false; |
|
518 |
|
519 $wp_theme_directories[] = $registered_directory; |
|
520 |
|
521 return true; |
|
522 } |
|
523 |
|
524 /** |
|
525 * Search all registered theme directories for complete and valid themes. |
|
526 * |
|
527 * @since 2.9.0 |
|
528 * |
|
529 * @return array Valid themes found |
|
530 */ |
|
531 function search_theme_directories() { |
|
532 global $wp_theme_directories, $wp_broken_themes; |
|
533 if ( empty( $wp_theme_directories ) ) |
|
534 return false; |
|
535 |
|
536 $theme_files = array(); |
|
537 $wp_broken_themes = array(); |
|
538 |
|
539 /* Loop the registered theme directories and extract all themes */ |
|
540 foreach ( (array) $wp_theme_directories as $theme_root ) { |
|
541 $theme_loc = $theme_root; |
|
542 |
|
543 /* We don't want to replace all forward slashes, see Trac #4541 */ |
|
544 if ( '/' != WP_CONTENT_DIR ) |
|
545 $theme_loc = str_replace(WP_CONTENT_DIR, '', $theme_root); |
|
546 |
|
547 /* Files in the root of the current theme directory and one subdir down */ |
|
548 $themes_dir = @ opendir($theme_root); |
|
549 |
|
550 if ( !$themes_dir ) |
|
551 return false; |
|
552 |
|
553 while ( ($theme_dir = readdir($themes_dir)) !== false ) { |
|
554 if ( is_dir($theme_root . '/' . $theme_dir) && is_readable($theme_root . '/' . $theme_dir) ) { |
|
555 if ( $theme_dir{0} == '.' || $theme_dir == 'CVS' ) |
|
556 continue; |
|
557 |
|
558 $stylish_dir = @opendir($theme_root . '/' . $theme_dir); |
|
559 $found_stylesheet = false; |
|
560 |
|
561 while ( ($theme_file = readdir($stylish_dir)) !== false ) { |
|
562 if ( $theme_file == 'style.css' ) { |
|
563 $theme_files[$theme_dir] = array( 'theme_file' => $theme_dir . '/' . $theme_file, 'theme_root' => $theme_root ); |
|
564 $found_stylesheet = true; |
|
565 break; |
|
566 } |
|
567 } |
|
568 @closedir($stylish_dir); |
|
569 |
|
570 if ( !$found_stylesheet ) { // look for themes in that dir |
|
571 $subdir = "$theme_root/$theme_dir"; |
|
572 $subdir_name = $theme_dir; |
|
573 $theme_subdirs = @opendir( $subdir ); |
|
574 |
|
575 $found_subdir_themes = false; |
|
576 while ( ($theme_subdir = readdir($theme_subdirs)) !== false ) { |
|
577 if ( is_dir( $subdir . '/' . $theme_subdir) && is_readable($subdir . '/' . $theme_subdir) ) { |
|
578 if ( $theme_subdir{0} == '.' || $theme_subdir == 'CVS' ) |
|
579 continue; |
|
580 |
|
581 $stylish_dir = @opendir($subdir . '/' . $theme_subdir); |
|
582 $found_stylesheet = false; |
|
583 |
|
584 while ( ($theme_file = readdir($stylish_dir)) !== false ) { |
|
585 if ( $theme_file == 'style.css' ) { |
|
586 $theme_files["$theme_dir/$theme_subdir"] = array( 'theme_file' => $subdir_name . '/' . $theme_subdir . '/' . $theme_file, 'theme_root' => $theme_root ); |
|
587 $found_stylesheet = true; |
|
588 $found_subdir_themes = true; |
|
589 break; |
|
590 } |
|
591 } |
|
592 @closedir($stylish_dir); |
|
593 } |
|
594 } |
|
595 @closedir($theme_subdir); |
|
596 if ( !$found_subdir_themes ) |
|
597 $wp_broken_themes[$theme_dir] = array('Name' => $theme_dir, 'Title' => $theme_dir, 'Description' => __('Stylesheet is missing.')); |
|
598 } |
|
599 } |
|
600 } |
|
601 if ( is_dir( $theme_dir ) ) |
|
602 @closedir( $theme_dir ); |
|
603 } |
|
604 return $theme_files; |
|
605 } |
|
606 |
|
607 /** |
502 * Retrieve path to themes directory. |
608 * Retrieve path to themes directory. |
503 * |
609 * |
504 * Does not have trailing slash. |
610 * Does not have trailing slash. |
505 * |
611 * |
506 * @since 1.5.0 |
612 * @since 1.5.0 |
|
613 * @param $stylesheet_or_template The stylesheet or template name of the theme |
507 * @uses apply_filters() Calls 'theme_root' filter on path. |
614 * @uses apply_filters() Calls 'theme_root' filter on path. |
508 * |
615 * |
509 * @return string Theme path. |
616 * @return string Theme path. |
510 */ |
617 */ |
511 function get_theme_root() { |
618 function get_theme_root( $stylesheet_or_template = false ) { |
512 return apply_filters('theme_root', WP_CONTENT_DIR . "/themes"); |
619 if ($stylesheet_or_template) { |
|
620 $theme_roots = get_theme_roots(); |
|
621 |
|
622 if ( $theme_roots[$stylesheet_or_template] ) |
|
623 $theme_root = WP_CONTENT_DIR . $theme_roots[$stylesheet_or_template]; |
|
624 else |
|
625 $theme_root = WP_CONTENT_DIR . '/themes'; |
|
626 } else { |
|
627 $theme_root = WP_CONTENT_DIR . '/themes'; |
|
628 } |
|
629 |
|
630 return apply_filters( 'theme_root', $theme_root ); |
513 } |
631 } |
514 |
632 |
515 /** |
633 /** |
516 * Retrieve URI for themes directory. |
634 * Retrieve URI for themes directory. |
517 * |
635 * |
518 * Does not have trailing slash. |
636 * Does not have trailing slash. |
519 * |
637 * |
520 * @since 1.5.0 |
638 * @since 1.5.0 |
|
639 * @param $stylesheet_or_template The stylesheet or template name of the theme |
521 * |
640 * |
522 * @return string Themes URI. |
641 * @return string Themes URI. |
523 */ |
642 */ |
524 function get_theme_root_uri() { |
643 function get_theme_root_uri( $stylesheet_or_template = false ) { |
525 return apply_filters('theme_root_uri', content_url('themes'), get_option('siteurl')); |
644 $theme_roots = get_theme_roots(); |
|
645 |
|
646 if ( $theme_roots[$stylesheet_or_template] ) |
|
647 $theme_root_uri = content_url( $theme_roots[$stylesheet_or_template] ); |
|
648 else |
|
649 $theme_root_uri = content_url( 'themes' ); |
|
650 |
|
651 return apply_filters( 'theme_root_uri', $theme_root_uri, get_option('siteurl'), $stylesheet_or_template ); |
526 } |
652 } |
527 |
653 |
528 /** |
654 /** |
529 * Retrieve path to file without the use of extension. |
655 * Retrieve path to file without the use of extension. |
530 * |
656 * |
588 } |
714 } |
589 |
715 |
590 /** |
716 /** |
591 * Retrieve path of category template in current or parent template. |
717 * Retrieve path of category template in current or parent template. |
592 * |
718 * |
593 * Works by retrieving the current category ID, for example 'category-1.php' and |
719 * Works by first retrieving the current slug for example 'category-default.php' and then |
594 * will fallback to category.php template, if the ID category file doesn't |
720 * trying category ID, for example 'category-1.php' and will finally fallback to category.php |
595 * exist. |
721 * template, if those files don't exist. |
596 * |
722 * |
597 * @since 1.5.0 |
723 * @since 1.5.0 |
598 * @uses apply_filters() Calls 'category_template' on file path of category template. |
724 * @uses apply_filters() Calls 'category_template' on file path of category template. |
599 * |
725 * |
600 * @return string |
726 * @return string |
601 */ |
727 */ |
602 function get_category_template() { |
728 function get_category_template() { |
603 $template = locate_template(array("category-" . absint( get_query_var('cat') ) . '.php', 'category.php')); |
729 $cat_ID = absint( get_query_var('cat') ); |
|
730 $category = get_category( $cat_ID ); |
|
731 |
|
732 $templates = array(); |
|
733 |
|
734 if ( !is_wp_error($category) ) |
|
735 $templates[] = "category-{$category->slug}.php"; |
|
736 |
|
737 $templates[] = "category-$cat_ID.php"; |
|
738 $templates[] = "category.php"; |
|
739 |
|
740 $template = locate_template($templates); |
604 return apply_filters('category_template', $template); |
741 return apply_filters('category_template', $template); |
605 } |
742 } |
606 |
743 |
607 /** |
744 /** |
608 * Retrieve path of tag template in current or parent template. |
745 * Retrieve path of tag template in current or parent template. |
609 * |
746 * |
610 * Works by retrieving the current tag name, for example 'tag-wordpress.php' and will |
747 * Works by first retrieving the current tag name, for example 'tag-wordpress.php' and then |
611 * fallback to tag.php template, if the name tag file doesn't exist. |
748 * trying tag ID, for example 'tag-1.php' and will finally fallback to tag.php |
|
749 * template, if those files don't exist. |
612 * |
750 * |
613 * @since 2.3.0 |
751 * @since 2.3.0 |
614 * @uses apply_filters() Calls 'tag_template' on file path of tag template. |
752 * @uses apply_filters() Calls 'tag_template' on file path of tag template. |
615 * |
753 * |
616 * @return string |
754 * @return string |
617 */ |
755 */ |
618 function get_tag_template() { |
756 function get_tag_template() { |
619 $template = locate_template(array("tag-" . get_query_var('tag') . '.php', 'tag.php')); |
757 $tag_id = absint( get_query_var('tag_id') ); |
|
758 $tag_name = get_query_var('tag'); |
|
759 |
|
760 $templates = array(); |
|
761 |
|
762 if ( $tag_name ) |
|
763 $templates[] = "tag-$tag_name.php"; |
|
764 if ( $tag_id ) |
|
765 $templates[] = "tag-$tag_id.php"; |
|
766 $templates[] = "tag.php"; |
|
767 |
|
768 $template = locate_template($templates); |
620 return apply_filters('tag_template', $template); |
769 return apply_filters('tag_template', $template); |
621 } |
770 } |
622 |
771 |
623 /** |
772 /** |
624 * Retrieve path of taxonomy template in current or parent template. |
773 * Retrieve path of taxonomy template in current or parent template. |
680 } |
829 } |
681 |
830 |
682 /** |
831 /** |
683 * Retrieve path of page template in current or parent template. |
832 * Retrieve path of page template in current or parent template. |
684 * |
833 * |
685 * First attempt is to look for the file in the '_wp_page_template' page meta |
834 * Will first look for the specifically assigned page template |
686 * data. The second attempt, if the first has a file and is not empty, is to |
835 * The will search for 'page-{slug}.php' followed by 'page-id.php' |
687 * look for 'page.php'. |
836 * and finally 'page.php' |
688 * |
837 * |
689 * @since 1.5.0 |
838 * @since 1.5.0 |
690 * |
839 * |
691 * @return string |
840 * @return string |
692 */ |
841 */ |
693 function get_page_template() { |
842 function get_page_template() { |
694 global $wp_query; |
843 global $wp_query; |
695 |
844 |
696 $id = (int) $wp_query->post->ID; |
845 $id = (int) $wp_query->post->ID; |
697 $template = get_post_meta($id, '_wp_page_template', true); |
846 $template = get_post_meta($id, '_wp_page_template', true); |
|
847 $pagename = get_query_var('pagename'); |
698 |
848 |
699 if ( 'default' == $template ) |
849 if ( 'default' == $template ) |
700 $template = ''; |
850 $template = ''; |
701 |
851 |
702 $templates = array(); |
852 $templates = array(); |
703 if ( !empty($template) && !validate_file($template) ) |
853 if ( !empty($template) && !validate_file($template) ) |
704 $templates[] = $template; |
854 $templates[] = $template; |
705 |
855 if ( $pagename ) |
|
856 $templates[] = "page-$pagename.php"; |
|
857 if ( $id ) |
|
858 $templates[] = "page-$id.php"; |
706 $templates[] = "page.php"; |
859 $templates[] = "page.php"; |
707 |
860 |
708 return apply_filters('page_template', locate_template($templates)); |
861 return apply_filters('page_template', locate_template($templates)); |
709 } |
862 } |
710 |
863 |
1150 require_once(ABSPATH . 'wp-admin/custom-header.php'); |
1309 require_once(ABSPATH . 'wp-admin/custom-header.php'); |
1151 $GLOBALS['custom_image_header'] =& new Custom_Image_Header($admin_header_callback); |
1310 $GLOBALS['custom_image_header'] =& new Custom_Image_Header($admin_header_callback); |
1152 add_action('admin_menu', array(&$GLOBALS['custom_image_header'], 'init')); |
1311 add_action('admin_menu', array(&$GLOBALS['custom_image_header'], 'init')); |
1153 } |
1312 } |
1154 |
1313 |
|
1314 /** |
|
1315 * Allows a theme to register its support of a certain feature |
|
1316 * |
|
1317 * Must be called in the themes functions.php file to work. |
|
1318 * |
|
1319 * @author Mark Jaquith |
|
1320 * @since 2.9 |
|
1321 * @param string $feature the feature being added |
|
1322 */ |
|
1323 function add_theme_support( $feature ) { |
|
1324 global $_wp_theme_features; |
|
1325 |
|
1326 if ( func_num_args() == 1 ) |
|
1327 $_wp_theme_features[$feature] = true; |
|
1328 else |
|
1329 $_wp_theme_features[$feature] = array_slice( func_get_args(), 1 ); |
|
1330 } |
|
1331 |
|
1332 /** |
|
1333 * Checks a theme's support for a given feature |
|
1334 * |
|
1335 * @author Mark Jaquith |
|
1336 * @since 2.9 |
|
1337 * @param string $feature the feature being checked |
|
1338 * @return boolean |
|
1339 */ |
|
1340 |
|
1341 function current_theme_supports( $feature ) { |
|
1342 global $_wp_theme_features; |
|
1343 |
|
1344 if ( !isset( $_wp_theme_features[$feature] ) ) |
|
1345 return false; |
|
1346 |
|
1347 // If no args passed then no extra checks need be performed |
|
1348 if ( func_num_args() <= 1 ) |
|
1349 return true; |
|
1350 |
|
1351 $args = array_slice( func_get_args(), 1 ); |
|
1352 |
|
1353 // @todo Allow pluggable arg checking |
|
1354 switch ( $feature ) { |
|
1355 case 'post-thumbnails': |
|
1356 // post-thumbnails can be registered for only certain content/post types by passing |
|
1357 // an array of types to add_theme_support(). If no array was passed, then |
|
1358 // any type is accepted |
|
1359 if ( true === $_wp_theme_features[$feature] ) // Registered for all types |
|
1360 return true; |
|
1361 $content_type = $args[0]; |
|
1362 if ( in_array($content_type, $_wp_theme_features[$feature][0]) ) |
|
1363 return true; |
|
1364 else |
|
1365 return false; |
|
1366 break; |
|
1367 } |
|
1368 |
|
1369 return true; |
|
1370 } |
|
1371 |
|
1372 /** |
|
1373 * Checks a theme's support for a given feature before loading the functions which implement it. |
|
1374 * |
|
1375 * @author Peter Westwood |
|
1376 * @since 2.9 |
|
1377 * @param string $feature the feature being checked |
|
1378 * @param string $include the file containing the functions that implement the feature |
|
1379 */ |
|
1380 function require_if_theme_supports( $feature, $include) { |
|
1381 if ( current_theme_supports( $feature ) ) |
|
1382 require ( $include ); |
|
1383 } |
|
1384 |
1155 ?> |
1385 ?> |