web/wp-admin/includes/theme.php
changeset 194 32102edaa81b
parent 136 bde1974c263b
child 204 09a1c134465b
equal deleted inserted replaced
193:2f6f6f7551ca 194:32102edaa81b
     5  * @package WordPress
     5  * @package WordPress
     6  * @subpackage Administration
     6  * @subpackage Administration
     7  */
     7  */
     8 
     8 
     9 /**
     9 /**
    10  * {@internal Missing Short Description}}
       
    11  *
       
    12  * @since unknown
       
    13  *
       
    14  * @return unknown
       
    15  */
       
    16 function current_theme_info() {
       
    17 	$themes = get_themes();
       
    18 	$current_theme = get_current_theme();
       
    19 	$ct->name = $current_theme;
       
    20 	$ct->title = $themes[$current_theme]['Title'];
       
    21 	$ct->version = $themes[$current_theme]['Version'];
       
    22 	$ct->parent_theme = $themes[$current_theme]['Parent Theme'];
       
    23 	$ct->template_dir = $themes[$current_theme]['Template Dir'];
       
    24 	$ct->stylesheet_dir = $themes[$current_theme]['Stylesheet Dir'];
       
    25 	$ct->template = $themes[$current_theme]['Template'];
       
    26 	$ct->stylesheet = $themes[$current_theme]['Stylesheet'];
       
    27 	$ct->screenshot = $themes[$current_theme]['Screenshot'];
       
    28 	$ct->description = $themes[$current_theme]['Description'];
       
    29 	$ct->author = $themes[$current_theme]['Author'];
       
    30 	$ct->tags = $themes[$current_theme]['Tags'];
       
    31 	$ct->theme_root = $themes[$current_theme]['Theme Root'];
       
    32 	$ct->theme_root_uri = $themes[$current_theme]['Theme Root URI'];
       
    33 	return $ct;
       
    34 }
       
    35 
       
    36 /**
       
    37  * Remove a theme
    10  * Remove a theme
    38  *
    11  *
    39  * @since 2.8.0
    12  * @since 2.8.0
    40  *
    13  *
    41  * @param string $template Template directory of the theme to delete
    14  * @param string $stylesheet Stylesheet of the theme to delete
       
    15  * @param string $redirect Redirect to page when complete.
    42  * @return mixed
    16  * @return mixed
    43  */
    17  */
    44 function delete_theme($template) {
    18 function delete_theme($stylesheet, $redirect = '') {
    45 	global $wp_filesystem;
    19 	global $wp_filesystem;
    46 
    20 
    47 	if ( empty($template) )
    21 	if ( empty($stylesheet) )
    48 		return false;
    22 		return false;
    49 
    23 
    50 	ob_start();
    24 	ob_start();
    51 	$url = wp_nonce_url('themes.php?action=delete&template=' . $template, 'delete-theme_' . $template);
    25 	if ( empty( $redirect ) )
    52 	if ( false === ($credentials = request_filesystem_credentials($url)) ) {
    26 		$redirect = wp_nonce_url('themes.php?action=delete&stylesheet=' . $stylesheet, 'delete-theme_' . $stylesheet);
       
    27 	if ( false === ($credentials = request_filesystem_credentials($redirect)) ) {
    53 		$data = ob_get_contents();
    28 		$data = ob_get_contents();
    54 		ob_end_clean();
    29 		ob_end_clean();
    55 		if ( ! empty($data) ){
    30 		if ( ! empty($data) ){
    56 			include_once( ABSPATH . 'wp-admin/admin-header.php');
    31 			include_once( ABSPATH . 'wp-admin/admin-header.php');
    57 			echo $data;
    32 			echo $data;
    63 
    38 
    64 	if ( ! WP_Filesystem($credentials) ) {
    39 	if ( ! WP_Filesystem($credentials) ) {
    65 		request_filesystem_credentials($url, '', true); // Failed to connect, Error and request again
    40 		request_filesystem_credentials($url, '', true); // Failed to connect, Error and request again
    66 		$data = ob_get_contents();
    41 		$data = ob_get_contents();
    67 		ob_end_clean();
    42 		ob_end_clean();
    68 		if( ! empty($data) ){
    43 		if ( ! empty($data) ) {
    69 			include_once( ABSPATH . 'wp-admin/admin-header.php');
    44 			include_once( ABSPATH . 'wp-admin/admin-header.php');
    70 			echo $data;
    45 			echo $data;
    71 			include( ABSPATH . 'wp-admin/admin-footer.php');
    46 			include( ABSPATH . 'wp-admin/admin-footer.php');
    72 			exit;
    47 			exit;
    73 		}
    48 		}
    74 		return;
    49 		return;
    75 	}
    50 	}
    76 
    51 
    77 
       
    78 	if ( ! is_object($wp_filesystem) )
    52 	if ( ! is_object($wp_filesystem) )
    79 		return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
    53 		return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
    80 
    54 
    81 	if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() )
    55 	if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() )
    82 		return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors);
    56 		return new WP_Error('fs_error', __('Filesystem error.'), $wp_filesystem->errors);
    83 
    57 
    84 	//Get the base plugin folder
    58 	//Get the base plugin folder
    85 	$themes_dir = $wp_filesystem->wp_themes_dir();
    59 	$themes_dir = $wp_filesystem->wp_themes_dir();
    86 	if ( empty($themes_dir) )
    60 	if ( empty($themes_dir) )
    87 		return new WP_Error('fs_no_themes_dir', __('Unable to locate WordPress theme directory.'));
    61 		return new WP_Error('fs_no_themes_dir', __('Unable to locate WordPress theme directory.'));
    88 
    62 
    89 	$themes_dir = trailingslashit( $themes_dir );
    63 	$themes_dir = trailingslashit( $themes_dir );
    90 
    64 	$theme_dir = trailingslashit($themes_dir . $stylesheet);
    91 	$errors = array();
       
    92 
       
    93 	$theme_dir = trailingslashit($themes_dir . $template);
       
    94 	$deleted = $wp_filesystem->delete($theme_dir, true);
    65 	$deleted = $wp_filesystem->delete($theme_dir, true);
    95 
    66 
    96 	if ( ! $deleted )
    67 	if ( ! $deleted )
    97 		return new WP_Error('could_not_remove_theme', sprintf(__('Could not fully remove the theme %s'), $template) );
    68 		return new WP_Error('could_not_remove_theme', sprintf(__('Could not fully remove the theme %s.'), $stylesheet) );
    98 
    69 
    99 	// Force refresh of theme update information
    70 	// Force refresh of theme update information
   100 	delete_transient('update_themes');
    71 	delete_site_transient('update_themes');
   101 
    72 
   102 	return true;
    73 	return true;
   103 }
    74 }
   104 
    75 
   105 /**
    76 /**
   106  * {@internal Missing Short Description}}
       
   107  *
       
   108  * @since unknown
       
   109  *
       
   110  * @return unknown
       
   111  */
       
   112 function get_broken_themes() {
       
   113 	global $wp_broken_themes;
       
   114 
       
   115 	get_themes();
       
   116 	return $wp_broken_themes;
       
   117 }
       
   118 
       
   119 /**
       
   120  * Get the Page Templates available in this theme
    77  * Get the Page Templates available in this theme
   121  *
    78  *
   122  * @since unknown
    79  * @since 1.5.0
   123  *
    80  *
   124  * @return array Key is template name, Value is template name
    81  * @return array Key is the template name, value is the filename of the template
   125  */
    82  */
   126 function get_page_templates() {
    83 function get_page_templates() {
   127 	$themes = get_themes();
    84 	return array_flip( wp_get_theme()->get_page_templates() );
   128 	$theme = get_current_theme();
       
   129 	$templates = $themes[$theme]['Template Files'];
       
   130 	$page_templates = array();
       
   131 
       
   132 	if ( is_array( $templates ) ) {
       
   133 		$base = array( trailingslashit(get_template_directory()), trailingslashit(get_stylesheet_directory()) );
       
   134 
       
   135 		foreach ( $templates as $template ) {
       
   136 			$basename = str_replace($base, '', $template);
       
   137 
       
   138 			// don't allow template files in subdirectories
       
   139 			if ( false !== strpos($basename, '/') )
       
   140 				continue;
       
   141 
       
   142 			$template_data = implode( '', file( $template ));
       
   143 
       
   144 			$name = '';
       
   145 			if ( preg_match( '|Template Name:(.*)$|mi', $template_data, $name ) )
       
   146 				$name = _cleanup_header_comment($name[1]);
       
   147 
       
   148 			if ( !empty( $name ) ) {
       
   149 				$page_templates[trim( $name )] = $basename;
       
   150 			}
       
   151 		}
       
   152 	}
       
   153 
       
   154 	return $page_templates;
       
   155 }
    85 }
   156 
    86 
   157 /**
    87 /**
   158  * Tidies a filename for url display by the theme editor.
    88  * Tidies a filename for url display by the theme editor.
   159  * 
    89  *
   160  * @since 2.9.0
    90  * @since 2.9.0
   161  * @private
    91  * @access private
   162  * 
    92  *
   163  * @param string $fullpath Full path to the theme file
    93  * @param string $fullpath Full path to the theme file
   164  * @param string $containingfolder Path of the theme parent folder
    94  * @param string $containingfolder Path of the theme parent folder
   165  * @return string
    95  * @return string
   166  */
    96  */
   167 function _get_template_edit_filename($fullpath, $containingfolder) {
    97 function _get_template_edit_filename($fullpath, $containingfolder) {
   168 	return str_replace(dirname(dirname( $containingfolder )) , '', $fullpath);
    98 	return str_replace(dirname(dirname( $containingfolder )) , '', $fullpath);
   169 }
    99 }
   170 
   100 
   171 ?>
   101 /**
       
   102  * Check if there is an update for a theme available.
       
   103  *
       
   104  * Will display link, if there is an update available.
       
   105  *
       
   106  * @since 2.7.0
       
   107  *
       
   108  * @param object $theme Theme data object.
       
   109  * @return bool False if no valid info was passed.
       
   110  */
       
   111 function theme_update_available( $theme ) {
       
   112 	static $themes_update;
       
   113 
       
   114 	if ( !current_user_can('update_themes' ) )
       
   115 		return;
       
   116 
       
   117 	if ( !isset($themes_update) )
       
   118 		$themes_update = get_site_transient('update_themes');
       
   119 
       
   120 	if ( ! is_a( $theme, 'WP_Theme' ) )
       
   121 		return;
       
   122 
       
   123 	$stylesheet = $theme->get_stylesheet();
       
   124 
       
   125 	if ( isset($themes_update->response[ $stylesheet ]) ) {
       
   126 		$update = $themes_update->response[ $stylesheet ];
       
   127 		$theme_name = $theme->display('Name');
       
   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.
       
   129 		$update_url = wp_nonce_url('update.php?action=upgrade-theme&theme=' . urlencode($stylesheet), 'upgrade-theme_' . $stylesheet);
       
   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;"';
       
   131 
       
   132 		if ( !is_multisite() ) {
       
   133 			if ( ! current_user_can('update_themes') )
       
   134 				printf( '<p><strong>' . __('There is a new version of %1$s available. <a href="%2$s" class="thickbox" title="%1$s">View version %3$s details</a>.') . '</strong></p>', $theme_name, $details_url, $update['new_version']);
       
   135 			else if ( empty($update['package']) )
       
   136 				printf( '<p><strong>' . __('There is a new version of %1$s available. <a href="%2$s" class="thickbox" title="%1$s">View version %3$s details</a>. <em>Automatic update is unavailable for this theme.</em>') . '</strong></p>', $theme_name, $details_url, $update['new_version']);
       
   137 			else
       
   138 				printf( '<p><strong>' . __('There is a new version of %1$s available. <a href="%2$s" class="thickbox" title="%1$s">View version %3$s details</a> or <a href="%4$s" %5$s>update now</a>.') . '</strong></p>', $theme_name, $details_url, $update['new_version'], $update_url, $update_onclick );
       
   139 		}
       
   140 	}
       
   141 }
       
   142 
       
   143 /**
       
   144  * Retrieve list of WordPress theme features (aka theme tags)
       
   145  *
       
   146  * @since 3.1.0
       
   147  *
       
   148  * @param bool $api Optional. Whether try to fetch tags from the WP.org API. Defaults to true.
       
   149  * @return array Array of features keyed by category with translations keyed by slug.
       
   150  */
       
   151 function get_theme_feature_list( $api = true ) {
       
   152 	// Hard-coded list is used if api not accessible.
       
   153 	$features = array(
       
   154 			__('Colors') => array(
       
   155 				'black'   => __( 'Black' ),
       
   156 				'blue'    => __( 'Blue' ),
       
   157 				'brown'   => __( 'Brown' ),
       
   158 				'gray'    => __( 'Gray' ),
       
   159 				'green'   => __( 'Green' ),
       
   160 				'orange'  => __( 'Orange' ),
       
   161 				'pink'    => __( 'Pink' ),
       
   162 				'purple'  => __( 'Purple' ),
       
   163 				'red'     => __( 'Red' ),
       
   164 				'silver'  => __( 'Silver' ),
       
   165 				'tan'     => __( 'Tan' ),
       
   166 				'white'   => __( 'White' ),
       
   167 				'yellow'  => __( 'Yellow' ),
       
   168 				'dark'    => __( 'Dark' ),
       
   169 				'light'   => __( 'Light' ),
       
   170 			),
       
   171 
       
   172 		__('Columns') => array(
       
   173 			'one-column'    => __( 'One Column' ),
       
   174 			'two-columns'   => __( 'Two Columns' ),
       
   175 			'three-columns' => __( 'Three Columns' ),
       
   176 			'four-columns'  => __( 'Four Columns' ),
       
   177 			'left-sidebar'  => __( 'Left Sidebar' ),
       
   178 			'right-sidebar' => __( 'Right Sidebar' ),
       
   179 		),
       
   180 
       
   181 		__('Width') => array(
       
   182 			'fixed-width'    => __( 'Fixed Width' ),
       
   183 			'flexible-width' => __( 'Flexible Width' ),
       
   184 		),
       
   185 
       
   186 		__( 'Features' ) => array(
       
   187 			'blavatar'              => __( 'Blavatar' ),
       
   188 			'buddypress'            => __( 'BuddyPress' ),
       
   189 			'custom-background'     => __( 'Custom Background' ),
       
   190 			'custom-colors'         => __( 'Custom Colors' ),
       
   191 			'custom-header'         => __( 'Custom Header' ),
       
   192 			'custom-menu'           => __( 'Custom Menu' ),
       
   193 			'editor-style'          => __( 'Editor Style' ),
       
   194 			'featured-image-header' => __( 'Featured Image Header' ),
       
   195 			'featured-images'       => __( 'Featured Images' ),
       
   196 			'front-page-post-form'  => __( 'Front Page Posting' ),
       
   197 			'full-width-template'   => __( 'Full Width Template' ),
       
   198 			'microformats'          => __( 'Microformats' ),
       
   199 			'post-formats'          => __( 'Post Formats' ),
       
   200 			'rtl-language-support'  => __( 'RTL Language Support' ),
       
   201 			'sticky-post'           => __( 'Sticky Post' ),
       
   202 			'theme-options'         => __( 'Theme Options' ),
       
   203 			'threaded-comments'     => __( 'Threaded Comments' ),
       
   204 			'translation-ready'     => __( 'Translation Ready' ),
       
   205 		),
       
   206 
       
   207 		__( 'Subject' )  => array(
       
   208 			'holiday'       => __( 'Holiday' ),
       
   209 			'photoblogging' => __( 'Photoblogging' ),
       
   210 			'seasonal'      => __( 'Seasonal' ),
       
   211 		)
       
   212 	);
       
   213 
       
   214 	if ( ! $api || ! current_user_can( 'install_themes' ) )
       
   215 		return $features;
       
   216 
       
   217 	if ( !$feature_list = get_site_transient( 'wporg_theme_feature_list' ) )
       
   218 		set_site_transient( 'wporg_theme_feature_list', array( ), 10800);
       
   219 
       
   220 	if ( !$feature_list ) {
       
   221 		$feature_list = themes_api( 'feature_list', array( ) );
       
   222 		if ( is_wp_error( $feature_list ) )
       
   223 			return $features;
       
   224 	}
       
   225 
       
   226 	if ( !$feature_list )
       
   227 		return $features;
       
   228 
       
   229 	set_site_transient( 'wporg_theme_feature_list', $feature_list, 10800 );
       
   230 
       
   231 	$category_translations = array( 'Colors' => __('Colors'), 'Columns' => __('Columns'), 'Width' => __('Width'),
       
   232 								   'Features' => __('Features'), 'Subject' => __('Subject') );
       
   233 
       
   234 	// Loop over the wporg canonical list and apply translations
       
   235 	$wporg_features = array();
       
   236 	foreach ( (array) $feature_list as $feature_category => $feature_items ) {
       
   237 		if ( isset($category_translations[$feature_category]) )
       
   238 			$feature_category = $category_translations[$feature_category];
       
   239 		$wporg_features[$feature_category] = array();
       
   240 
       
   241 		foreach ( $feature_items as $feature ) {
       
   242 			if ( isset($features[$feature_category][$feature]) )
       
   243 				$wporg_features[$feature_category][$feature] = $features[$feature_category][$feature];
       
   244 			else
       
   245 				$wporg_features[$feature_category][$feature] = $feature;
       
   246 		}
       
   247 	}
       
   248 
       
   249 	return $wporg_features;
       
   250 }
       
   251 
       
   252 /**
       
   253  * Retrieve theme installer pages from WordPress Themes API.
       
   254  *
       
   255  * It is possible for a theme to override the Themes API result with three
       
   256  * filters. Assume this is for themes, which can extend on the Theme Info to
       
   257  * offer more choices. This is very powerful and must be used with care, when
       
   258  * overridding the filters.
       
   259  *
       
   260  * The first filter, 'themes_api_args', is for the args and gives the action as
       
   261  * the second parameter. The hook for 'themes_api_args' must ensure that an
       
   262  * object is returned.
       
   263  *
       
   264  * The second filter, 'themes_api', is the result that would be returned.
       
   265  *
       
   266  * @since 2.8.0
       
   267  *
       
   268  * @param string $action
       
   269  * @param array|object $args Optional. Arguments to serialize for the Theme Info API.
       
   270  * @return mixed
       
   271  */
       
   272 function themes_api($action, $args = null) {
       
   273 
       
   274 	if ( is_array($args) )
       
   275 		$args = (object)$args;
       
   276 
       
   277 	if ( !isset($args->per_page) )
       
   278 		$args->per_page = 24;
       
   279 
       
   280 	$args = apply_filters('themes_api_args', $args, $action); //NOTE: Ensure that an object is returned via this filter.
       
   281 	$res = apply_filters('themes_api', false, $action, $args); //NOTE: Allows a theme to completely override the builtin WordPress.org API.
       
   282 
       
   283 	if ( ! $res ) {
       
   284 		$request = wp_remote_post('http://api.wordpress.org/themes/info/1.0/', array( 'body' => array('action' => $action, 'request' => serialize($args))) );
       
   285 		if ( is_wp_error($request) ) {
       
   286 			$res = new WP_Error('themes_api_failed', __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="http://wordpress.org/support/">support forums</a>.' ), $request->get_error_message() );
       
   287 		} else {
       
   288 			$res = maybe_unserialize( wp_remote_retrieve_body( $request ) );
       
   289 			if ( ! is_object( $res ) && ! is_array( $res ) )
       
   290 				$res = new WP_Error('themes_api_failed', __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="http://wordpress.org/support/">support forums</a>.' ), wp_remote_retrieve_body( $request ) );
       
   291 		}
       
   292 	}
       
   293 
       
   294 	return apply_filters('themes_api_result', $res, $action, $args);
       
   295 }