Wordpress 2.6.2-scripts
[autoinstalls/wordpress.git] / wp-includes / theme.php
1 <?php
2 /*
3  * Theme/template/stylesheet functions.
4  */
5
6 function get_stylesheet() {
7         return apply_filters('stylesheet', get_option('stylesheet'));
8 }
9
10 function get_stylesheet_directory() {
11         $stylesheet = get_stylesheet();
12         $stylesheet_dir = get_theme_root() . "/$stylesheet";
13         return apply_filters('stylesheet_directory', $stylesheet_dir, $stylesheet);
14 }
15
16 function get_stylesheet_directory_uri() {
17         $stylesheet = get_stylesheet();
18         $stylesheet_dir_uri = get_theme_root_uri() . "/$stylesheet";
19         return apply_filters('stylesheet_directory_uri', $stylesheet_dir_uri, $stylesheet);
20 }
21
22 function get_stylesheet_uri() {
23         $stylesheet_dir_uri = get_stylesheet_directory_uri();
24         $stylesheet_uri = $stylesheet_dir_uri . "/style.css";
25         return apply_filters('stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri);
26 }
27
28 function get_locale_stylesheet_uri() {
29         global $wp_locale;
30         $stylesheet_dir_uri = get_stylesheet_directory_uri();
31         $dir = get_stylesheet_directory();
32         $locale = get_locale();
33         if ( file_exists("$dir/$locale.css") )
34                 $stylesheet_uri = "$stylesheet_dir_uri/$locale.css";
35         elseif ( !empty($wp_locale->text_direction) && file_exists("$dir/{$wp_locale->text_direction}.css") )
36                 $stylesheet_uri = "$stylesheet_dir_uri/{$wp_locale->text_direction}.css";
37         else
38                 $stylesheet_uri = '';
39         return apply_filters('locale_stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri);
40 }
41
42 function get_template() {
43         return apply_filters('template', get_option('template'));
44 }
45
46 function get_template_directory() {
47         $template = get_template();
48         $template_dir = get_theme_root() . "/$template";
49         return apply_filters('template_directory', $template_dir, $template);
50 }
51
52 function get_template_directory_uri() {
53         $template = get_template();
54         $template_dir_uri = get_theme_root_uri() . "/$template";
55         return apply_filters('template_directory_uri', $template_dir_uri, $template);
56 }
57
58 function get_theme_data( $theme_file ) {
59         $themes_allowed_tags = array(
60                 'a' => array(
61                         'href' => array(),'title' => array()
62                         ),
63                 'abbr' => array(
64                         'title' => array()
65                         ),
66                 'acronym' => array(
67                         'title' => array()
68                         ),
69                 'code' => array(),
70                 'em' => array(),
71                 'strong' => array()
72         );
73
74         $theme_data = implode( '', file( $theme_file ) );
75         $theme_data = str_replace ( '\r', '\n', $theme_data );
76         preg_match( '|Theme Name:(.*)$|mi', $theme_data, $theme_name );
77         preg_match( '|Theme URI:(.*)$|mi', $theme_data, $theme_uri );
78         preg_match( '|Description:(.*)$|mi', $theme_data, $description );
79
80         if ( preg_match( '|Author URI:(.*)$|mi', $theme_data, $author_uri ) )
81                 $author_uri = clean_url( trim( $author_uri[1]) );
82         else
83                 $author_uti = '';
84
85         if ( preg_match( '|Template:(.*)$|mi', $theme_data, $template ) )
86                 $template = wp_kses( trim( $template[1] ), $themes_allowed_tags );
87         else
88                 $template = '';
89
90         if ( preg_match( '|Version:(.*)|i', $theme_data, $version ) )
91                 $version = wp_kses( trim( $version[1] ), $themes_allowed_tags );
92         else
93                 $version = '';
94
95         if ( preg_match('|Status:(.*)|i', $theme_data, $status) )
96                 $status = wp_kses( trim( $status[1] ), $themes_allowed_tags );
97         else
98                 $status = 'publish';
99
100         if ( preg_match('|Tags:(.*)|i', $theme_data, $tags) )
101                 $tags = array_map( 'trim', explode( ',', wp_kses( trim( $tags[1] ), array() ) ) );
102         else
103                 $tags = array();
104
105         $name = $theme = wp_kses( trim( $theme_name[1] ), $themes_allowed_tags );
106         $theme_uri = clean_url( trim( $theme_uri[1] ) );
107         $description = wptexturize( wp_kses( trim( $description[1] ), $themes_allowed_tags ) );
108
109         if ( preg_match( '|Author:(.*)$|mi', $theme_data, $author_name ) ) {
110                 if ( empty( $author_uri ) ) {
111                         $author = wp_kses( trim( $author_name[1] ), $themes_allowed_tags );
112                 } else {
113                         $author = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $author_uri, __( 'Visit author homepage' ), wp_kses( trim( $author_name[1] ), $themes_allowed_tags ) );
114                 }
115         } else {
116                 $author = __('Anonymous');
117         }
118
119         return array( 'Name' => $name, 'Title' => $theme, 'URI' => $theme_uri, 'Description' => $description, 'Author' => $author, 'Version' => $version, 'Template' => $template, 'Status' => $status, 'Tags' => $tags );
120 }
121
122 function get_themes() {
123         global $wp_themes, $wp_broken_themes;
124
125         if ( isset($wp_themes) )
126                 return $wp_themes;
127
128         $themes = array();
129         $wp_broken_themes = array();
130         $theme_loc = $theme_root = get_theme_root();
131         if ( '/' != WP_CONTENT_DIR ) // don't want to replace all forward slashes, see Trac #4541
132                 $theme_loc = str_replace(WP_CONTENT_DIR, '', $theme_root);
133
134         // Files in wp-content/themes directory and one subdir down
135         $themes_dir = @ opendir($theme_root);
136         if ( !$themes_dir )
137                 return false;
138
139         while ( ($theme_dir = readdir($themes_dir)) !== false ) {
140                 if ( is_dir($theme_root . '/' . $theme_dir) && is_readable($theme_root . '/' . $theme_dir) ) {
141                         if ( $theme_dir{0} == '.' || $theme_dir == '..' || $theme_dir == 'CVS' )
142                                 continue;
143                         $stylish_dir = @ opendir($theme_root . '/' . $theme_dir);
144                         $found_stylesheet = false;
145                         while ( ($theme_file = readdir($stylish_dir)) !== false ) {
146                                 if ( $theme_file == 'style.css' ) {
147                                         $theme_files[] = $theme_dir . '/' . $theme_file;
148                                         $found_stylesheet = true;
149                                         break;
150                                 }
151                         }
152                         @closedir($stylish_dir);
153                         if ( !$found_stylesheet ) { // look for themes in that dir
154                                 $subdir = "$theme_root/$theme_dir";
155                                 $subdir_name = $theme_dir;
156                                 $theme_subdir = @ opendir( $subdir );
157                                 while ( ($theme_dir = readdir($theme_subdir)) !== false ) {
158                                         if ( is_dir( $subdir . '/' . $theme_dir) && is_readable($subdir . '/' . $theme_dir) ) {
159                                                 if ( $theme_dir{0} == '.' || $theme_dir == '..' || $theme_dir == 'CVS' )
160                                                         continue;
161                                                 $stylish_dir = @ opendir($subdir . '/' . $theme_dir);
162                                                 $found_stylesheet = false;
163                                                 while ( ($theme_file = readdir($stylish_dir)) !== false ) {
164                                                         if ( $theme_file == 'style.css' ) {
165                                                                 $theme_files[] = $subdir_name . '/' . $theme_dir . '/' . $theme_file;
166                                                                 $found_stylesheet = true;
167                                                                 break;
168                                                         }
169                                                 }
170                                                 @closedir($stylish_dir);
171                                         }
172                                 }
173                                 @closedir($theme_subdir);
174                                 $wp_broken_themes[$theme_dir] = array('Name' => $theme_dir, 'Title' => $theme_dir, 'Description' => __('Stylesheet is missing.'));
175                         }
176                 }
177         }
178         if ( is_dir( $theme_dir ) )
179                 @closedir( $theme_dir );
180
181         if ( !$themes_dir || !$theme_files )
182                 return $themes;
183
184         sort($theme_files);
185
186         foreach ( (array) $theme_files as $theme_file ) {
187                 if ( !is_readable("$theme_root/$theme_file") ) {
188                         $wp_broken_themes[$theme_file] = array('Name' => $theme_file, 'Title' => $theme_file, 'Description' => __('File not readable.'));
189                         continue;
190                 }
191
192                 $theme_data = get_theme_data("$theme_root/$theme_file");
193
194                 $name        = $theme_data['Name'];
195                 $title       = $theme_data['Title'];
196                 $description = wptexturize($theme_data['Description']);
197                 $version     = $theme_data['Version'];
198                 $author      = $theme_data['Author'];
199                 $template    = $theme_data['Template'];
200                 $stylesheet  = dirname($theme_file);
201
202                 $screenshot = false;
203                 foreach ( array('png', 'gif', 'jpg', 'jpeg') as $ext ) {
204                         if (file_exists("$theme_root/$stylesheet/screenshot.$ext")) {
205                                 $screenshot = "screenshot.$ext";
206                                 break;
207                         }
208                 }
209
210                 if ( empty($name) ) {
211                         $name = dirname($theme_file);
212                         $title = $name;
213                 }
214
215                 if ( empty($template) ) {
216                         if ( file_exists(dirname("$theme_root/$theme_file/index.php")) )
217                                 $template = dirname($theme_file);
218                         else
219                                 continue;
220                 }
221
222                 $template = trim($template);
223
224                 if ( !file_exists("$theme_root/$template/index.php") ) {
225                         $parent_dir = dirname(dirname($theme_file));
226                         if ( file_exists("$theme_root/$parent_dir/$template/index.php") ) {
227                                 $template = "$parent_dir/$template";
228                         } else {
229                                 $wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => __('Template is missing.'));
230                                 continue;
231                         }
232                 }
233
234                 $stylesheet_files = array();
235                 $stylesheet_dir = @ dir("$theme_root/$stylesheet");
236                 if ( $stylesheet_dir ) {
237                         while ( ($file = $stylesheet_dir->read()) !== false ) {
238                                 if ( !preg_match('|^\.+$|', $file) && preg_match('|\.css$|', $file) )
239                                         $stylesheet_files[] = "$theme_loc/$stylesheet/$file";
240                         }
241                 }
242
243                 $template_files = array();
244                 $template_dir = @ dir("$theme_root/$template");
245                 if ( $template_dir ) {
246                         while(($file = $template_dir->read()) !== false) {
247                                 if ( !preg_match('|^\.+$|', $file) && preg_match('|\.php$|', $file) )
248                                         $template_files[] = "$theme_loc/$template/$file";
249                         }
250                 }
251
252                 $template_dir = dirname($template_files[0]);
253                 $stylesheet_dir = dirname($stylesheet_files[0]);
254
255                 if ( empty($template_dir) )
256                         $template_dir = '/';
257                 if ( empty($stylesheet_dir) )
258                         $stylesheet_dir = '/';
259
260                 // Check for theme name collision.  This occurs if a theme is copied to
261                 // a new theme directory and the theme header is not updated.  Whichever
262                 // theme is first keeps the name.  Subsequent themes get a suffix applied.
263                 // The Default and Classic themes always trump their pretenders.
264                 if ( isset($themes[$name]) ) {
265                         if ( ('WordPress Default' == $name || 'WordPress Classic' == $name) &&
266                                          ('default' == $stylesheet || 'classic' == $stylesheet) ) {
267                                 // If another theme has claimed to be one of our default themes, move
268                                 // them aside.
269                                 $suffix = $themes[$name]['Stylesheet'];
270                                 $new_name = "$name/$suffix";
271                                 $themes[$new_name] = $themes[$name];
272                                 $themes[$new_name]['Name'] = $new_name;
273                         } else {
274                                 $name = "$name/$stylesheet";
275                         }
276                 }
277
278                 $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']);
279         }
280
281         // Resolve theme dependencies.
282         $theme_names = array_keys($themes);
283
284         foreach ( (array) $theme_names as $theme_name ) {
285                 $themes[$theme_name]['Parent Theme'] = '';
286                 if ( $themes[$theme_name]['Stylesheet'] != $themes[$theme_name]['Template'] ) {
287                         foreach ( (array) $theme_names as $parent_theme_name ) {
288                                 if ( ($themes[$parent_theme_name]['Stylesheet'] == $themes[$parent_theme_name]['Template']) && ($themes[$parent_theme_name]['Template'] == $themes[$theme_name]['Template']) ) {
289                                         $themes[$theme_name]['Parent Theme'] = $themes[$parent_theme_name]['Name'];
290                                         break;
291                                 }
292                         }
293                 }
294         }
295
296         $wp_themes = $themes;
297
298         return $themes;
299 }
300
301 function get_theme($theme) {
302         $themes = get_themes();
303
304         if ( array_key_exists($theme, $themes) )
305                 return $themes[$theme];
306
307         return NULL;
308 }
309
310 function get_current_theme() {
311         if ( $theme = get_option('current_theme') )
312                 return $theme;
313
314         $themes = get_themes();
315         $theme_names = array_keys($themes);
316         $current_template = get_option('template');
317         $current_stylesheet = get_option('stylesheet');
318         $current_theme = 'WordPress Default';
319
320         if ( $themes ) {
321                 foreach ( (array) $theme_names as $theme_name ) {
322                         if ( $themes[$theme_name]['Stylesheet'] == $current_stylesheet &&
323                                         $themes[$theme_name]['Template'] == $current_template ) {
324                                 $current_theme = $themes[$theme_name]['Name'];
325                                 break;
326                         }
327                 }
328         }
329
330         update_option('current_theme', $current_theme);
331
332         return $current_theme;
333 }
334
335 function get_theme_root() {
336         return apply_filters('theme_root', WP_CONTENT_DIR . "/themes");
337 }
338
339 function get_theme_root_uri() {
340         return apply_filters('theme_root_uri', content_url('themes'), get_option('siteurl'));
341 }
342
343 function get_query_template($type) {
344         $template = '';
345         $type = preg_replace( '|[^a-z0-9-]+|', '', $type );
346         if ( file_exists(TEMPLATEPATH . "/{$type}.php") )
347                 $template = TEMPLATEPATH . "/{$type}.php";
348
349         return apply_filters("{$type}_template", $template);
350 }
351
352 function get_404_template() {
353         return get_query_template('404');
354 }
355
356 function get_archive_template() {
357         return get_query_template('archive');
358 }
359
360 function get_author_template() {
361         return get_query_template('author');
362 }
363
364 function get_category_template() {
365         $template = '';
366         if ( file_exists(TEMPLATEPATH . "/category-" . absint( get_query_var('cat') ) . '.php') )
367                 $template = TEMPLATEPATH . "/category-" . absint( get_query_var('cat') ) . '.php';
368         elseif ( file_exists(TEMPLATEPATH . "/category.php") )
369                 $template = TEMPLATEPATH . "/category.php";
370
371         return apply_filters('category_template', $template);
372 }
373
374 function get_tag_template() {
375         $template = '';
376         if ( file_exists(TEMPLATEPATH . "/tag-" . get_query_var('tag') . '.php') )
377                 $template = TEMPLATEPATH . "/tag-" . get_query_var('tag') . '.php';
378         elseif ( file_exists(TEMPLATEPATH . "/tag.php") )
379                 $template = TEMPLATEPATH . "/tag.php";
380
381         return apply_filters('tag_template', $template);
382 }
383
384 function get_taxonomy_template() {
385         $template = '';
386         $taxonomy = get_query_var('taxonomy');
387         $term = get_query_var('term');
388         if ( $taxonomy && $term && file_exists(TEMPLATEPATH . "/taxonomy-$taxonomy-$term.php") )
389                 $template = TEMPLATEPATH . "/taxonomy-$taxonomy-$term.php";
390         elseif ( $taxonomy && file_exists(TEMPLATEPATH . "/taxonomy-$taxonomy.php") )
391                 $template = TEMPLATEPATH . "/taxonomy-$taxonomy.php";
392         elseif ( file_exists(TEMPLATEPATH . "/taxonomy.php") )
393                 $template = TEMPLATEPATH . "/taxonomy.php";
394
395         return apply_filters('taxonomy_template', $template);
396 }
397
398 function get_date_template() {
399         return get_query_template('date');
400 }
401
402 function get_home_template() {
403         $template = '';
404
405         if ( file_exists(TEMPLATEPATH . "/home.php") )
406                 $template = TEMPLATEPATH . "/home.php";
407         elseif ( file_exists(TEMPLATEPATH . "/index.php") )
408                 $template = TEMPLATEPATH . "/index.php";
409
410         return apply_filters('home_template', $template);
411 }
412
413 function get_page_template() {
414         global $wp_query;
415
416         $id = (int) $wp_query->post->ID;
417         $template = get_post_meta($id, '_wp_page_template', true);
418
419         if ( 'default' == $template )
420                 $template = '';
421
422         if ( !empty($template) && !validate_file($template) && file_exists(TEMPLATEPATH . "/$template") )
423                 $template = TEMPLATEPATH . "/$template";
424         elseif ( file_exists(TEMPLATEPATH . "/page.php") )
425                 $template = TEMPLATEPATH . "/page.php";
426         else
427                 $template = '';
428
429         return apply_filters('page_template', $template);
430 }
431
432 function get_paged_template() {
433         return get_query_template('paged');
434 }
435
436 function get_search_template() {
437         return get_query_template('search');
438 }
439
440 function get_single_template() {
441         return get_query_template('single');
442 }
443
444 function get_attachment_template() {
445         global $posts;
446         $type = explode('/', $posts[0]->post_mime_type);
447         if ( $template = get_query_template($type[0]) )
448                 return $template;
449         elseif ( $template = get_query_template($type[1]) )
450                 return $template;
451         elseif ( $template = get_query_template("$type[0]_$type[1]") )
452                 return $template;
453         else
454                 return get_query_template('attachment');
455 }
456
457 function get_comments_popup_template() {
458         if ( file_exists( TEMPLATEPATH . '/comments-popup.php') )
459                 $template = TEMPLATEPATH . '/comments-popup.php';
460         else
461                 $template = get_theme_root() . '/default/comments-popup.php';
462
463         return apply_filters('comments_popup_template', $template);
464 }
465
466 function load_template($_template_file) {
467         global $posts, $post, $wp_did_header, $wp_did_template_redirect, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID;
468
469         if ( is_array($wp_query->query_vars) )
470                 extract($wp_query->query_vars, EXTR_SKIP);
471
472         require_once($_template_file);
473 }
474
475 function locale_stylesheet() {
476         $stylesheet = get_locale_stylesheet_uri();
477         if ( empty($stylesheet) )
478                 return;
479         echo '<link rel="stylesheet" href="' . $stylesheet . '" type="text/css" media="screen" />';
480 }
481
482 function preview_theme() {
483         if ( ! (isset($_GET['template']) && isset($_GET['preview'])) )
484                 return;
485
486         if ( !current_user_can( 'switch_themes' ) )
487                 return;
488
489         $_GET[template] = preg_replace('|[^a-z0-9_.-]|i', '', $_GET[template]);
490
491         if ( validate_file($_GET[template]) )
492                 return;
493
494         add_filter('template', create_function('', "return '$_GET[template]';") );
495
496         if ( isset($_GET['stylesheet']) ) {
497                 $_GET[stylesheet] = preg_replace('|[^a-z0-9_.-]|i', '', $_GET[stylesheet]);
498                 if ( validate_file($_GET[stylesheet]) )
499                         return;
500                 add_filter('stylesheet', create_function('', "return '$_GET[stylesheet]';") );
501         }
502
503         ob_start( 'preview_theme_ob_filter' );
504 }
505 add_action('setup_theme', 'preview_theme');
506
507 function preview_theme_ob_filter( $content ) {
508         return preg_replace_callback( "|(<a.*?href=([\"']))(.*?)([\"'].*?>)|", 'preview_theme_ob_filter_callback', $content );
509 }
510
511 function preview_theme_ob_filter_callback( $matches ) {
512         if (
513                 ( false !== strpos($matches[3], '/wp-admin/') )
514         ||
515                 ( false !== strpos($matches[3], '://') && 0 !== strpos($matches[3], get_option('home')) )
516         ||
517                 ( false !== strpos($matches[3], '/feed/') )
518         ||
519                 ( false !== strpos($matches[3], '/trackback/') )
520         )
521                 return $matches[1] . "#$matches[2] onclick=$matches[2]return false;" . $matches[4];
522
523         $link = add_query_arg( array('preview' => 1, 'template' => $_GET['template'], 'stylesheet' => @$_GET['stylesheet'] ), $matches[3] );
524         if ( 0 === strpos($link, 'preview=1') )
525                 $link = "?$link";
526         return $matches[1] . attribute_escape( $link ) . $matches[4];
527 }
528
529 function switch_theme($template, $stylesheet) {
530         update_option('template', $template);
531         update_option('stylesheet', $stylesheet);
532         delete_option('current_theme');
533         $theme = get_current_theme();
534         do_action('switch_theme', $theme);
535 }
536
537 function validate_current_theme() {
538         // Don't validate during an install/upgrade.
539         if ( defined('WP_INSTALLING') )
540                 return true;
541
542         if ( get_template() != 'default' && !file_exists(get_template_directory() . '/index.php') ) {
543                 switch_theme('default', 'default');
544                 return false;
545         }
546
547         if ( get_stylesheet() != 'default' && !file_exists(get_template_directory() . '/style.css') ) {
548                 switch_theme('default', 'default');
549                 return false;
550         }
551
552         return true;
553 }
554
555 function get_theme_mod($name, $default = false) {
556         $theme = get_current_theme();
557
558         $mods = get_option("mods_$theme");
559
560         if ( isset($mods[$name]) )
561                 return apply_filters( "theme_mod_$name", $mods[$name] );
562
563         return apply_filters( "theme_mod_$name", sprintf($default, get_template_directory_uri(), get_stylesheet_directory_uri()) );
564 }
565
566 function set_theme_mod($name, $value) {
567         $theme = get_current_theme();
568
569         $mods = get_option("mods_$theme");
570
571         $mods[$name] = $value;
572
573         update_option("mods_$theme", $mods);
574         wp_cache_delete("mods_$theme", 'options');
575 }
576
577 function remove_theme_mod( $name ) {
578         $theme = get_current_theme();
579
580         $mods = get_option("mods_$theme");
581
582         if ( !isset($mods[$name]) )
583                 return;
584
585         unset($mods[$name]);
586
587         if ( empty($mods) )
588                 return remove_theme_mods();
589
590         update_option("mods_$theme", $mods);
591         wp_cache_delete("mods_$theme", 'options');
592 }
593
594 function remove_theme_mods() {
595         $theme = get_current_theme();
596
597         delete_option("mods_$theme");
598 }
599
600 function get_header_textcolor() {
601         return get_theme_mod('header_textcolor', HEADER_TEXTCOLOR);
602 }
603
604 function header_textcolor() {
605         echo get_header_textcolor();
606 }
607
608 function get_header_image() {
609         return get_theme_mod('header_image', HEADER_IMAGE);
610 }
611
612 function header_image() {
613         echo get_header_image();
614 }
615
616 function add_custom_image_header($header_callback, $admin_header_callback) {
617         if ( ! empty($header_callback) )
618                 add_action('wp_head', $header_callback);
619
620         if ( ! is_admin() )
621                 return;
622         require_once(ABSPATH . 'wp-admin/custom-header.php');
623         $GLOBALS['custom_image_header'] =& new Custom_Image_Header($admin_header_callback);
624         add_action('admin_menu', array(&$GLOBALS['custom_image_header'], 'init'));
625 }
626
627 ?>