diff --git a/wp-admin/css/colors-classic.css b/wp-admin/css/colors-classic.css index 65d0f3831..a3fcbe402 100644 --- a/wp-admin/css/colors-classic.css +++ b/wp-admin/css/colors-classic.css @@ -33,7 +33,8 @@ input.disabled, textarea.disabled { #user_info a:hover, li.widget-list-control-item h4.widget-title a:hover, .submit a, #dashmenu a:hover, #footer a, #upload-menu li a.upload-tab-link, li.widget-list-control-item h4.widget-title a, #dragHelper li.widget-list-control-item h4.widget-title a, -#draghelper li.widget-list-control-item h4.widget-title a:visited, .login #backtoblog a:hover { +#draghelper li.widget-list-control-item h4.widget-title a:visited, .login #backtoblog a:hover, +#plugin-information .action-button a, #plugin-information .action-button a:hover, #plugin-information .action-button a:visited { color: #fff; } @@ -321,7 +322,7 @@ ul#widget-list li.widget-list-item h4.widget-title { color: #fff; } -#rightnow .reallynow { +#rightnow .reallynow, #plugin-information .action-button { background-color: #114973; color: #fff; } @@ -331,7 +332,7 @@ ul#widget-list li.widget-list-item h4.widget-title { background-color: #07273E; } -#adminmenu, div#media-upload-header { +#adminmenu, div#media-upload-header, div#plugin-information-header { background-color: #14568a; border-bottom-color: #07273e; } diff --git a/wp-admin/css/colors-fresh.css b/wp-admin/css/colors-fresh.css index 09e0c5822..fb43754c5 100644 --- a/wp-admin/css/colors-fresh.css +++ b/wp-admin/css/colors-fresh.css @@ -37,7 +37,8 @@ input.disabled, textarea.disabled { #user_info a:hover, li.widget-list-control-item h4.widget-title a:hover, .submit a, #dashmenu a:hover, #footer a, #upload-menu li a.upload-tab-link, li.widget-list-control-item h4.widget-title a, #dragHelper li.widget-list-control-item h4.widget-title a, -#draghelper li.widget-list-control-item h4.widget-title a:visited, .login #backtoblog a:hover { +#draghelper li.widget-list-control-item h4.widget-title a:visited, .login #backtoblog a:hover, +#plugin-information .action-button a, #plugin-information .action-button a:hover, #plugin-information .action-button a:visited { color: #fff; } @@ -295,7 +296,7 @@ ul#widget-list li.widget-list-item h4.widget-title { background-image: url(../images/comment-stalk-fresh.gif); } -#adminmenu li a #awaiting-mod span, #sidemenu li a #update-plugins span, #rightnow .reallynow { +#adminmenu li a #awaiting-mod span, #sidemenu li a #update-plugins span, #rightnow .reallynow, #plugin-information .action-button { background-color: #d54e21; color: #fff; } @@ -304,7 +305,7 @@ ul#widget-list li.widget-list-item h4.widget-title { background-color: #264761; } -#adminmenu, div#media-upload-header { +#adminmenu, div#media-upload-header, div#plugin-information-header { background-color: #e4f2fd; border-bottom-color: #c6d9e9; } diff --git a/wp-admin/css/plugin-install.css b/wp-admin/css/plugin-install.css new file mode 100644 index 000000000..1bd75c79f --- /dev/null +++ b/wp-admin/css/plugin-install.css @@ -0,0 +1,122 @@ +/* NOTE: the following CSS rules(.star*) are taken more or less straight from the bbPress rating plugin. */ +div.star-holder { + position: relative; + height: 19px; + width: 100px; + font-size: 19px; +} +div.star { + height: 100%; + position: absolute; + top: 0px; + left: 0px; + background-color: transparent; + letter-spacing: 1ex; + border: none; +} +div.star.select:hover { background-color: #d00; } +.star1 { width: 20%; } +.star2 { width: 40%; } +.star3 { width: 60%; } +.star4 { width: 80%; } +.star5 { width: 100%; } +.star-average, .star.star-rating { background-color: #fc0; } /* TODO: Colour CSS file */ +.star img, div.star a, div.star a:hover, div.star a:visited { + display: block; + position: absolute; + right: 0px; + border: none; + text-decoration: none; +} +div.star img { + width: 19px; + height: 19px; + border-left: 1px solid #fff; + border-right: 1px solid #fff; +} + +/* Start custom CSS */ +/* TODO: Move remaining colours to Colours CSS */ +/* Header on thickbox */ +#plugin-information-header { + margin: 0; + padding: 0 5px; + font-weight: bold; + position: relative; + border-bottom-width: 1px; + border-bottom-style: solid; + height: 2.5em; +} +#plugin-information ul#sidemenu { + font-weight: normal; + margin: 0 5px; + position: absolute; + left: 0px; + bottom: -1px; +} + +/* Install sidemenu */ + +#plugin-information p.action-button { + width: 100%; + padding-bottom:0; + margin-bottom:0; + margin-top: 10px; +} + +#plugin-information .action-button a { + text-align: center; + font-weight: bold; + text-decoration: none; + display: block; + line-height: 2em; +} + +#plugin-information h2 { + clear: none !important; + margin-right: 200px; +} + +#plugin-information .fyi { + margin-left: 10px; + margin-bottom: 50px; + width: 210px; +} + +#plugin-information .fyi h2 { + font-size: 0.9em; + margin-bottom: 0px; + margin-right: 0px; +} + +#plugin-information .fyi h2.mainheader { + background-color: #cee1ef; /* TODO: Colour CSS file */ + padding: 5px; +} + +#plugin-information .fyi ul { + background-color: #eaf3fa; /* TODO: Colour CSS file */ + padding-top: 10px; + padding-bottom: 10px; + padding-left: 7px; + padding-right: 5px; + margin: 0px; + list-style: none; +} + +#plugin-information .fyi li { + margin-right: 0px; +} + +#plugin-information #section-holder { + padding: 10px; +} + +#plugin-information #section-screenshots li img { + vertical-align: text-top; +} +#plugin-information #section-screenshots li p { + font-style: italic; + padding-left: 20px; + padding-bottom: 2em; +} \ No newline at end of file diff --git a/wp-admin/images/star.gif b/wp-admin/images/star.gif new file mode 100644 index 000000000..c96b94472 Binary files /dev/null and b/wp-admin/images/star.gif differ diff --git a/wp-admin/includes/class-wp-filesystem-ftpext.php b/wp-admin/includes/class-wp-filesystem-ftpext.php index 20699351d..eb5e44a59 100644 --- a/wp-admin/includes/class-wp-filesystem-ftpext.php +++ b/wp-admin/includes/class-wp-filesystem-ftpext.php @@ -119,7 +119,7 @@ class WP_Filesystem_FTPext extends WP_Filesystem_Base{ return $ret; } function cwd() { - $cwd = ftp_pwd($this->link); + $cwd = @ftp_pwd($this->link); if( $cwd ) $cwd = trailingslashit($cwd); return $cwd; diff --git a/wp-admin/includes/dashboard.php b/wp-admin/includes/dashboard.php index 27839fcfd..fe92c70f7 100644 --- a/wp-admin/includes/dashboard.php +++ b/wp-admin/includes/dashboard.php @@ -433,10 +433,16 @@ function wp_dashboard_plugins_output() { list($link, $frag) = explode( '#', $item['link'] ); $link = clean_url($link); - $dlink = rtrim($link, '/') . '/download/'; + if( preg_match('|/([^/]+?)/?$|', $link, $matches) ) + $slug = $matches[1]; + else + $slug = ''; + + $ilink = wp_nonce_url('plugin-install.php?tab=install-confirmation&plugin=' . $slug, 'install-plugin_' . $slug) . + '&TB_iframe=true&width=600&height=800'; echo "

$label

\n"; - echo "
$title
 (" . __( 'Download' ) . ")\n"; + echo "
$title
 (" . __( 'Install' ) . ")\n"; echo "

$description

\n"; } } diff --git a/wp-admin/includes/file.php b/wp-admin/includes/file.php index 349feb2e6..67b048399 100644 --- a/wp-admin/includes/file.php +++ b/wp-admin/includes/file.php @@ -458,4 +458,78 @@ function get_filesystem_method() { return apply_filters('filesystem_method', $method); } -?> \ No newline at end of file +function request_filesystem_credentials($form_post, $type = '', $error = false) { + $req_cred = apply_filters('request_filesystem_credentials', '', $form_post, $type, $error); + if ( '' !== $req_cred ) + return $req_cred; + + if ( empty($type) ) + $type = get_filesystem_method(); + + if ( 'direct' == $type ) + return true; + + if( ! $credentials = get_option('ftp_credentials') ) + $credentials = array(); + // If defined, set it to that, Else, If POST'd, set it to that, If not, Set it to whatever it previously was(saved details in option) + $credentials['hostname'] = defined('FTP_HOST') ? FTP_HOST : (!empty($_POST['hostname']) ? $_POST['hostname'] : $credentials['hostname']); + $credentials['username'] = defined('FTP_USER') ? FTP_USER : (!empty($_POST['username']) ? $_POST['username'] : $credentials['username']); + $credentials['password'] = defined('FTP_PASS') ? FTP_PASS : (!empty($_POST['password']) ? $_POST['password'] : $credentials['password']); + $credentials['ssl'] = defined('FTP_SSL') ? FTP_SSL : ( isset($_POST['ssl']) ? $_POST['ssl'] : $credentials['ssl']); + + if ( ! $error && !empty($credentials['password']) && !empty($credentials['username']) && !empty($credentials['hostname']) ) { + $stored_credentials = $credentials; + unset($stored_credentials['password']); + update_option('ftp_credentials', $stored_credentials); + return $credentials; + } + $hostname = ''; + $username = ''; + $password = ''; + $ssl = ''; + if ( !empty($credentials) ) + extract($credentials, EXTR_OVERWRITE); + if( $error ) + echo '

' . __('Error: There was an error connecting to the server, Please verify the settings are correct.') . '

'; +?> +
+
+

+

+ + + + + + + + + + + + + + + + + +
size="40" />
size="40" />
size="40" />'.__('(Password not shown)').''; ?>
+ +
+

+ +

+
+
+ diff --git a/wp-admin/includes/misc.php b/wp-admin/includes/misc.php index 4ee545639..90afdcf0f 100644 --- a/wp-admin/includes/misc.php +++ b/wp-admin/includes/misc.php @@ -160,4 +160,14 @@ function wp_reset_vars( $vars ) { } } +function show_message($message) { + if( is_wp_error($message) ){ + if( $message->get_error_data() ) + $message = $message->get_error_message() . ': ' . $message->get_error_data(); + else + $message = $message->get_error_message(); + } + echo "

$message

\n"; +} + ?> diff --git a/wp-admin/includes/plugin-install.php b/wp-admin/includes/plugin-install.php new file mode 100644 index 000000000..d80d89b11 --- /dev/null +++ b/wp-admin/includes/plugin-install.php @@ -0,0 +1,532 @@ + $action, 'request' => serialize($args))) );//Note: http_build_query() can be removed once WP_HTTP accepts unencoded data. + $res = unserialize($request['body']); + if ( ! $res ) + wp_die($request['body']); + } + + return apply_filters('plugins_api_result', $res); +} + +function install_popular_tags( $args = array() ) { + if ( ! $cache = get_option('wporg_popular_tags') ) + add_option('wporg_popular_tags', array(), '', 'no');///No autoload. + + if ( $cache && $cache->timeout + 3 * 60 * 60 > time() ) + return $cache->cached; + + $tags = plugins_api('hot_tags'); + + update_option('wporg_popular_tags', (object) array('timeout' => time(), 'cached' => $tags)); + + return $tags; +} + +add_action('install_plugins_search', 'install_search', 10, 1); +function install_search($page) { + $type = isset($_REQUEST['type']) ? $_REQUEST['type'] : ''; + $term = isset($_REQUEST['s']) ? $_REQUEST['s'] : ''; + + if( ! empty($term) ){ + $args = array(); + + switch( $type ){ + case 'tag': + $args['tag'] = sanitize_title_with_dashes($term); + break; + case 'term': + $args['search'] = $term; + break; + case 'author': + $args['author'] = $term; + break; + } + + $args['page'] = $page; + + $api = plugins_api('query_plugins', $args); + + add_action('install_plugins_table_header', 'install_search_form'); + + display_plugins_table($api->plugins, $api->info['page'], $api->info['pages']); + + return; + } + ?> + +

WordPress Plugin Directory via this page.') ?>

+ +

+ +


+ Term: Searches plugins names and descriptions for the specified term') ?>
+ Tag: Searches for plugins tagged as such') ?>
+ Author: Searches for plugins created by the Author, or which the Author contributed to.') ?>

+ +

+

+ clean_url( admin_url('plugin-install.php?tab=search&type=tag&s=' . urlencode($tag['name'])) ), + 'name' => $tag['name'], + 'count' => $tag['count'] ); + echo wp_generate_tag_cloud($tags, array( 'single_text' => __('%d plugin'), 'multiple_text' => __('%d plugins') ) ); +} + +function install_search_form(){ + $type = isset($_REQUEST['type']) ? $_REQUEST['type'] : ''; + $term = isset($_REQUEST['s']) ? $_REQUEST['s'] : ''; + + ?>
+ + + +
'featured', 'page' => $page); + $api = plugins_api('query_plugins', $args); + display_plugins_table($api->plugins, $api->info['page'], $api->info['pages']); +} +add_action('install_plugins_popular', 'install_popular', 10, 1); +function install_popular($page){ + $args = array('browse' => 'popular', 'page' => $page); + $api = plugins_api('query_plugins', $args); + display_plugins_table($api->plugins, $api->info['page'], $api->info['pages']); +} +add_action('install_plugins_new', 'install_new', 10, 1); +function install_new($page){ + $args = array('browse' => 'new', 'page' => $page); + $api = plugins_api('query_plugins', $args); + display_plugins_table($api->plugins, $api->info['page'], $api->info['pages']); +} +add_action('install_plugins_updated', 'install_updated', 10, 1); +function install_updated($page){ + $args = array('browse' => 'updated', 'page' => $page); + $api = plugins_api('query_plugins', $args); + display_plugins_table($api->plugins, $api->info['page'], $api->info['pages']); +} +add_action('install_plugins_upload', 'install_upload_custom', 10, 1); +function install_upload_custom($page){ + //$args = array('browse' => 'updated', 'page' => $page); + //$api = plugins_api('query_plugins', $args); + //display_plugins_table($api->plugins, $api->info['page'], $api->info['pages']); + echo '

Not Implemented

Will utilise SwfUpload(if available) & unzip .zip plugin packages

'; +} + +function display_plugins_table($plugins, $page = 1, $totalpages = 1){ + global $tab; + + $type = isset($_REQUEST['type']) ? $_REQUEST['type'] : ''; + $term = isset($_REQUEST['s']) ? $_REQUEST['s'] : ''; + + $plugins_allowedtags = array('a' => array('href' => array(),'title' => array(), 'target' => array()),'abbr' => array('title' => array()),'acronym' => array('title' => array()),'code' => array(),'em' => array(),'strong' => array()); + +?> +
+
+ +
+ add_query_arg('paged', '%#%', $url), + 'format' => '', + 'total' => $totalpages, + 'current' => $page + )); + + if ( $page_links ) + echo "\t\t
$page_links
"; +?> +
+
+ + + + + + + + + + + + '; + + foreach( (array) $plugins as $plugin ){ + if ( is_object($plugin) ) + $plugin = (array) $plugin; + + $title = wp_kses($plugin['name'], $plugins_allowedtags); + $description = wp_kses($plugin['description'], $plugins_allowedtags); + $version = wp_kses($plugin['version'], $plugins_allowedtags); + + $name = strip_tags($title . ' ' . $version); + + $author = $plugin['author']; + if( ! empty($plugin['author']) ) + $author = ' ' . sprintf( __('By %s'), $author ) . '.'; + + $author = wp_kses($author, $plugins_allowedtags); + + if( isset($plugin['homepage']) ) + $title = '' . $title . ''; + + $action_links = array(); + $action_links[] = '' . __('Install') . ''; + + $action_links = apply_filters('plugin_install_action_links', $action_links, $plugin); + ?> + + + + + + + + + +
', __('No plugins match your request.'), '
+
+
+
<?php _e('5 stars') ?>
+
<?php _e('4 stars') ?>
+
<?php _e('3 stars') ?>
+
<?php _e('2 stars') ?>
+
<?php _e('1 star') ?>
+
+

+ + + > + + +<?php bloginfo('name') ?> › <?php echo $title ?> + + + + +> + +'; +} + +add_action('install_plugins_pre_plugin-information', 'install_plugin_information'); +function install_plugin_information() { + global $tab; + + $api = plugins_api('plugin_information', array('slug' => $_REQUEST['plugin'])); + + $section = isset($_REQUEST['section']) ? $_REQUEST['section'] : 'description'; //Default to the Description tab, Do not translate, API returns English. + if( empty($section) || ! isset($api->sections[ $section ]) ) + $section = array_shift( $section_titles = array_keys((array)$api->sections) ); + + install_iframe_header(); + echo "
\n"; + echo "\n"; + echo "
\n"; + + ?> +
+ download_link) ) : ?> +

+ slug ) ) { //TODO: Make more.. searchable? + $type = 'latest_installed'; + $update_plugins = get_option('update_plugins'); + foreach ( (array)$update_plugins->response as $file => $plugin ) { + if ( $plugin->slug === $api->slug ) { + $type = 'update_available'; + $update_file = $file; + break; + } + } + } + + switch ( $type ) : + default: + case 'install': + if ( current_user_can('install_plugins') ) : + ?> +

+ +

+ +

+
+
+
<?php _e('5 stars') ?>
+
<?php _e('4 stars') ?>
+
<?php _e('3 stars') ?>
+
<?php _e('2 stars') ?>
+
<?php _e('1 star') ?>
+
+ num_ratings) ?> +
+ \n"; + foreach ( (array)$api->sections as $section_name => $content ) { + $title = $section_name; + $title[0] = strtoupper($title[0]); + $title = str_replace('_', ' ', $title); + + $content = links_add_base_url($content, 'http://wordpress.org/extend/plugins/' . $api->slug . '/'); + $content = links_add_target($content, '_blank'); + + $san_title = attribute_escape(sanitize_title_with_dashes($title)); + + $display = ( $section_name == $section ) ? 'block' : 'none'; + + echo "\t
\n"; + echo "\t\t

$title

"; + echo $content; + echo "\t
\n"; + } + echo "\n"; + + //var_dump($api); + exit; +} + +add_action('install_plugins_pre_install', 'install_plugin'); +function install_plugin() { + + check_admin_referer('install-plugin_' . $_REQUEST['plugin']); + + install_iframe_header(); + + $api = plugins_api('plugin_information', array('slug' => $_REQUEST['plugin'], 'fields' => array('sections' => false) ) ); //Save on a bit of bandwidth. + + echo '
'; + echo '

', sprintf( __('Installing Plugin: %s'), $api->name . ' ' . $api->version ), '

'; + + do_plugin_install($api->download_link); + echo '
'; + + exit; +} +function do_plugin_install($download_url = '') { + global $wp_filesystem; + + if ( empty($download_url) ) { + show_message( __('No plugin Specified') ); + return; + } + + $plugin = isset($_REQUEST['plugin']) ? $_REQUEST['plugin'] : ''; + + $url = 'plugin-install.php?tab=install'; + $url = add_query_arg(array('plugin' => $plugin, 'plugin_name' => $_REQUEST['plugin_name'], 'download_url' => $_REQUEST['download_url']), $url); + + $url = wp_nonce_url($url, "install-plugin_$plugin"); + if ( false === ($credentials = request_filesystem_credentials($url)) ) + return; + + if ( ! WP_Filesystem($credentials) ) { + request_filesystem_credentials($url, '', true); //Failed to connect, Error and request again + return; + } + + if ( $wp_filesystem->errors->get_error_code() ) { + foreach ( $wp_filesystem->errors->get_error_messages() as $message ) + show_message($message); + return; + } + + $result = wp_install_plugin( $download_url, 'show_message' ); + + if ( is_wp_error($result) ) { + show_message($result); + show_message( __('Installation Failed') ); + } else { + show_message( sprintf(__('Successfully installed the plugin %s %s.'), $plugin_information->name, $plugin_information->version) ); + } +} + +function wp_install_plugin($package, $feedback = '') { + global $wp_filesystem; + + if ( !empty($feedback) ) + add_filter('install_feedback', $feedback); + + // Is a filesystem accessor setup? + if ( ! $wp_filesystem || ! is_object($wp_filesystem) ) + WP_Filesystem(); + + if ( ! is_object($wp_filesystem) ) + return new WP_Error('fs_unavailable', __('Could not access filesystem.')); + + if ( $wp_filesystem->errors->get_error_code() ) + return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors); + + //Get the base plugin folder + $plugins_dir = $wp_filesystem->wp_plugins_dir(); + if ( empty($plugins_dir) ) + return new WP_Error('fs_no_plugins_dir', __('Unable to locate WordPress Plugin directory.')); + + //And the same for the Content directory. + $content_dir = $wp_filesystem->wp_content_dir(); + if( empty($content_dir) ) + return new WP_Error('fs_no_content_dir', __('Unable to locate WordPress Content directory (wp-content).')); + + $plugins_dir = trailingslashit( $plugins_dir ); + $content_dir = trailingslashit( $content_dir ); + + if ( empty($package) ) + return new WP_Error('no_package', __('Install package not available.')); + + // Download the package + apply_filters('install_feedback', sprintf(__('Downloading plugin package from %s'), $package)); + $download_file = download_url($package); + + if ( is_wp_error($download_file) ) + return new WP_Error('download_failed', __('Download failed.'), $download_file->get_error_message()); + + $working_dir = $content_dir . 'upgrade/' . basename($package, '.zip'); + + // Clean up working directory + if ( $wp_filesystem->is_dir($working_dir) ) + $wp_filesystem->delete($working_dir, true); + + apply_filters('install_feedback', __('Unpacking the plugin package')); + // Unzip package to working directory + $result = unzip_file($download_file, $working_dir); + + // Once extracted, delete the package + unlink($download_file); + + if ( is_wp_error($result) ) { + $wp_filesystem->delete($working_dir, true); + return $result; + } + + //Get a list of the directories in the working directory before we delete it, We need to know the new folder for the plugin + $filelist = array_keys( $wp_filesystem->dirlist($working_dir) ); + + if( $wp_filesystem->exists( $plugins_dir . $filelist[0] ) ) { + $wp_filesystem->delete($working_dir, true); + return new WP_Error('install_folder_exists', __('Folder allready exists.'), $filelist[0] ); + } + + apply_filters('install_feedback', __('Installing the plugin')); + // Copy new version of plugin into place. + $result = copy_dir($working_dir, $plugins_dir); + if ( is_wp_error($result) ) { + $wp_filesystem->delete($working_dir, true); + return $result; + } + + // Remove working directory + $wp_filesystem->delete($working_dir, true); + +} + + +?> \ No newline at end of file diff --git a/wp-admin/includes/schema.php b/wp-admin/includes/schema.php index a3873e78e..28c2d6810 100644 --- a/wp-admin/includes/schema.php +++ b/wp-admin/includes/schema.php @@ -277,6 +277,7 @@ function populate_roles() { populate_roles_230(); populate_roles_250(); populate_roles_260(); + populate_roles_270(); } function populate_roles_160() { @@ -441,4 +442,12 @@ function populate_roles_260() { } } +function populate_roles_270() { + $role = get_role( 'administrator' ); + + if ( !empty( $role ) ) { + $role->add_cap( 'install_plugins' ); + } +} + ?> diff --git a/wp-admin/includes/update.php b/wp-admin/includes/update.php index 7070bad8d..ffb51d00d 100644 --- a/wp-admin/includes/update.php +++ b/wp-admin/includes/update.php @@ -60,13 +60,15 @@ function wp_plugin_update_row( $file, $plugin_data ) { $r = $current->response[ $file ]; + $details_url = admin_url('plugin-install.php?tab=plugin-information&plugin=' . $r->slug . '&TB_iframe=true&width=600&height=800'); + echo ''; if ( ! current_user_can('update_plugins') ) - printf( __('There is a new version of %1$s available. Download version %3$s here.'), $plugin_data['Name'], $r->url, $r->new_version); + printf( __('There is a new version of %1$s available. View version %3$s Details.'), $plugin_data['Name'], $details_url, $r->new_version); else if ( empty($r->package) ) - printf( __('There is a new version of %1$s available. Download version %3$s here automatic upgrade unavailable for this plugin.'), $plugin_data['Name'], $r->url, $r->new_version); + printf( __('There is a new version of %1$s available. View version %3$s Details automatic upgrade unavailable for this plugin.'), $plugin_data['Name'], $details_url, $r->new_version); else - printf( __('There is a new version of %1$s available. Download version %3$s here or upgrade automatically.'), $plugin_data['Name'], $r->url, $r->new_version, wp_nonce_url('update.php?action=upgrade-plugin&plugin=' . $file, 'upgrade-plugin_' . $file) ); + printf( __('There is a new version of %1$s available. View version %3$s Details or upgrade automatically.'), $plugin_data['Name'], $details_url, $r->new_version, wp_nonce_url('update.php?action=upgrade-plugin&plugin=' . $file, 'upgrade-plugin_' . $file) ); echo ''; } diff --git a/wp-admin/includes/upgrade.php b/wp-admin/includes/upgrade.php index fc398ab44..5fa8836c6 100644 --- a/wp-admin/includes/upgrade.php +++ b/wp-admin/includes/upgrade.php @@ -207,6 +207,9 @@ function upgrade_all() { if ( $wp_current_db_version < 8201 ) upgrade_260(); + if ( $wp_current_db_version < 8539 ) + upgrade_270(); + maybe_disable_automattic_widgets(); $wp_rewrite->flush_rules(); @@ -755,6 +758,12 @@ function upgrade_260() { } } +function upgrade_270() { + if ( $wp_current_db_version < 8530 ) + populate_roles_270(); +} + + // The functions we use to actually do stuff // General diff --git a/wp-admin/index.php b/wp-admin/index.php index 2401ef9f9..77e4f7e37 100644 --- a/wp-admin/index.php +++ b/wp-admin/index.php @@ -27,7 +27,10 @@ jQuery(function($) { add_action( 'admin_head', 'index_js' ); wp_enqueue_script( 'jquery' ); +wp_enqueue_script( 'plugin-installer' ); wp_admin_css( 'dashboard' ); +wp_admin_css( 'plugin-installer' ); +add_thickbox(); $title = __('Dashboard'); $parent_file = 'index.php'; diff --git a/wp-admin/js/plugin-install.js b/wp-admin/js/plugin-install.js new file mode 100644 index 000000000..5222efa54 --- /dev/null +++ b/wp-admin/js/plugin-install.js @@ -0,0 +1,53 @@ +/* Plugin Browser Thickbox related JS*/ +jQuery(function($) { + var thickDims = function() { + var tbWindow = $('#TB_window'); + var width = $(window).width(); + var H = $(window).height(); + var W = ( 720 < width ) ? 720 : width; + + if ( tbWindow.size() ) { + tbWindow.width( W - 50 ).height( H - 45 ); + $('#TB_iframeContent').width( W - 50 ).height( H - 75 ); + tbWindow.css({'margin-left': '-' + parseInt((( W - 50 ) / 2),10) + 'px'}); + if ( ! ( $.browser.msie && $.browser.version.substr(0,1) < 7 ) ) + tbWindow.css({'top':'20px','margin-top':'0'}); + }; + + return $('a.thickbox').each( function() { + var href = $(this).attr('href'); + if ( ! href ) + return; + href = href.replace(/&width=[0-9]+/g, ''); + href = href.replace(/&height=[0-9]+/g, ''); + $(this).attr( 'href', href + '&width=' + ( W - 80 ) + '&height=' + ( H - 85 ) ); + }); + }; + + thickDims().click( function() { + $('#TB_title').css({'background-color':'#222','color':'#cfcfcf'}); + $('#TB_ajaxWindowTitle').html('' + plugininstallL10n.plugin_information + ' ' + $(this).attr('title') ); + return false; + }); + + $(window).resize( function() { tb_position() } ); +}); + +/* Plugin install related JS*/ +jQuery(function($) { + $('#install-plugins tbody.plugins tr').click( function() { + $(this).find('.action-links a.onclick').click(); + return false; + }); + + $('#plugin-information #sidemenu a').click( function() { + var tab = $(this).attr('name'); + //Flip the tab + $('#plugin-information-header a.current').removeClass('current'); + $(this).addClass('current'); + //Flip the content. + $('#section-holder div').hide(); //Hide 'em all + $('#section-' + tab).show(); + return false; + }); +}); \ No newline at end of file diff --git a/wp-admin/menu.php b/wp-admin/menu.php index cad05c870..abf8dc054 100644 --- a/wp-admin/menu.php +++ b/wp-admin/menu.php @@ -70,6 +70,7 @@ $submenu['options-general.php'][40] = array(__('Miscellaneous'), 'manage_options $submenu['plugins.php'][5] = array(__('Plugins'), 'activate_plugins', 'plugins.php'); $submenu['plugins.php'][10] = array(__('Plugin Editor'), 'edit_plugins', 'plugin-editor.php'); +$submenu['plugins.php'][15] = array(__('Install Plugins'), 'install_plugins', 'plugin-install.php'); $submenu['themes.php'][5] = array(__('Themes'), 'switch_themes', 'themes.php'); $submenu['themes.php'][10] = array(__('Theme Editor'), 'edit_themes', 'theme-editor.php'); diff --git a/wp-admin/plugin-install.php b/wp-admin/plugin-install.php new file mode 100644 index 000000000..4bbe871cf --- /dev/null +++ b/wp-admin/plugin-install.php @@ -0,0 +1,59 @@ + __('Search Plugins'), + 'upload' => __('Upload a Plugin'), + 'featured' => __('Featured Plugins'), + 'popular' => __('Popular Plugins'), + 'new' => __('Newest Plugins'), + 'updated' => __('Recently Updated Plugins') + ); + +$tabs = apply_filters('install_plugins_tabs', $tabs ); + +if( empty($tab) || ( ! isset($tabs[ $tab ]) && ! in_array($tab, array('install', 'plugin-information')) ) ){ + $tab_actions = array_keys($tabs); + $tab = $tab_actions[0]; +} +if( empty($paged) ) + $paged = 1; + +$body_id = $tab; + +do_action('install_plugins_pre_' . $tab); + +include('admin-header.php'); +?> +
+

+ + +
+ \ No newline at end of file diff --git a/wp-admin/plugins.php b/wp-admin/plugins.php index 039f88cd3..317d562bc 100644 --- a/wp-admin/plugins.php +++ b/wp-admin/plugins.php @@ -122,10 +122,8 @@ if( !empty($action) ) { "; - } + foreach( (array)$plugins as $plugin ) + echo ''; ?> @@ -138,10 +136,8 @@ if( !empty($action) ) { @@ -161,6 +157,8 @@ if( !empty($action) ) { } wp_enqueue_script('admin-forms'); +wp_enqueue_script('plugin-install'); +add_thickbox(); $title = __('Manage Plugins'); require_once('admin-header.php'); @@ -205,7 +203,7 @@ $all_plugins = get_plugins(); $active_plugins = array(); $inactive_plugins = array(); $recent_plugins = array(); -$recently_activated = (array)get_option('recently_activated'); +$recently_activated = (array) get_option('recently_activated'); //Clean out any plugins which were deactivated over a week ago. foreach( $recently_activated as $key => $time ) @@ -374,8 +372,9 @@ function print_plugins_table($plugins, $context = '') {

-

WordPress plugin directory.'); ?>

-

%s directory. Once a plugin is uploaded, you may activate it here.'), WP_PLUGIN_DIR); ?>

+

Plugin Browser/Installer functionality, Or by browsing the WordPress Plugin Directory directly and installing manually.'); ?>

+

manually install a plugin you generally just need to upload the plugin file into your %s directory.'), WP_PLUGIN_DIR); ?>

+

diff --git a/wp-admin/update.php b/wp-admin/update.php index c3cd28924..b01e1d44e 100644 --- a/wp-admin/update.php +++ b/wp-admin/update.php @@ -5,90 +5,6 @@ require_once('admin.php'); if ( ! current_user_can('update_plugins') ) wp_die(__('You do not have sufficient permissions to update plugins for this blog.')); -function request_filesystem_credentials($form_post, $type = '', $error = false) { - $req_cred = apply_filters('request_filesystem_credentials', '', $form_post, $type, $error); - if ( '' !== $req_cred ) - return $req_cred; - - if ( empty($type) ) - $type = get_filesystem_method(); - - if ( 'direct' == $type ) - return true; - - if( ! $credentials = get_option('ftp_credentials') ) - $credentials = array(); - // If defined, set it to that, Else, If POST'd, set it to that, If not, Set it to whatever it previously was(saved details in option) - $credentials['hostname'] = defined('FTP_HOST') ? FTP_HOST : (!empty($_POST['hostname']) ? $_POST['hostname'] : $credentials['hostname']); - $credentials['username'] = defined('FTP_USER') ? FTP_USER : (!empty($_POST['username']) ? $_POST['username'] : $credentials['username']); - $credentials['password'] = defined('FTP_PASS') ? FTP_PASS : (!empty($_POST['password']) ? $_POST['password'] : $credentials['password']); - $credentials['ssl'] = defined('FTP_SSL') ? FTP_SSL : ( isset($_POST['ssl']) ? $_POST['ssl'] : $credentials['ssl']); - - if ( ! $error && !empty($credentials['password']) && !empty($credentials['username']) && !empty($credentials['hostname']) ) { - $stored_credentials = $credentials; - unset($stored_credentials['password']); - update_option('ftp_credentials', $stored_credentials); - return $credentials; - } - $hostname = ''; - $username = ''; - $password = ''; - $ssl = ''; - if ( !empty($credentials) ) - extract($credentials, EXTR_OVERWRITE); - if( $error ) - echo '

' . __('Error: There was an error connecting to the server, Please verify the settings are correct.') . '

'; -?> -
-
-

-

- - - - - - - - - - - - - - - - - -
size="40" />
size="40" />
size="40" />'.__('(Password not shown)').''; ?>
- -
-

- -

-
-
-get_error_data() ) - $message = $message->get_error_message() . ': ' . $message->get_error_data(); - else - $message = $message->get_error_message(); - } - echo "

$message

\n"; -} - function do_plugin_upgrade($plugin) { global $wp_filesystem; diff --git a/wp-includes/category-template.php b/wp-includes/category-template.php index 2c37e9773..5eb9a085b 100644 --- a/wp-includes/category-template.php +++ b/wp-includes/category-template.php @@ -350,10 +350,16 @@ function wp_tag_cloud( $args = '' ) { if ( empty($tags) ) return; - $return = wp_generate_tag_cloud( $tags, $args ); // Here's where those top tags get sorted according to $args + foreach ( $tags as $key => $tag ) { + $link = get_tag_link( $tag->term_id ); + if ( is_wp_error( $link ) ) + return false; - if ( is_wp_error( $return ) ) - return false; + $tags[ $key ]->link = $link; + $tags[ $key ]->id = $tag->term_id; + } + + $return = wp_generate_tag_cloud( $tags, $args ); // Here's where those top tags get sorted according to $args $return = apply_filters( 'wp_tag_cloud', $return, $args ); @@ -363,28 +369,33 @@ function wp_tag_cloud( $args = '' ) { echo $return; } -// $tags = prefetched tag array ( get_tags() ) -// $args['format'] = 'flat' => whitespace separated, 'list' => UL, 'array' => array() -// $args['orderby'] = 'name', 'count' +/** + * Generates a tag cloud (heatmap) from provided data + * + * TODO: Complete + * + * @since 2.6 + * + * $tags = array of objects with the properties 'name', 'link', 'id', and 'count' + * $args['format'] = 'flat' => whitespace separated, 'list' => UL, 'array' => array() + * $args['orderby'] = 'name', 'count' +*/ function wp_generate_tag_cloud( $tags, $args = '' ) { global $wp_rewrite; $defaults = array( - 'smallest' => 8, 'largest' => 22, 'unit' => 'pt', 'number' => 45, - 'format' => 'flat', 'orderby' => 'name', 'order' => 'ASC' + 'smallest' => 8, 'largest' => 22, 'unit' => 'pt', + 'format' => 'flat', 'orderby' => 'name', 'order' => 'ASC', + 'single_text' => '%d topic', 'multiple_text' => '%d topics' ); $args = wp_parse_args( $args, $defaults ); extract($args); - if ( !$tags ) + if ( empty($tags) ) return; - $counts = $tag_links = array(); - foreach ( (array) $tags as $tag ) { - $counts[$tag->name] = $tag->count; - $tag_links[$tag->name] = get_tag_link( $tag->term_id ); - if ( is_wp_error( $tag_links[$tag->name] ) ) - return $tag_links[$tag->name]; - $tag_ids[$tag->name] = $tag->term_id; - } + + $counts = array(); + foreach ( (array) $tags as $tag ) + $counts[ $tag->name ] = $tag->count; $min_count = min($counts); $spread = max($counts) - $min_count; @@ -416,9 +427,10 @@ function wp_generate_tag_cloud( $tags, $args = '' ) { $rel = ( is_object($wp_rewrite) && $wp_rewrite->using_permalinks() ) ? ' rel="tag"' : ''; foreach ( $counts as $tag => $count ) { - $tag_id = $tag_ids[$tag]; - $tag_link = clean_url($tag_links[$tag]); - $a[] = "$tag"; } diff --git a/wp-includes/formatting.php b/wp-includes/formatting.php index 09863061f..84ab78ea7 100644 --- a/wp-includes/formatting.php +++ b/wp-includes/formatting.php @@ -1420,4 +1420,85 @@ function wp_html_excerpt( $str, $count ) { return $str; } +/** + * Add a Base url to relative links in passed content. + * + * By default it supports the 'src' and 'href' attributes, + * However this may be changed via the 3rd param. + * + * @package WordPress + * @since 2.7 + * + * @param string $content String to search for links in + * @param string $base The base URL to prefix to links + * @param array $attrs The attributes which should be processed. + * @eaturn string The processed content. + */ +function links_add_base_url( $content, $base, $attrs = array('src', 'href') ) { + $attrs = implode('|', (array)$attrs); + return preg_replace_callback("!($attrs)=(['\"])(.+?)\\2!i", + create_function('$m', 'return _links_add_base($m, "' . $base . '");'), + $content); +} + +/** + * Callback to add a base url to relative links in passed content. + * + * + * @package WordPress + * @since 2.7 + * + * @internal + * @param string $m The matched link + * @param string $base The base URL to prefix to links + * @eaturn string The processed link + */ +function _links_add_base($m, $base) { + //1 = attribute name 2 = quotation mark 3 = URL + return $m[1] . '=' . $m[2] . + (strpos($m[3], 'http://') === false ? + path_join($base, $m[3]) : + $m[3]) + . $m[2]; +} + +/** + * Adds a Target attribute to all links in passed content. + * + * This function by default only applies to tags, + * however this can be modified by the 3rd param. + * NOTE: Any current target attributed will be striped and replaced. + * + * @package WordPress + * @since 2.7 + * + * @param string $content String to search for links in + * @param string $target The Target to add to the links + * @param array $tags An array of tags to apply to. + * @eaturn string The processed content. + */ +function links_add_target( $content, $target = '_blank', $tags = array('a') ) { + $tags = implode('|', (array)$tags); + return preg_replace_callback("!<($tags)(.+?)>!i", + create_function('$m', 'return _links_add_target($m, "' . $target . '");'), + $content); +} +/** + * Callback to add a target attribute to all links in passed content + * + * + * @package WordPress + * @since 2.7 + * + * @internal + * @param string $m The matched link + * @param string $target The Target to add to the links + * @eaturn string The processed link. + */ +function _links_add_target( $m, $target ) { + $tag = $m[1]; + $link = preg_replace('|(target=[\'"](.*?)[\'"])|i', '', $m[2]); + return '<' . $tag . $link . ' target="' . $target . '">'; +} + ?> diff --git a/wp-includes/script-loader.php b/wp-includes/script-loader.php index fd461619b..4caec11e6 100644 --- a/wp-includes/script-loader.php +++ b/wp-includes/script-loader.php @@ -201,6 +201,12 @@ function wp_default_scripts( &$scripts ) { )); $scripts->add( 'theme-preview', '/wp-admin/js/theme-preview.js', array( 'thickbox', 'jquery' ), '20080625' ); + + $scripts->add( 'plugin-install', '/wp-admin/js/plugin-install.js', array( 'thickbox', 'jquery' ), '20080803' ); + $scripts->localize( 'plugin-install', 'plugininstallL10n', array( + 'plugin_information' => __('Plugin Information:') + ) ); + } } @@ -234,6 +240,7 @@ function wp_default_styles( &$styles ) { $styles->add_data( 'press-this-ie', 'conditional', 'gte IE 6' ); $styles->add( 'thickbox', '/wp-includes/js/thickbox/thickbox.css', array(), '20080613' ); $styles->add( 'login', '/wp-admin/css/login.css' ); + $styles->add( 'plugin-install', '/wp-admin/css/plugin-install.css' ); foreach ( $rtl_styles as $rtl_style ) $styles->add_data( $rtl_style, 'rtl', true ); diff --git a/wp-includes/version.php b/wp-includes/version.php index 721f5d96a..223c085a5 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -15,6 +15,6 @@ $wp_version = '2.7-bleeding'; * * @global int $wp_db_version */ -$wp_db_version = 8370; +$wp_db_version = 8539; ?>