diff --git a/wp/readme.html b/wp/readme.html index d4ef7825..e7562000 100644 --- a/wp/readme.html +++ b/wp/readme.html @@ -9,7 +9,7 @@

WordPress -
Version 4.5.2 +
Version 4.5.3

Semantic Personal Publishing Platform

diff --git a/wp/wp-admin/about.php b/wp/wp-admin/about.php index 8772bf04..f22c555f 100644 --- a/wp/wp-admin/about.php +++ b/wp/wp-admin/about.php @@ -40,6 +40,10 @@ include( ABSPATH . 'wp-admin/admin-header.php' );

+

Version %s addressed some security issues and fixed %2$s bug.', + 'Version %s addressed some security issues and fixed %2$s bugs.', 17 ), '4.5.3', number_format_i18n( 17 ) ); ?> + the release notes.' ), 'https://codex.wordpress.org/Version_4.5.3' ); ?> +

Version %s addressed some security issues.' ), '4.5.2' ); ?> the release notes.' ), 'https://codex.wordpress.org/Version_4.5.2' ); ?>

diff --git a/wp/wp-admin/includes/ajax-actions.php b/wp/wp-admin/includes/ajax-actions.php index e3b345c5..0f558368 100644 --- a/wp/wp-admin/includes/ajax-actions.php +++ b/wp/wp-admin/includes/ajax-actions.php @@ -2761,7 +2761,7 @@ function wp_ajax_get_revision_diffs() { if ( ! $post = get_post( (int) $_REQUEST['post_id'] ) ) wp_send_json_error(); - if ( ! current_user_can( 'read_post', $post->ID ) ) + if ( ! current_user_can( 'edit_post', $post->ID ) ) wp_send_json_error(); // Really just pre-loading the cache here. diff --git a/wp/wp-admin/includes/class-wp-media-list-table.php b/wp/wp-admin/includes/class-wp-media-list-table.php index 98deaac8..82894740 100644 --- a/wp/wp-admin/includes/class-wp-media-list-table.php +++ b/wp/wp-admin/includes/class-wp-media-list-table.php @@ -395,7 +395,7 @@ class WP_Media_List_Table extends WP_List_Table { ID ); - echo wp_basename( $file ); + echo esc_html( wp_basename( $file ) ); ?>

cap->assign_terms ) ) { + unset( $post_data['post_category'] ); + } + } + return $post_data; } @@ -1312,7 +1319,7 @@ function get_sample_permalink_html( $id, $new_title = null, $new_slug = null ) { if ( false !== $view_link ) { $display_link = urldecode( $view_link ); - $return .= '' . $display_link . "\n"; + $return .= '' . esc_html( $display_link ) . "\n"; } else { $return .= '' . $permalink . "\n"; } @@ -1336,14 +1343,14 @@ function get_sample_permalink_html( $id, $new_title = null, $new_slug = null ) { } } - $post_name_html = '' . $post_name_abridged . ''; - $display_link = str_replace( array( '%pagename%', '%postname%' ), $post_name_html, urldecode( $permalink ) ); + $post_name_html = '' . esc_html( $post_name_abridged ) . ''; + $display_link = str_replace( array( '%pagename%', '%postname%' ), $post_name_html, esc_html( urldecode( $permalink ) ) ); $return = '' . __( 'Permalink:' ) . "\n"; $return .= '' . $display_link . "\n"; $return .= '‎'; // Fix bi-directional text display defect in RTL languages. $return .= '\n"; - $return .= '' . $post_name . "\n"; + $return .= '' . esc_html( $post_name ) . "\n"; } /** diff --git a/wp/wp-admin/includes/upgrade.php b/wp/wp-admin/includes/upgrade.php index 9e4e19dd..3ddbc8b1 100644 --- a/wp/wp-admin/includes/upgrade.php +++ b/wp/wp-admin/includes/upgrade.php @@ -2154,6 +2154,9 @@ function dbDelta( $queries = '', $execute = true ) { */ $iqueries = apply_filters( 'dbdelta_insert_queries', $iqueries ); + $text_fields = array( 'tinytext', 'text', 'mediumtext', 'longtext' ); + $blob_fields = array( 'tinyblob', 'blob', 'mediumblob', 'longblob' ); + $global_tables = $wpdb->tables( 'global' ); foreach ( $cqueries as $table => $qry ) { // Upgrade global tables only for the main site. Don't upgrade at all if conditions are not optimal. @@ -2223,9 +2226,24 @@ function dbDelta( $queries = '', $execute = true ) { // Is actual field type different from the field type in query? if ($tablefield->Type != $fieldtype) { + $do_change = true; + if ( in_array( strtolower( $fieldtype ), $text_fields ) && in_array( strtolower( $tablefield->Type ), $text_fields ) ) { + if ( array_search( strtolower( $fieldtype ), $text_fields ) < array_search( strtolower( $tablefield->Type ), $text_fields ) ) { + $do_change = false; + } + } + + if ( in_array( strtolower( $fieldtype ), $blob_fields ) && in_array( strtolower( $tablefield->Type ), $blob_fields ) ) { + if ( array_search( strtolower( $fieldtype ), $blob_fields ) < array_search( strtolower( $tablefield->Type ), $blob_fields ) ) { + $do_change = false; + } + } + + if ( $do_change ) { // Add a query to change the column type - $cqueries[] = "ALTER TABLE {$table} CHANGE COLUMN {$tablefield->Field} " . $cfields[strtolower($tablefield->Field)]; - $for_update[$table.'.'.$tablefield->Field] = "Changed type of {$table}.{$tablefield->Field} from {$tablefield->Type} to {$fieldtype}"; + $cqueries[] = "ALTER TABLE {$table} CHANGE COLUMN {$tablefield->Field} " . $cfields[strtolower($tablefield->Field)]; + $for_update[$table.'.'.$tablefield->Field] = "Changed type of {$table}.{$tablefield->Field} from {$tablefield->Type} to {$fieldtype}"; + } } // Get the default value from the array diff --git a/wp/wp-admin/nav-menus.php b/wp/wp-admin/nav-menus.php index ab15bede..1acfde55 100644 --- a/wp/wp-admin/nav-menus.php +++ b/wp/wp-admin/nav-menus.php @@ -49,30 +49,108 @@ $num_locations = count( array_keys( $locations ) ); // Allowed actions: add, update, delete $action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : 'edit'; +/** + * If a JSON blob of navigation menu data is in POST data, expand it and inject + * it into `$_POST` to avoid PHP `max_input_vars` limitations. See #14134. + * + * @ignore + * @since 4.5.3 + * @access private + */ +function _wp_expand_nav_menu_post_data() { + if ( ! isset( $_POST['nav-menu-data'] ) ) { + return; + } + + $data = json_decode( stripslashes( $_POST['nav-menu-data'] ) ); + + if ( ! is_null( $data ) && $data ) { + foreach ( $data as $post_input_data ) { + // For input names that are arrays (e.g. `menu-item-db-id[3][4][5]`), + // derive the array path keys via regex and set the value in $_POST. + preg_match( '#([^\[]*)(\[(.+)\])?#', $post_input_data->name, $matches ); + + $array_bits = array( $matches[1] ); + + if ( isset( $matches[3] ) ) { + $array_bits = array_merge( $array_bits, explode( '][', $matches[3] ) ); + } + + $new_post_data = array(); + + // Build the new array value from leaf to trunk. + for ( $i = count( $array_bits ) - 1; $i >= 0; $i -- ) { + if ( $i == count( $array_bits ) - 1 ) { + $new_post_data[ $array_bits[ $i ] ] = wp_slash( $post_input_data->value ); + } else { + $new_post_data = array( $array_bits[ $i ] => $new_post_data ); + } + } + + $_POST = array_replace_recursive( $_POST, $new_post_data ); + } + } +} + +if ( ! function_exists( 'array_replace_recursive' ) ) : + /** + * PHP-agnostic version of {@link array_replace_recursive()}. + * + * The array_replace_recursive() function is a PHP 5.3 function. WordPress + * currently supports down to PHP 5.2, so this method is a workaround + * for PHP 5.2. + * + * Note: array_replace_recursive() supports infinite arguments, but for our use- + * case, we only need to support two arguments. + * + * Subject to removal once WordPress makes PHP 5.3.0 the minimum requirement. + * + * @since 4.5.3 + * + * @see http://php.net/manual/en/function.array-replace-recursive.php#109390 + * + * @param array $base Array with keys needing to be replaced. + * @param array $replacements Array with the replaced keys. + * + * @return array + */ + function array_replace_recursive( $base = array(), $replacements = array() ) { + foreach ( array_slice( func_get_args(), 1 ) as $replacements ) { + $bref_stack = array( &$base ); + $head_stack = array( $replacements ); + + do { + end( $bref_stack ); + + $bref = &$bref_stack[ key( $bref_stack ) ]; + $head = array_pop( $head_stack ); + + unset( $bref_stack[ key( $bref_stack ) ] ); + + foreach ( array_keys( $head ) as $key ) { + if ( isset( $key, $bref ) && + isset( $bref[ $key ] ) && is_array( $bref[ $key ] ) && + isset( $head[ $key ] ) && is_array( $head[ $key ] ) + ) { + $bref_stack[] = &$bref[ $key ]; + $head_stack[] = $head[ $key ]; + } else { + $bref[ $key ] = $head[ $key ]; + } + } + } while ( count( $head_stack ) ); + } + + return $base; + } +endif; + /* * If a JSON blob of navigation menu data is found, expand it and inject it * into `$_POST` to avoid PHP `max_input_vars` limitations. See #14134. */ -if ( isset( $_POST['nav-menu-data'] ) ) { - $data = json_decode( stripslashes( $_POST['nav-menu-data'] ) ); - if ( ! is_null( $data ) && $data ) { - foreach ( $data as $post_input_data ) { - // For input names that are arrays (e.g. `menu-item-db-id[3]`), derive the array path keys via regex. - if ( preg_match( '#(.*)\[(\w+)\]#', $post_input_data->name, $matches ) ) { - if ( empty( $_POST[ $matches[1] ] ) ) { - $_POST[ $matches[1] ] = array(); - } - // Cast input elements with a numeric array index to integers. - if ( is_numeric( $matches[2] ) ) { - $matches[2] = (int) $matches[2]; - } - $_POST[ $matches[1] ][ $matches[2] ] = wp_slash( $post_input_data->value ); - } else { - $_POST[ $post_input_data->name ] = wp_slash( $post_input_data->value ); - } - } - } -} +_wp_expand_nav_menu_post_data(); + switch ( $action ) { case 'add-menu-item': check_admin_referer( 'add-menu_item', 'menu-settings-column-nonce' ); diff --git a/wp/wp-admin/options.php b/wp/wp-admin/options.php index e2bfa90f..6bad0fd6 100644 --- a/wp/wp-admin/options.php +++ b/wp/wp-admin/options.php @@ -84,7 +84,7 @@ if ( is_multisite() && ! is_super_admin() && 'update' != $action ) { $whitelist_options = array( 'general' => array( 'blogname', 'blogdescription', 'gmt_offset', 'date_format', 'time_format', 'start_of_week', 'timezone_string', 'WPLANG' ), 'discussion' => array( 'default_pingback_flag', 'default_ping_status', 'default_comment_status', 'comments_notify', 'moderation_notify', 'comment_moderation', 'require_name_email', 'comment_whitelist', 'comment_max_links', 'moderation_keys', 'blacklist_keys', 'show_avatars', 'avatar_rating', 'avatar_default', 'close_comments_for_old_posts', 'close_comments_days_old', 'thread_comments', 'thread_comments_depth', 'page_comments', 'comments_per_page', 'default_comments_page', 'comment_order', 'comment_registration' ), - 'media' => array( 'thumbnail_size_w', 'thumbnail_size_h', 'thumbnail_crop', 'medium_size_w', 'medium_size_h', 'medium_large_size_w', 'medium_large_size_h', 'large_size_w', 'large_size_h', 'image_default_size', 'image_default_align', 'image_default_link_type' ), + 'media' => array( 'thumbnail_size_w', 'thumbnail_size_h', 'thumbnail_crop', 'medium_size_w', 'medium_size_h', 'large_size_w', 'large_size_h', 'image_default_size', 'image_default_align', 'image_default_link_type' ), 'reading' => array( 'posts_per_page', 'posts_per_rss', 'rss_use_excerpt', 'show_on_front', 'page_on_front', 'page_for_posts', 'blog_public' ), 'writing' => array( 'default_category', 'default_email_category', 'default_link_category', 'default_post_format' ) ); diff --git a/wp/wp-admin/revision.php b/wp/wp-admin/revision.php index 4d86c536..d63b26bb 100644 --- a/wp/wp-admin/revision.php +++ b/wp/wp-admin/revision.php @@ -63,7 +63,7 @@ default : if ( ! $post = get_post( $revision->post_parent ) ) break; - if ( ! current_user_can( 'read_post', $revision->ID ) || ! current_user_can( 'read_post', $post->ID ) ) + if ( ! current_user_can( 'read_post', $revision->ID ) || ! current_user_can( 'edit_post', $revision->post_parent ) ) break; // Revisions disabled and we're not looking at an autosave diff --git a/wp/wp-content/plugins/wordpress-seo/.babelrc b/wp/wp-content/plugins/wordpress-seo/.babelrc new file mode 100644 index 00000000..4f654b82 --- /dev/null +++ b/wp/wp-content/plugins/wordpress-seo/.babelrc @@ -0,0 +1,3 @@ +{ + "plugins": ["transform-react-jsx"] +} diff --git a/wp/wp-content/plugins/wordpress-seo/README.md b/wp/wp-content/plugins/wordpress-seo/README.md deleted file mode 100644 index 2e81557e..00000000 --- a/wp/wp-content/plugins/wordpress-seo/README.md +++ /dev/null @@ -1,57 +0,0 @@ -Yoast SEO -====================== - -[![Build Status](https://api.travis-ci.org/Yoast/wordpress-seo.png?branch=master)](https://travis-ci.org/Yoast/wordpress-seo) -[![Stable Version](https://poser.pugx.org/yoast/wordpress-seo/v/stable.svg)](https://packagist.org/packages/yoast/wordpress-seo) -[![License](https://poser.pugx.org/yoast/wordpress-seo/license.svg)](https://packagist.org/packages/yoast/wordpress-seo) - -Welcome to the Yoast SEO GitHub repository ----------------------------------------------- - -While the documentation for the [Yoast SEO plugin](https://yoast.com/wordpress/seo/) can be found on [Yoast.com](https://yoast.com/), here -you can browse the source of the project, find and discuss open issues and even -[contribute yourself](https://github.com/yoast/wordpress-seo/blob/master/CONTRIBUTING.md). - -Installation ------------- - -Here's a [guide on how to install Yoast SEO in your WordPress site](https://yoast.com/wordpress/seo/installation/). - -If you want to run the Git version for development though, you can set it up with [Composer](https://getcomposer.org/): - -```bash -composer create-project yoast/wordpress-seo:dev-trunk --prefer-source --keep-vcs -``` - -Read more about [using Composer with Yoast SEO](https://github.com/Yoast/wordpress-seo/wiki/Using-Composer). - -This will download the latest development version of Yoast SEO. While this version is usually stable, -it is not recommended for use in a production environment. - -Support -------- -This is a developer's portal for Yoast SEO and should not be used for support. Please visit the -[support forums](https://wordpress.org/support/plugin/wordpress-seo). - -Reporting bugs ----- -We try to fix as many bugs we can, this is a graph of our recent activity: -[![Throughput Graph](https://graphs.waffle.io/yoast/wordpress-seo/throughput.svg)](https://waffle.io/yoast/wordpress-seo/metrics) - -If you find an issue, [let us know here](https://github.com/yoast/wordpress-seo/issues/new)! Please follow [how to write a good bug report?](http://kb.yoast.com/article/180-how-to-write-a-good-bug-report) guidelines. - -It may help us a lot if you can provide a backtrace of the error encountered. You can use [code in this gist](https://gist.github.com/jrfnl/5925642) to enable the backtrace in your website's configuration. - -Contributions -------------- -Anyone is welcome to contribute to Yoast SEO. Please -[read the guidelines](https://github.com/yoast/wordpress-seo/blob/master/CONTRIBUTING.md) for contributing to this -repository. - -There are various ways you can contribute: - -* [Raise an issue](https://github.com/yoast/wordpress-seo/issues) on GitHub. -* Send us a Pull Request with your bug fixes and/or new features. -* [Translate Yoast SEO into different languages](http://translate.yoast.com/projects/wordpress-seo/). -* Provide feedback and [suggestions on enhancements](https://github.com/yoast/wordpress-seo/issues?direction=desc&labels=Enhancement&page=1&sort=created&state=open). - diff --git a/wp/wp-content/plugins/wordpress-seo/admin/ajax.php b/wp/wp-content/plugins/wordpress-seo/admin/ajax.php index 317bc387..a6832128 100644 --- a/wp/wp-content/plugins/wordpress-seo/admin/ajax.php +++ b/wp/wp-content/plugins/wordpress-seo/admin/ajax.php @@ -19,7 +19,7 @@ if ( ! defined( 'WPSEO_VERSION' ) ) { * @param array $results Results array for encoding. */ function wpseo_ajax_json_echo_die( $results ) { - echo WPSEO_Utils::json_encode( $results ); + echo wp_json_encode( $results ); die(); } @@ -318,22 +318,6 @@ function wpseo_upsert_new( $what, $post_id, $new, $original ) { return wpseo_upsert_meta( $post_id, $new, $original, $meta_key, $what ); } -/** - * Create an export and return the URL - */ -function wpseo_get_export() { - if ( ! current_user_can( 'manage_options' ) ) { - die( '-1' ); - } - - $include_taxonomy = ( filter_input( INPUT_POST, 'include_taxonomy' ) === 'true' ); - $export = new WPSEO_Export( $include_taxonomy ); - - wpseo_ajax_json_echo_die( $export->get_results() ); -} - -add_action( 'wp_ajax_wpseo_export', 'wpseo_get_export' ); - /** * Handles the posting of a new FB admin. */ @@ -363,7 +347,7 @@ function ajax_get_keyword_usage() { } wp_die( - WPSEO_Utils::json_encode( WPSEO_Meta::keyword_usage( $keyword, $post_id ) ) + wp_json_encode( WPSEO_Meta::keyword_usage( $keyword, $post_id ) ) ); } @@ -375,19 +359,25 @@ add_action( 'wp_ajax_get_focus_keyword_usage', 'ajax_get_keyword_usage' ); function ajax_get_term_keyword_usage() { $post_id = filter_input( INPUT_POST, 'post_id' ); $keyword = filter_input( INPUT_POST, 'keyword' ); - $taxonomy = filter_input( INPUT_POST, 'taxonomy' ); + $taxonomyName = filter_input( INPUT_POST, 'taxonomy' ); - if ( ! current_user_can( 'edit_terms' ) ) { - die( '-1' ); + $taxonomy = get_taxonomy( $taxonomyName ); + + if ( ! $taxonomy ) { + wp_die( 0 ); } - $usage = WPSEO_Taxonomy_Meta::get_keyword_usage( $keyword, $post_id, $taxonomy ); + if ( ! current_user_can( $taxonomy->cap->edit_terms ) ) { + wp_die( -1 ); + } + + $usage = WPSEO_Taxonomy_Meta::get_keyword_usage( $keyword, $post_id, $taxonomyName ); // Normalize the result so it it the same as the post keyword usage AJAX request. $usage = $usage[ $keyword ]; wp_die( - WPSEO_Utils::json_encode( $usage ) + wp_json_encode( $usage ) ); } @@ -443,3 +433,16 @@ new WPSEO_Taxonomy_Columns(); // Setting the notice for the recalculate the posts. new Yoast_Dismissable_Notice_Ajax( 'recalculate', Yoast_Dismissable_Notice_Ajax::FOR_SITE ); + +/********************** DEPRECATED METHODS **********************/ + +/** + * Create an export and return the URL + * + * @deprecated 3.3.2 + */ +function wpseo_get_export() { + _deprecated_function( __METHOD__, 'WPSEO 3.3.2', 'This method is deprecated.' ); + + wpseo_ajax_json_echo_die( '' ); +} diff --git a/wp/wp-content/plugins/wordpress-seo/admin/ajax/class-recalculate-scores-ajax.php b/wp/wp-content/plugins/wordpress-seo/admin/ajax/class-recalculate-scores-ajax.php index 88a87760..66f31b4a 100644 --- a/wp/wp-content/plugins/wordpress-seo/admin/ajax/class-recalculate-scores-ajax.php +++ b/wp/wp-content/plugins/wordpress-seo/admin/ajax/class-recalculate-scores-ajax.php @@ -26,7 +26,7 @@ class WPSEO_Recalculate_Scores_Ajax { check_ajax_referer( 'wpseo_recalculate', 'nonce' ); wp_die( - WPSEO_Utils::json_encode( + wp_json_encode( array( 'posts' => $this->calculate_posts(), 'terms' => $this->calculate_terms(), @@ -47,7 +47,7 @@ class WPSEO_Recalculate_Scores_Ajax { $response = $fetch_object->get_items_to_recalculate( $paged ); if ( ! empty( $response ) ) { - wp_die( WPSEO_Utils::json_encode( $response ) ); + wp_die( wp_json_encode( $response ) ); } } diff --git a/wp/wp-content/plugins/wordpress-seo/admin/ajax/class-yoast-onpage-ajax.php b/wp/wp-content/plugins/wordpress-seo/admin/ajax/class-yoast-onpage-ajax.php index 264564a5..35f791f7 100644 --- a/wp/wp-content/plugins/wordpress-seo/admin/ajax/class-yoast-onpage-ajax.php +++ b/wp/wp-content/plugins/wordpress-seo/admin/ajax/class-yoast-onpage-ajax.php @@ -30,7 +30,7 @@ class Yoast_OnPage_Ajax { } /** - * Storing the the dismissed value as an user option in the database + * Storing the dismissed value as an user option in the database */ private function save_dismissed() { update_user_meta( get_current_user_id(), WPSEO_OnPage::USER_META_KEY, 1 ); diff --git a/wp/wp-content/plugins/wordpress-seo/admin/class-admin-asset-manager.php b/wp/wp-content/plugins/wordpress-seo/admin/class-admin-asset-manager.php index 65b50024..d867e098 100644 --- a/wp/wp-content/plugins/wordpress-seo/admin/class-admin-asset-manager.php +++ b/wp/wp-content/plugins/wordpress-seo/admin/class-admin-asset-manager.php @@ -39,7 +39,7 @@ class WPSEO_Admin_Asset_Manager { public function register_script( WPSEO_Admin_Asset $script ) { wp_register_script( self::PREFIX . $script->get_name(), - plugins_url( 'js/dist/' . $script->get_src() . $script->get_suffix() . '.js', WPSEO_FILE ), + $script->get_url( WPSEO_Admin_Asset::TYPE_JS, WPSEO_FILE ), $script->get_deps(), $script->get_version(), $script->is_in_footer() @@ -54,7 +54,7 @@ class WPSEO_Admin_Asset_Manager { public function register_style( WPSEO_Admin_Asset $style ) { wp_register_style( self::PREFIX . $style->get_name(), - plugins_url( 'css/' . $style->get_src() . $style->get_suffix() . '.css', WPSEO_FILE ), + $style->get_url( WPSEO_Admin_Asset::TYPE_CSS, WPSEO_FILE ), $style->get_deps(), $style->get_version(), $style->get_media() @@ -93,6 +93,20 @@ class WPSEO_Admin_Asset_Manager { } } + /** + * A list of styles that shouldn't be registered but are needed in other locations in the plugin. + * + * @return array + */ + public function special_styles() { + return array( + 'inside-editor' => new WPSEO_Admin_Asset( array( + 'name' => 'inside-editor', + 'src' => 'inside-editor-331', + ) ), + ); + } + /** * Returns the scripts that need to be registered. * @@ -104,7 +118,7 @@ class WPSEO_Admin_Asset_Manager { return array( array( 'name' => 'admin-script', - 'src' => 'wp-seo-admin-320', + 'src' => 'wp-seo-admin-330', 'deps' => array( 'jquery', 'jquery-ui-core', @@ -126,24 +140,19 @@ class WPSEO_Admin_Asset_Manager { 'src' => 'wp-seo-bulk-editor-320', 'deps' => array( 'jquery' ), ), - array( - 'name' => 'export', - 'src' => 'wp-seo-export-320', - 'deps' => array( 'jquery' ), - ), array( 'name' => 'dismissible', - 'src' => 'wp-seo-dismissible-320', + 'src' => 'wp-seo-dismissible-330', 'deps' => array( 'jquery' ), ), array( 'name' => 'admin-global-script', - 'src' => 'wp-seo-admin-global-320', + 'src' => 'wp-seo-admin-global-332', 'deps' => array( 'jquery' ), ), array( 'name' => 'metabox', - 'src' => 'wp-seo-metabox-320', + 'src' => 'wp-seo-metabox-330', 'deps' => array( 'jquery', 'jquery-ui-core', @@ -155,7 +164,7 @@ class WPSEO_Admin_Asset_Manager { ), array( 'name' => 'featured-image', - 'src' => 'wp-seo-featured-image-320', + 'src' => 'wp-seo-featured-image-330', 'deps' => array( 'jquery' ), @@ -168,7 +177,7 @@ class WPSEO_Admin_Asset_Manager { ), array( 'name' => 'post-scraper', - 'src' => 'wp-seo-post-scraper-324', + 'src' => 'wp-seo-post-scraper-332', 'deps' => array( self::PREFIX . 'replacevar-plugin', self::PREFIX . 'shortcode-plugin', @@ -177,14 +186,14 @@ class WPSEO_Admin_Asset_Manager { ), array( 'name' => 'term-scraper', - 'src' => 'wp-seo-term-scraper-324', + 'src' => 'wp-seo-term-scraper-332', 'deps' => array( self::PREFIX . 'replacevar-plugin', ), ), array( 'name' => 'replacevar-plugin', - 'src' => 'wp-seo-replacevar-plugin-320', + 'src' => 'wp-seo-replacevar-plugin-330', ), array( 'name' => 'shortcode-plugin', @@ -240,7 +249,7 @@ class WPSEO_Admin_Asset_Manager { return array( array( 'name' => 'admin-css', - 'src' => 'yst_plugin_tools-320', + 'src' => 'yst_plugin_tools-330', 'deps' => array( self::PREFIX . 'toggle-switch' ), ), // TODO minify toggle styles. R. @@ -252,7 +261,7 @@ class WPSEO_Admin_Asset_Manager { ), array( 'name' => 'toggle-switch', - 'src' => 'toggle-switch', + 'src' => 'toggle-switch-330', 'deps' => array( self::PREFIX . 'toggle-switch-lib' ), ), array( @@ -261,38 +270,42 @@ class WPSEO_Admin_Asset_Manager { ), array( 'name' => 'dismissible', - 'src' => 'wpseo-dismissible', + 'src' => 'wpseo-dismissible-330', + ), + array( + 'name' => 'alerts', + 'src' => 'alerts', ), array( 'name' => 'edit-page', - 'src' => 'edit-page-302', + 'src' => 'edit-page-330', ), array( 'name' => 'featured-image', - 'src' => 'featured-image', + 'src' => 'featured-image-330', ), array( 'name' => 'metabox-css', - 'src' => 'metabox-320', + 'src' => 'metabox-331', 'deps' => array( self::PREFIX . 'select2', ), ), array( 'name' => 'wp-dashboard', - 'src' => 'dashboard-305', + 'src' => 'dashboard-330', ), array( 'name' => 'scoring', - 'src' => 'yst_seo_score-310', + 'src' => 'yst_seo_score-330', ), array( 'name' => 'snippet', - 'src' => 'snippet-320', + 'src' => 'snippet-330', ), array( 'name' => 'adminbar', - 'src' => 'adminbar-320', + 'src' => 'adminbar-330', ), array( 'name' => 'primary-category', @@ -304,6 +317,18 @@ class WPSEO_Admin_Asset_Manager { 'suffix' => '.min', 'version' => '4.0.1', ), + array( + 'name' => 'kb-search', + 'src' => 'kb-search-331', + ), + array( + 'name' => 'help-center', + 'src' => 'help-center-331', + ), + array( + 'name' => 'admin-global', + 'src' => 'admin-global-330', + ), ); } } diff --git a/wp/wp-content/plugins/wordpress-seo/admin/class-admin-init.php b/wp/wp-content/plugins/wordpress-seo/admin/class-admin-init.php index b42fab88..709eefff 100644 --- a/wp/wp-content/plugins/wordpress-seo/admin/class-admin-init.php +++ b/wp/wp-content/plugins/wordpress-seo/admin/class-admin-init.php @@ -44,55 +44,30 @@ class WPSEO_Admin_Init { add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_dismissible' ) ); add_action( 'admin_init', array( $this, 'after_update_notice' ), 15 ); add_action( 'admin_init', array( $this, 'tagline_notice' ), 15 ); + add_action( 'admin_init', array( $this, 'blog_public_notice' ), 15 ); + add_action( 'admin_init', array( $this, 'permalink_notice' ), 15 ); + add_action( 'admin_init', array( $this, 'page_comments_notice' ), 15 ); add_action( 'admin_init', array( $this, 'ga_compatibility_notice' ), 15 ); + add_action( 'admin_init', array( $this, 'yoast_plugin_compatibility_notification' ), 15 ); add_action( 'admin_init', array( $this, 'recalculate_notice' ), 15 ); add_action( 'admin_init', array( $this, 'ignore_tour' ) ); add_action( 'admin_init', array( $this, 'load_tour' ) ); add_action( 'admin_init', array( $this->asset_manager, 'register_assets' ) ); add_action( 'admin_init', array( $this, 'show_hook_deprecation_warnings' ) ); + add_action( 'admin_init', array( 'WPSEO_Plugin_Conflict', 'hook_check_for_plugin_conflicts' ) ); $this->load_meta_boxes(); $this->load_taxonomy_class(); $this->load_admin_page_class(); $this->load_admin_user_class(); $this->load_xml_sitemaps_admin(); - - $this->sync_about_version_from_cookie(); } /** - * Get about version seen from cookie if set. - */ - protected function sync_about_version_from_cookie() { - - $user_id = get_current_user_id(); - $meta_seen_about_version = get_user_meta( $user_id, 'wpseo_seen_about_version', true ); - - $cookie_key = 'wpseo_seen_about_version_' . $user_id; - - $cookie_seen_about_version = isset( $_COOKIE[ $cookie_key ] ) ? $_COOKIE[ $cookie_key ] : ''; - - if ( ! empty( $cookie_seen_about_version ) ) { - - if ( version_compare( $cookie_seen_about_version, $meta_seen_about_version, '>' ) ) { - update_user_meta( $user_id, 'wpseo_seen_about_version', $cookie_seen_about_version ); - $meta_seen_about_version = $cookie_seen_about_version; - } - } - - if ( $cookie_seen_about_version !== $meta_seen_about_version ) { - setcookie( $cookie_key, $meta_seen_about_version, ( $_SERVER['REQUEST_TIME'] + YEAR_IN_SECONDS ) ); - } - } - - /** - * For WP versions older than 4.2, this includes styles and a script to make notices dismissible. + * Enqueue our styling for dismissible yoast notifications. */ public function enqueue_dismissible() { - if ( version_compare( $GLOBALS['wp_version'], '4.2', '<' ) ) { - $this->asset_manager->enqueue_script( 'dismissable' ); - $this->asset_manager->enqueue_style( 'dismissable' ); - } + $this->asset_manager->enqueue_style( 'dismissible' ); } /** @@ -100,32 +75,39 @@ class WPSEO_Admin_Init { */ public function after_update_notice() { - $can_access = is_multisite() ? WPSEO_Utils::grant_access() : current_user_can( 'manage_options' ); + $notification = $this->get_update_notification(); + $notification_center = Yoast_Notification_Center::get(); - if ( $can_access && $this->has_ignored_tour() && ! $this->seen_about() ) { - - if ( filter_input( INPUT_GET, 'intro' ) === '1' || $this->dismiss_notice( 'wpseo-dismiss-about' ) ) { - update_user_meta( get_current_user_id(), 'wpseo_seen_about_version', WPSEO_VERSION ); - return; - } - - /* translators: %1$s expands to Yoast SEO, $2%s to the version number, %3$s and %4$s to anchor tags with link to intro page */ - $info_message = sprintf( - __( '%1$s has been updated to version %2$s. %3$sClick here%4$s to find out what\'s new!', 'wordpress-seo' ), - 'Yoast SEO', - WPSEO_VERSION, - '', - '' - ); - - $notification_options = array( - 'type' => 'updated', - 'id' => 'wpseo-dismiss-about', - 'nonce' => wp_create_nonce( 'wpseo-dismiss-about' ), - ); - - Yoast_Notification_Center::get()->add_notification( new Yoast_Notification( $info_message, $notification_options ) ); + if ( $this->has_ignored_tour() && ! $this->seen_about() ) { + $notification_center->add_notification( $notification ); } + else { + $notification_center->remove_notification( $notification ); + } + } + + /** + * Build the update notification + * + * @return Yoast_Notification + */ + private function get_update_notification() { + /* translators: %1$s expands to Yoast SEO, $2%s to the version number, %3$s and %4$s to anchor tags with link to intro page */ + $info_message = sprintf( + __( '%1$s has been updated to version %2$s. %3$sClick here%4$s to find out what\'s new!', 'wordpress-seo' ), + 'Yoast SEO', + WPSEO_VERSION, + '', + '' + ); + + $notification_options = array( + 'type' => Yoast_Notification::UPDATED, + 'id' => 'wpseo-dismiss-about', + 'capabilities' => 'manage_options', + ); + + return new Yoast_Notification( $info_message, $notification_options ); } /** @@ -145,35 +127,95 @@ class WPSEO_Admin_Init { */ public function tagline_notice() { - // Just a return, because we want to temporary disable this notice (#3998). - return; + $current_url = ( is_ssl() ? 'https://' : 'http://' ); + $current_url .= sanitize_text_field( $_SERVER['SERVER_NAME'] ) . sanitize_text_field( $_SERVER['REQUEST_URI'] ); + $customize_url = add_query_arg( array( + 'url' => urlencode( $current_url ), + ), wp_customize_url() ); - if ( current_user_can( 'manage_options' ) && $this->has_default_tagline() && ! $this->seen_tagline_notice() ) { + $info_message = sprintf( + __( 'You still have the default WordPress tagline, even an empty one is probably better. %1$sYou can fix this in the customizer%2$s.', 'wordpress-seo' ), + '', + '' + ); - // Only add the notice on GET requests, not in the customizer, and not in "action" type submits to prevent faulty return url. - if ( 'GET' !== filter_input( INPUT_SERVER, 'REQUEST_METHOD' ) || is_customize_preview() || null !== filter_input( INPUT_GET, 'action' ) ) { - return; - } + $notification_options = array( + 'type' => Yoast_Notification::ERROR, + 'id' => 'wpseo-dismiss-tagline-notice', + 'capabilities' => 'manage_options', + ); - $current_url = ( is_ssl() ? 'https://' : 'http://' ); - $current_url .= sanitize_text_field( $_SERVER['SERVER_NAME'] ) . sanitize_text_field( $_SERVER['REQUEST_URI'] ); - $customize_url = add_query_arg( array( - 'url' => urlencode( $current_url ), - ), wp_customize_url() ); + $tagline_notification = new Yoast_Notification( $info_message, $notification_options ); - $info_message = sprintf( - __( 'You still have the default WordPress tagline, even an empty one is probably better. %1$sYou can fix this in the customizer%2$s.', 'wordpress-seo' ), - '', - '' - ); + $notification_center = Yoast_Notification_Center::get(); + if ( $this->has_default_tagline() ) { + $notification_center->add_notification( $tagline_notification ); + } + else { + $notification_center->remove_notification( $tagline_notification ); + } + } - $notification_options = array( - 'type' => 'error', - 'id' => 'wpseo-dismiss-tagline-notice', - 'nonce' => wp_create_nonce( 'wpseo-dismiss-tagline-notice' ), - ); + /** + * Add an alert if the blog is not publicly visible + */ + public function blog_public_notice() { - Yoast_Notification_Center::get()->add_notification( new Yoast_Notification( $info_message, $notification_options ) ); + $info_message = '' . __( 'Huge SEO Issue: You\'re blocking access to robots.', 'wordpress-seo' ) . ' '; + $info_message .= sprintf( + /* translators: %1$s resolves to the opening tag of the link to the reading settings, %1$s resolves to the closing tag for the link */ + __( 'You must %1$sgo to your Reading Settings%2$s and uncheck the box for Search Engine Visibility.', 'wordpress-seo' ), + '', + '' + ); + + $notification_options = array( + 'type' => Yoast_Notification::ERROR, + 'id' => 'wpseo-dismiss-blog-public-notice', + 'priority' => 1.0, + 'capabilities' => 'manage_options', + ); + + $notification = new Yoast_Notification( $info_message, $notification_options ); + + $notification_center = Yoast_Notification_Center::get(); + if ( ! $this->is_blog_public() ) { + $notification_center->add_notification( $notification ); + } + else { + $notification_center->remove_notification( $notification ); + } + } + + /** + * Display notice to disable comment pagination + */ + public function page_comments_notice() { + + $info_message = __( 'Paging comments is enabled, this is not needed in 999 out of 1000 cases, we recommend to disable it.', 'wordpress-seo' ); + $info_message .= '
'; + + /* translators: %1$s resolves to the opening tag of the link to the comment setting page, %2$s resolves to the closing tag of the link */ + $info_message .= sprintf( + __( 'Simply uncheck the box before "Break comments into pages..." on the %1$sComment settings page%2$s.', 'wordpress-seo' ), + '', + '' + ); + + $notification_options = array( + 'type' => Yoast_Notification::WARNING, + 'id' => 'wpseo-dismiss-page_comments-notice', + 'capabilities' => 'manage_options', + ); + + $tagline_notification = new Yoast_Notification( $info_message, $notification_options ); + + $notification_center = Yoast_Notification_Center::get(); + if ( $this->has_page_comments() ) { + $notification_center->add_notification( $tagline_notification ); + } + else { + $notification_center->remove_notification( $tagline_notification ); } } @@ -183,21 +225,50 @@ class WPSEO_Admin_Init { * @return bool */ public function has_default_tagline() { - return __( 'Just another WordPress site' ) === get_bloginfo( 'description' ); + $blog_description = get_bloginfo( 'description' ); + $default_blog_description = 'Just another WordPress site'; + return __( $default_blog_description ) === $blog_description || $default_blog_description === $blog_description; } /** - * Returns whether or not the user has seen the tagline notice + * Show alert when the permalink doesn't contain %postname% + */ + public function permalink_notice() { + + $info_message = __( 'You do not have your postname in the URL of your posts and pages, it is highly recommended that you do. Consider setting your permalink structure to /%postname%/.', 'wordpress-seo' ); + $info_message .= '
'; + $info_message .= sprintf( + /* translators: %1$s resolves to the starting tag of the link to the permalink settings page, %2$s resolves to the closing tag of the link */ + __( 'You can fix this on the %1$sPermalink settings page%2$s.', 'wordpress-seo' ), + '', + '' + ); + + $notification_options = array( + 'type' => Yoast_Notification::WARNING, + 'id' => 'wpseo-dismiss-permalink-notice', + 'capabilities' => 'manage_options', + 'priority' => 0.8, + ); + + $notification = new Yoast_Notification( $info_message, $notification_options ); + + $notification_center = Yoast_Notification_Center::get(); + if ( ! $this->has_postname_in_permalink() ) { + $notification_center->add_notification( $notification ); + } + else { + $notification_center->remove_notification( $notification ); + } + } + + /** + * Are page comments enabled * * @return bool */ - public function seen_tagline_notice() { - // Check if the current request contain action to dismiss the notice. - if ( $this->dismiss_notice( 'wpseo-dismiss-tagline-notice' ) ) { - update_user_meta( get_current_user_id(), 'wpseo_seen_tagline_notice', 'seen' ); - } - - return 'seen' === get_user_meta( get_current_user_id(), 'wpseo_seen_tagline_notice', true ); + public function has_page_comments() { + return '1' === get_option( 'page_comments' ); } /** @@ -205,29 +276,95 @@ class WPSEO_Admin_Init { * on the google search console page. */ public function ga_compatibility_notice() { + + $notification = $this->get_compatibility_notification(); + $notification_center = Yoast_Notification_Center::get(); + if ( defined( 'GAWP_VERSION' ) && '5.4.3' === GAWP_VERSION ) { - - $info_message = sprintf( - /* translators: %1$s expands to Yoast SEO, %2$s expands to 5.4.3, %3$s expands to Google Analytics by Yoast */ - __( '%1$s detected you are using version %2$s of %3$s, please update to the latest version to prevent compatibility issues.', 'wordpress-seo' ), - 'Yoast SEO', - '5.4.3', - 'Google Analytics by Yoast' - ); - - $notification_options = array( - 'type' => 'error', - ); - - Yoast_Notification_Center::get()->add_notification( new Yoast_Notification( $info_message, $notification_options ) ); + $notification_center->add_notification( $notification ); } + else { + $notification_center->remove_notification( $notification ); + } + } + + /** + * Build compatibility problem notification + * + * @return Yoast_Notification + */ + private function get_compatibility_notification() { + $info_message = sprintf( + /* translators: %1$s expands to Yoast SEO, %2$s expands to 5.4.3, %3$s expands to Google Analytics by Yoast */ + __( '%1$s detected you are using version %2$s of %3$s, please update to the latest version to prevent compatibility issues.', 'wordpress-seo' ), + 'Yoast SEO', + '5.4.3', + 'Google Analytics by Yoast' + ); + + return new Yoast_Notification( + $info_message, + array( + 'id' => 'gawp-compatibility-notice', + 'type' => Yoast_Notification::ERROR, + ) + ); + } + + /** + * Add an alert if outdated versions of Yoast SEO plugins are running. + */ + public function yoast_plugin_compatibility_notification() { + $compatibility_checker = new WPSEO_Plugin_Compatibility( WPSEO_VERSION ); + $plugins = $compatibility_checker->get_installed_plugins_compatibility(); + + $notification_center = Yoast_Notification_Center::get(); + + foreach ( $plugins as $name => $plugin ) { + $type = ( $plugin['active'] ) ? Yoast_Notification::ERROR : Yoast_Notification::WARNING; + $notification = $this->get_yoast_seo_compatibility_notification( $name, $plugin, $type ); + + if ( $plugin['compatible'] === false ) { + $notification_center->add_notification( $notification ); + } + else { + $notification_center->remove_notification( $notification ); + } + } + } + + /** + * Build Yoast SEO compatibility problem notification + * + * @param string $name The plugin name to use for the unique ID. + * @param array $plugin The plugin to retrieve the data from. + * @param string $level The severity level to use for the notification. + * + * @return Yoast_Notification + */ + private function get_yoast_seo_compatibility_notification( $name, $plugin, $level = Yoast_Notification::WARNING ) { + $info_message = sprintf( + /* translators: %1$s expands to Yoast SEO, %2$s expands to the plugin version, %3$s expands to the plugin name */ + __( '%1$s detected you are using version %2$s of %3$s, please update to the latest version to prevent compatibility issues.', 'wordpress-seo' ), + 'Yoast SEO', + $plugin['version'], + $plugin['title'] + ); + + return new Yoast_Notification( + $info_message, + array( + 'id' => 'wpseo-outdated-yoast-seo-plugin-' . $name, + 'type' => $level, + ) + ); } /** * Shows the notice for recalculating the post. the Notice will only be shown if the user hasn't dismissed it before. */ public function recalculate_notice() { - // Just a return, because we want to temporary disable this notice (#3998). + // Just a return, because we want to temporary disable this notice (#3998 and #4532). return; if ( filter_input( INPUT_GET, 'recalculate' ) === '1' ) { @@ -334,7 +471,11 @@ class WPSEO_Admin_Init { if ( $this->on_wpseo_admin_page() ) { // For backwards compatabilty, this still needs a global, for now... $GLOBALS['wpseo_admin_pages'] = new WPSEO_Admin_Pages; - $this->register_i18n_promo_class(); + + // Only register the yoast i18n when the page is a Yoast SEO page. + if ( WPSEO_Utils::is_yoast_seo_free_page( filter_input( INPUT_GET, 'page' ) ) ) { + $this->register_i18n_promo_class(); + } } } @@ -349,7 +490,7 @@ class WPSEO_Admin_Init { 'textdomain' => 'wordpress-seo', 'project_slug' => 'wordpress-seo', 'plugin_name' => 'Yoast SEO', - 'hook' => 'wpseo_admin_footer', + 'hook' => 'wpseo_admin_promo_footer', 'glotpress_url' => 'http://translate.yoast.com/gp/', 'glotpress_name' => 'Yoast Translate', 'glotpress_logo' => 'https://translate.yoast.com/gp-templates/images/Yoast_Translate.svg', @@ -401,6 +542,15 @@ class WPSEO_Admin_Init { } } + /** + * Check if the site is set to be publicly visible + * + * @return bool + */ + private function is_blog_public() { + return '1' === get_option( 'blog_public' ); + } + /** * Shows deprecation warnings to the user if a plugin has registered a filter we have deprecated. */ @@ -446,4 +596,24 @@ class WPSEO_Admin_Init { private function dismiss_notice( $notice_name ) { return filter_input( INPUT_GET, $notice_name ) === '1' && wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), $notice_name ); } + + /** + * Returns whether or not the user has seen the tagline notice + * + * @deprecated 3.3 + * + * @return bool + */ + public function seen_tagline_notice() { + return false; + } + + /** + * Check if the permalink uses %postname% + * + * @return bool + */ + private function has_postname_in_permalink() { + return ( false !== strpos( get_option( 'permalink_structure' ), '%postname%' ) ); + } } diff --git a/wp/wp-content/plugins/wordpress-seo/admin/class-admin-user-profile.php b/wp/wp-content/plugins/wordpress-seo/admin/class-admin-user-profile.php index 861bf67a..50be97fa 100644 --- a/wp/wp-content/plugins/wordpress-seo/admin/class-admin-user-profile.php +++ b/wp/wp-content/plugins/wordpress-seo/admin/class-admin-user-profile.php @@ -70,6 +70,7 @@ class WPSEO_Admin_User_Profile { update_user_meta( $user_id, 'wpseo_metadesc', $this->filter_input_post( 'wpseo_author_metadesc' ) ); update_user_meta( $user_id, 'wpseo_metakey', $this->filter_input_post( 'wpseo_author_metakey' ) ); update_user_meta( $user_id, 'wpseo_excludeauthorsitemap', $this->filter_input_post( 'wpseo_author_exclude' ) ); + update_user_meta( $user_id, 'wpseo_content_analysis_disable', $this->filter_input_post( 'wpseo_content_analysis_disable' ) ); } /** diff --git a/wp/wp-content/plugins/wordpress-seo/admin/class-admin.php b/wp/wp-content/plugins/wordpress-seo/admin/class-admin.php index d1ebe722..143092f0 100644 --- a/wp/wp-content/plugins/wordpress-seo/admin/class-admin.php +++ b/wp/wp-content/plugins/wordpress-seo/admin/class-admin.php @@ -8,6 +8,9 @@ */ class WPSEO_Admin { + /** The page identifier used in WordPress to register the admin page !DO NOT CHANGE THIS! */ + const PAGE_IDENTIFIER = 'wpseo_dashboard'; + /** * @var array */ @@ -59,16 +62,7 @@ class WPSEO_Admin { add_filter( 'plugin_action_links_' . WPSEO_BASENAME, array( $this, 'add_action_link' ), 10, 2 ); add_action( 'admin_enqueue_scripts', array( $this, 'config_page_scripts' ) ); - - if ( '0' === get_option( 'blog_public' ) ) { - add_action( 'admin_footer', array( $this, 'blog_public_warning' ) ); - } - - if ( ( ( isset( $this->options['theme_has_description'] ) && $this->options['theme_has_description'] === true ) || - $this->options['theme_description_found'] !== '' ) && $this->options['ignore_meta_description_warning'] !== true - ) { - add_action( 'admin_footer', array( $this, 'meta_description_warning' ) ); - } + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_global_style' ) ); if ( $this->options['cleanslugs'] === true ) { add_filter( 'name_save_pre', array( $this, 'remove_stopwords_from_slug' ), 0 ); @@ -85,6 +79,10 @@ class WPSEO_Admin { add_action( 'admin_init', array( $this, 'import_plugin_hooks' ) ); WPSEO_Sitemaps_Cache::register_clear_on_option_update( 'wpseo' ); + + if ( WPSEO_Utils::is_yoast_seo_page() ) { + add_action( 'admin_head', array( $this, 'enqueue_assets' ) ); + } } /** @@ -126,12 +124,17 @@ class WPSEO_Admin { } // Base 64 encoded SVG image. - $icon_svg = $this->get_menu_svg(); + $icon_svg = WPSEO_Utils::get_icon_svg(); $manage_options_cap = $this->get_manage_options_cap(); + $notification_center = Yoast_Notification_Center::get(); + $notification_count = $notification_center->get_notification_count(); + // Add main page. - $admin_page = add_menu_page( 'Yoast SEO: ' . __( 'General Settings', 'wordpress-seo' ), __( 'SEO', 'wordpress-seo' ), $manage_options_cap, 'wpseo_dashboard', array( + $counter = sprintf( '%1$d', $notification_count ); + + $admin_page = add_menu_page( 'Yoast SEO: ' . __( 'Dashboard', 'wordpress-seo' ), __( 'SEO', 'wordpress-seo' ) . ' ' . $counter, $manage_options_cap, self::PAGE_IDENTIFIER, array( $this, 'load_page', ), $icon_svg, '99.31337' ); @@ -139,7 +142,16 @@ class WPSEO_Admin { // Sub menu pages. $submenu_pages = array( array( - 'wpseo_dashboard', + self::PAGE_IDENTIFIER, + '', + __( 'General', 'wordpress-seo' ), + $manage_options_cap, + self::PAGE_IDENTIFIER, + array( $this, 'load_page' ), + null, + ), + array( + self::PAGE_IDENTIFIER, '', __( 'Titles & Metas', 'wordpress-seo' ), $manage_options_cap, @@ -147,7 +159,7 @@ class WPSEO_Admin { array( $this, 'load_page' ), ), array( - 'wpseo_dashboard', + self::PAGE_IDENTIFIER, '', __( 'Social', 'wordpress-seo' ), $manage_options_cap, @@ -156,7 +168,7 @@ class WPSEO_Admin { null, ), array( - 'wpseo_dashboard', + self::PAGE_IDENTIFIER, '', __( 'XML Sitemaps', 'wordpress-seo' ), $manage_options_cap, @@ -165,7 +177,7 @@ class WPSEO_Admin { null, ), array( - 'wpseo_dashboard', + self::PAGE_IDENTIFIER, '', __( 'Advanced', 'wordpress-seo' ), $manage_options_cap, @@ -174,7 +186,7 @@ class WPSEO_Admin { null, ), array( - 'wpseo_dashboard', + self::PAGE_IDENTIFIER, '', __( 'Tools', 'wordpress-seo' ), $manage_options_cap, @@ -183,7 +195,7 @@ class WPSEO_Admin { null, ), array( - 'wpseo_dashboard', + self::PAGE_IDENTIFIER, '', __( 'Search Console', 'wordpress-seo' ), $manage_options_cap, @@ -192,7 +204,7 @@ class WPSEO_Admin { array( array( $this->admin_features['google_search_console'], 'set_help' ) ), ), array( - 'wpseo_dashboard', + self::PAGE_IDENTIFIER, '', '' . __( 'Extensions', 'wordpress-seo' ) . '', $manage_options_cap, @@ -200,6 +212,7 @@ class WPSEO_Admin { array( $this, 'load_page' ), null, ), + ); // Allow submenu pages manipulation. @@ -222,11 +235,19 @@ class WPSEO_Admin { } global $submenu; - if ( isset( $submenu['wpseo_dashboard'] ) && current_user_can( $manage_options_cap ) ) { - $submenu['wpseo_dashboard'][0][0] = __( 'General', 'wordpress-seo' ); + if ( isset( $submenu[ self::PAGE_IDENTIFIER ] ) && current_user_can( $manage_options_cap ) ) { + $submenu[ self::PAGE_IDENTIFIER ][0][0] = __( 'Dashboard', 'wordpress-seo' ); } } + /** + * Register assets needed on admin pages + */ + public function enqueue_assets() { + $asset_manager = new WPSEO_Admin_Asset_Manager(); + $asset_manager->enqueue_style( 'help-center' ); + } + /** * Returns the manage_options cap * @@ -287,21 +308,22 @@ class WPSEO_Admin { function register_network_settings_page() { if ( WPSEO_Utils::grant_access() ) { // Base 64 encoded SVG image. - $icon_svg = $this->get_menu_svg(); - add_menu_page( 'Yoast SEO: ' . __( 'MultiSite Settings', 'wordpress-seo' ), __( 'SEO', 'wordpress-seo' ), 'delete_users', 'wpseo_dashboard', array( + $icon_svg = WPSEO_Utils::get_icon_svg(); + + add_menu_page( 'Yoast SEO: ' . __( 'MultiSite Settings', 'wordpress-seo' ), __( 'SEO', 'wordpress-seo' ), 'delete_users', self::PAGE_IDENTIFIER, array( $this, 'network_config_page', ), $icon_svg ); if ( WPSEO_Utils::allow_system_file_edit() === true ) { - add_submenu_page( 'wpseo_dashboard', 'Yoast SEO: ' . __( 'Edit Files', 'wordpress-seo' ), __( 'Edit Files', 'wordpress-seo' ), 'delete_users', 'wpseo_files', array( + add_submenu_page( self::PAGE_IDENTIFIER, 'Yoast SEO: ' . __( 'Edit Files', 'wordpress-seo' ), __( 'Edit Files', 'wordpress-seo' ), 'delete_users', 'wpseo_files', array( $this, 'load_page', ) ); } // Add Extension submenu page. - add_submenu_page( 'wpseo_dashboard', 'Yoast SEO: ' . __( 'Extensions', 'wordpress-seo' ), __( 'Extensions', 'wordpress-seo' ), 'delete_users', 'wpseo_licenses', array( + add_submenu_page( self::PAGE_IDENTIFIER, 'Yoast SEO: ' . __( 'Extensions', 'wordpress-seo' ), __( 'Extensions', 'wordpress-seo' ), 'delete_users', 'wpseo_licenses', array( $this, 'load_page', ) ); @@ -348,7 +370,7 @@ class WPSEO_Admin { require_once( WPSEO_PATH . 'admin/pages/tutorial-videos.php' ); break; - case 'wpseo_dashboard': + case self::PAGE_IDENTIFIER: default: require_once( WPSEO_PATH . 'admin/pages/dashboard.php' ); break; @@ -395,71 +417,6 @@ class WPSEO_Admin { return $status; } - /** - * Display an error message when the blog is set to private. - */ - function blog_public_warning() { - if ( ( function_exists( 'is_network_admin' ) && is_network_admin() ) || WPSEO_Utils::grant_access() !== true ) { - return; - } - - if ( ! current_user_can( 'manage_options' ) ) { - return; - } - - if ( $this->options['ignore_blog_public_warning'] === true ) { - return; - } - printf( ' -
-

- %1$s - %2$s - %4$s -

-
', - __( 'Huge SEO Issue: You\'re blocking access to robots.', 'wordpress-seo' ), - sprintf( __( 'You must %sgo to your Reading Settings%s and uncheck the box for Search Engine Visibility.', 'wordpress-seo' ), sprintf( '', esc_url( admin_url( 'options-reading.php' ) ) ), '' ), - esc_js( wp_create_nonce( 'wpseo-ignore' ) ), - __( 'I know, don\'t bug me.', 'wordpress-seo' ) - ); - } - - /** - * Display an error message when the theme contains a meta description tag. - * - * @since 1.4.14 - */ - function meta_description_warning() { - if ( ( function_exists( 'is_network_admin' ) && is_network_admin() ) || WPSEO_Utils::grant_access() !== true ) { - return; - } - - // No need to double display it on the dashboard. - if ( 'wpseo_dashboard' === filter_input( INPUT_GET, 'page' ) ) { - return; - } - - if ( true === $this->options['ignore_meta_description_warning'] ) { - return; - } - - printf( ' -
-

- %1$s - %2$s - %4$s -

-
', - __( 'SEO Issue:', 'wordpress-seo' ), - /* translators: %1$s expands to Yoast SEO, %2$s to opening anchor and %3$s the anchor closing tag */ - sprintf( __( 'Your theme contains a meta description, which blocks %1$s from working properly. Please visit the %2$sSEO Dashboard%3$s to fix this.', 'wordpress-seo' ), 'Yoast SEO', sprintf( '', esc_url( admin_url( 'admin.php?page=wpseo_dashboard' ) ) ), '' ), - esc_js( wp_create_nonce( 'wpseo-ignore' ) ), - __( 'I know, don\'t bug me.', 'wordpress-seo' ) - ); - } - /** * Add a link to the settings page to the plugins list * @@ -472,7 +429,7 @@ class WPSEO_Admin { */ function add_action_link( $links, $file ) { if ( WPSEO_BASENAME === $file && WPSEO_Utils::grant_access() ) { - $settings_link = '' . __( 'Settings', 'wordpress-seo' ) . ''; + $settings_link = '' . __( 'Settings', 'wordpress-seo' ) . ''; array_unshift( $links, $settings_link ); } @@ -506,6 +463,14 @@ class WPSEO_Admin { } } + /** + * Enqueues the (tiny) global stylesheet needed for the plugin. + */ + public function enqueue_global_style() { + $asset_manager = new WPSEO_Admin_Asset_Manager(); + $asset_manager->enqueue_style( 'admin-global' ); + } + /** * Filter the $contactmethods array and add Facebook, Google+ and Twitter. * @@ -634,17 +599,6 @@ class WPSEO_Admin { } } - /** - * Returns a base64 URL for the svg for use in the menu - * - * @return string - */ - private function get_menu_svg() { - $icon_svg = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIGZpbGw9Im5vbmUiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIj48Zz48Zz48Zz48Zz48cGF0aCBzdHlsZT0iZmlsbDojMDAwIiBkPSJNMjAzLjYsMzk1YzYuOC0xNy40LDYuOC0zNi42LDAtNTRsLTc5LjQtMjA0aDcwLjlsNDcuNywxNDkuNGw3NC44LTIwNy42SDExNi40Yy00MS44LDAtNzYsMzQuMi03Niw3NlYzNTdjMCw0MS44LDM0LjIsNzYsNzYsNzZIMTczQzE4OSw0MjQuMSwxOTcuNiw0MTAuMywyMDMuNiwzOTV6Ii8+PC9nPjxnPjxwYXRoIHN0eWxlPSJmaWxsOiMwMDAiIGQ9Ik00NzEuNiwxNTQuOGMwLTQxLjgtMzQuMi03Ni03Ni03NmgtM0wyODUuNywzNjVjLTkuNiwyNi43LTE5LjQsNDkuMy0zMC4zLDY4aDIxNi4yVjE1NC44eiIvPjwvZz48L2c+PHBhdGggc3R5bGU9ImZpbGw6IzAwMCIgc3Ryb2tlLXdpZHRoPSIyLjk3NCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBkPSJNMzM4LDEuM2wtOTMuMywyNTkuMWwtNDIuMS0xMzEuOWgtODkuMWw4My44LDIxNS4yYzYsMTUuNSw2LDMyLjUsMCw0OGMtNy40LDE5LTE5LDM3LjMtNTMsNDEuOWwtNy4yLDF2NzZoOC4zYzgxLjcsMCwxMTguOS01Ny4yLDE0OS42LTE0Mi45TDQzMS42LDEuM0gzMzh6IE0yNzkuNCwzNjJjLTMyLjksOTItNjcuNiwxMjguNy0xMjUuNywxMzEuOHYtNDVjMzcuNS03LjUsNTEuMy0zMSw1OS4xLTUxLjFjNy41LTE5LjMsNy41LTQwLjcsMC02MGwtNzUtMTkyLjdoNTIuOGw1My4zLDE2Ni44bDEwNS45LTI5NGg1OC4xTDI3OS40LDM2MnoiLz48L2c+PC9nPjwvc3ZnPg=='; - - return $icon_svg; - } - /** * Localization for the dismiss urls. * @@ -737,4 +691,24 @@ class WPSEO_Admin { function options_init() { _deprecated_function( __METHOD__, 'WPSEO 1.5.0', 'WPSEO_Option::register_setting()' ); } + + /** + * Display an error message when the blog is set to private. + * + * @deprecated 3.3 + */ + function blog_public_warning() { + return; + } + + /** + * Display an error message when the theme contains a meta description tag. + * + * @since 1.4.14 + * + * @deprecated 3.3 + */ + function meta_description_warning() { + _deprecated_function( __FUNCTION__, 'WPSEO 3.3.0' ); + } } diff --git a/wp/wp-content/plugins/wordpress-seo/admin/class-asset.php b/wp/wp-content/plugins/wordpress-seo/admin/class-asset.php index fe37098c..e8714ac1 100644 --- a/wp/wp-content/plugins/wordpress-seo/admin/class-asset.php +++ b/wp/wp-content/plugins/wordpress-seo/admin/class-asset.php @@ -8,6 +8,9 @@ */ class WPSEO_Admin_Asset { + const TYPE_JS = 'js'; + const TYPE_CSS = 'css'; + const NAME = 'name'; const SRC = 'src'; const DEPS = 'deps'; @@ -16,7 +19,7 @@ class WPSEO_Admin_Asset { // Style specific. const MEDIA = 'media'; - // Script specififc. + // Script specific. const IN_FOOTER = 'in_footer'; /** @@ -76,13 +79,13 @@ class WPSEO_Admin_Asset { 'suffix' => WPSEO_CSSJS_SUFFIX, ), $args ); - $this->name = $args['name']; - $this->src = $args['src']; - $this->deps = $args['deps']; - $this->version = $args['version']; - $this->media = $args['media']; + $this->name = $args['name']; + $this->src = $args['src']; + $this->deps = $args['deps']; + $this->version = $args['version']; + $this->media = $args['media']; $this->in_footer = $args['in_footer']; - $this->suffix = $args['suffix']; + $this->suffix = $args['suffix']; } /** @@ -133,4 +136,69 @@ class WPSEO_Admin_Asset { public function get_suffix() { return $this->suffix; } + + /** + * Returns the full URL for this asset based on the path to the plugin file. + * + * @param string $type Type of asset. + * @param string $plugin_file Absolute path to the plugin file. + * + * @return string The full URL to the asset. + */ + public function get_url( $type, $plugin_file ) { + + $relative_path = $this->get_relative_path( $type ); + if ( empty( $relative_path ) ) { + return ''; + } + + if ( ! $this->get_suffix() ) { + + $plugin_path = plugin_dir_path( $plugin_file ); + if ( ! file_exists( $plugin_path . $relative_path ) ) { + + // Give a notice to the user in the console (only once). + WPSEO_Utils::javascript_console_notification( + 'Development Files', + sprintf( + /* translators: %1$s resolves to https://github.com/Yoast/wordpress-seo */ + __( 'You are trying to load non-minified files, these are only available in our development package. Check out %1$s to see all the source files.', 'wordpress-seo' ), + 'https://github.com/Yoast/wordpress-seo' + ), + true + ); + + // Just load the .min file. + $relative_path = $this->get_relative_path( $type, '.min' ); + } + } + + return plugins_url( $relative_path, $plugin_file ); + } + + /** + * Get the relative file for this asset + * + * @param string $type Type of this asset. + * @param null $force_suffix Force use suffix. + * + * @return string + */ + protected function get_relative_path( $type, $force_suffix = null ) { + $relative_path = ''; + + $suffix = ( is_null( $force_suffix ) ) ? $this->get_suffix() : $force_suffix; + + switch ( $type ) { + case self::TYPE_JS: + $relative_path = 'js/dist/' . $this->get_src() . $suffix . '.js'; + break; + + case self::TYPE_CSS: + $relative_path = 'css/' . $this->get_src() . $suffix . '.css'; + break; + } + + return $relative_path; + } } diff --git a/wp/wp-content/plugins/wordpress-seo/admin/class-bulk-editor-list-table.php b/wp/wp-content/plugins/wordpress-seo/admin/class-bulk-editor-list-table.php index efe2e4b3..9de95c8e 100644 --- a/wp/wp-content/plugins/wordpress-seo/admin/class-bulk-editor-list-table.php +++ b/wp/wp-content/plugins/wordpress-seo/admin/class-bulk-editor-list-table.php @@ -130,7 +130,12 @@ class WPSEO_Bulk_List_Table extends WP_List_Table { */ private function verify_nonce() { if ( $this->should_verify_nonce() && ! wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), 'bulk-editor-table' ) ) { - Yoast_Notification_Center::get()->add_notification( new Yoast_Notification( __( 'You are not allowed to access this page.', 'wordpress-seo' ), array( 'type' => 'error' ) ) ); + Yoast_Notification_Center::get()->add_notification( + new Yoast_Notification( + __( 'You are not allowed to access this page.', 'wordpress-seo' ), + array( 'type' => Yoast_Notification::ERROR ) + ) + ); Yoast_Notification_Center::get()->display_notifications(); die; } diff --git a/wp/wp-content/plugins/wordpress-seo/admin/class-config.php b/wp/wp-content/plugins/wordpress-seo/admin/class-config.php index e697a099..582cbfd9 100644 --- a/wp/wp-content/plugins/wordpress-seo/admin/class-config.php +++ b/wp/wp-content/plugins/wordpress-seo/admin/class-config.php @@ -38,7 +38,7 @@ class WPSEO_Admin_Pages { function init() { if ( filter_input( INPUT_GET, 'wpseo_reset_defaults' ) && wp_verify_nonce( filter_input( INPUT_GET, 'nonce' ), 'wpseo_reset_defaults' ) && current_user_can( 'manage_options' ) ) { WPSEO_Options::reset(); - wp_redirect( admin_url( 'admin.php?page=wpseo_dashboard' ) ); + wp_redirect( admin_url( 'admin.php?page=' . WPSEO_Admin::PAGE_IDENTIFIER ) ); } if ( WPSEO_Utils::grant_access() ) { @@ -59,6 +59,8 @@ class WPSEO_Admin_Pages { $this->asset_manager->enqueue_style( 'admin-css' ); + $this->asset_manager->enqueue_style( 'kb-search' ); + if ( is_rtl() ) { $this->asset_manager->enqueue_style( 'rtl' ); } @@ -76,27 +78,18 @@ class WPSEO_Admin_Pages { wp_enqueue_script( 'thickbox' ); $page = filter_input( INPUT_GET, 'page' ); - $tool = filter_input( INPUT_GET, 'tool' ); wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'admin-script', 'wpseoSelect2Locale', substr( get_locale(), 0, 2 ) ); - if ( in_array( $page, array( 'wpseo_social', 'wpseo_dashboard' ) ) ) { + if ( in_array( $page, array( 'wpseo_social', WPSEO_Admin::PAGE_IDENTIFIER ) ) ) { wp_enqueue_media(); $this->asset_manager->enqueue_script( 'admin-media' ); wp_localize_script( WPSEO_Admin_Asset_Manager::PREFIX . 'admin-media', 'wpseoMediaL10n', $this->localize_media_script() ); } - if ( 'wpseo_tools' === $page && empty( $tool ) ) { - $this->asset_manager->enqueue_script( 'yoast-seo' ); - } - - if ( 'wpseo_tools' === $page && 'bulk-editor' === $tool ) { - $this->asset_manager->enqueue_script( 'bulk-editor' ); - } - - if ( 'wpseo_tools' === $page && 'import-export' === $tool ) { - $this->asset_manager->enqueue_script( 'export' ); + if ( 'wpseo_tools' === $page ) { + $this->enqueue_tools_scripts(); } } @@ -123,9 +116,55 @@ class WPSEO_Admin_Pages { /* translators: %s: '%%term_title%%' variable used in titles and meta's template that's not compatible with the given template */ 'variable_warning' => sprintf( __( 'Warning: the variable %s cannot be used in this template.', 'wordpress-seo' ), '%s' ) . ' ' . __( 'See the help tab for more info.', 'wordpress-seo' ), 'locale' => get_locale(), + 'kb_no_results' => __( 'No results found.', 'wordpress-seo' ), + 'kb_heading' => __( 'Search the Yoast knowledge base', 'wordpress-seo' ), + 'kb_error_message' => __( 'Something went wrong. Please try again later.', 'wordpress-seo' ), + 'kb_loading_placeholder' => __( 'Loading...', 'wordpress-seo' ), + 'kb_search' => __( 'search', 'wordpress-seo' ), + 'kb_back' => __( 'Back', 'wordpress-seo' ), + 'kb_open' => __( 'Open', 'wordpress-seo' ), ); } + /** + * Enqueues and handles all the tool dependencies. + */ + private function enqueue_tools_scripts() { + $tool = filter_input( INPUT_GET, 'tool' ); + + if ( empty( $tool ) ) { + $this->asset_manager->enqueue_script( 'yoast-seo' ); + } + + if ( 'bulk-editor' === $tool ) { + $this->asset_manager->enqueue_script( 'bulk-editor' ); + } + + if ( 'import-export' === $tool && filter_input( INPUT_POST, WPSEO_Export::NONCE_NAME ) !== null ) { + $this->do_yoast_export(); + } + } + + /** + * Runs the yoast exporter class to possibly init the file download. + */ + private function do_yoast_export() { + check_admin_referer( WPSEO_Export::NONCE_ACTION, WPSEO_Export::NONCE_NAME ); + + if ( ! current_user_can( 'manage_options' ) ) { + return; + } + + $wpseo_post = filter_input( INPUT_POST, 'wpseo' ); + $include_taxonomy = ! empty( $wpseo_post['include_taxonomy'] ); + $export = new WPSEO_Export( $include_taxonomy ); + + if ( $export->has_error() ) { + add_action( 'admin_notices', array( $export, 'set_error_hook' ) ); + + } + } + /********************** DEPRECATED METHODS **********************/ /** @@ -142,9 +181,8 @@ class WPSEO_Admin_Pages { if ( $export->success ) { return $export->export_zip_url; } - else { - return false; - } + + return false; } /** diff --git a/wp/wp-content/plugins/wordpress-seo/admin/class-export.php b/wp/wp-content/plugins/wordpress-seo/admin/class-export.php index e71235ed..ef8dd7f0 100644 --- a/wp/wp-content/plugins/wordpress-seo/admin/class-export.php +++ b/wp/wp-content/plugins/wordpress-seo/admin/class-export.php @@ -10,6 +10,12 @@ */ class WPSEO_Export { + const ZIP_FILENAME = 'yoast-seo-settings-export.zip'; + const INI_FILENAME = 'settings.ini'; + + const NONCE_ACTION = 'wpseo_export'; + const NONCE_NAME = 'wpseo_export_nonce'; + /** * @var string */ @@ -51,57 +57,52 @@ class WPSEO_Export { public function __construct( $include_taxonomy = false ) { $this->include_taxonomy = $include_taxonomy; $this->dir = wp_upload_dir(); - $this->success = $this->export_settings(); + + $this->export_settings(); } /** - * Returns an array with status and output message. + * Returns true when the property error has a value. * - * @return array $results + * @return bool */ - public function get_results() { - $results = array(); - if ( $this->success ) { - $results['status'] = 'success'; - $results['msg'] = sprintf( __( 'Export created: %1$sdownload your export file here%2$s.', 'wordpress-seo' ), '', '' ); - } - else { - $results['status'] = 'failure'; - /* translators: %1$s expands to Yoast SEO */ - $results['msg'] = sprintf( __( 'Error creating %1$s export: ', 'wordpress-seo' ), 'Yoast SEO' ) . $this->error; - } + public function has_error() { + return ( $this->error !== '' ); + } - return $results; + /** + * Sets the error hook, to display the error to the user. + */ + public function set_error_hook() { + $class = 'notice notice-error'; + $message = sprintf( __( 'Error creating %1$s export: ', 'wordpress-seo' ), 'Yoast SEO' ) . $this->error; + + printf( '

%2$s

', $class, $message ); } /** * Exports the current site's WP SEO settings. - * - * @return boolean|string $return true when success, error when failed. */ private function export_settings() { $this->export_header(); foreach ( WPSEO_Options::get_option_names() as $opt_group ) { - $this->write_opt_group( $opt_group, $this->export ); + $this->write_opt_group( $opt_group ); } $this->taxonomy_metadata(); - if ( $this->write_file() ) { - if ( $this->zip_file() ) { - return true; - } - else { - $this->error = __( 'Could not zip settings-file.', 'wordpress-seo' ); + if ( ! $this->write_settings_file() ) { + $this->error = __( 'Could not write settings to file.', 'wordpress-seo' ); - return false; - } + return; } - $this->error = __( 'Could not write settings to file.', 'wordpress-seo' ); - return false; + if ( $this->zip_file() ) { + // Just exit, because there is a download being served. + exit; + } } /** @@ -134,6 +135,7 @@ class WPSEO_Export { * @param string $opt_group Option group name. */ private function write_opt_group( $opt_group ) { + $this->write_line( '[' . $opt_group . ']', true ); $options = get_option( $opt_group ); @@ -175,7 +177,7 @@ class WPSEO_Export { $taxonomy_meta = get_option( 'wpseo_taxonomy_meta' ); if ( is_array( $taxonomy_meta ) ) { $this->write_line( '[wpseo_taxonomy_meta]', true ); - $this->write_setting( 'wpseo_taxonomy_meta', urlencode( WPSEO_Utils::json_encode( $taxonomy_meta ) ) ); + $this->write_setting( 'wpseo_taxonomy_meta', urlencode( wp_json_encode( $taxonomy_meta ) ) ); } else { $this->write_line( '; ' . __( 'No taxonomy metadata found', 'wordpress-seo' ), true ); @@ -188,8 +190,8 @@ class WPSEO_Export { * * @return boolean unsigned */ - private function write_file() { - $handle = fopen( $this->dir['path'] . '/settings.ini', 'w' ); + private function write_settings_file() { + $handle = fopen( $this->dir['path'] . '/' . self::INI_FILENAME, 'w' ); if ( ! $handle ) { return false; } @@ -207,17 +209,66 @@ class WPSEO_Export { /** * Zips the settings ini file * - * @return boolean unsigned + * @return bool|null */ private function zip_file() { - chdir( $this->dir['path'] ); - $zip = new PclZip( './settings.zip' ); - if ( 0 === $zip->create( './settings.ini' ) ) { + $is_zip_created = $this->create_zip(); + + // The settings.ini isn't needed, because it's in the zipfile. + $this->remove_settings_ini(); + + if ( ! $is_zip_created ) { + $this->error = __( 'Could not zip settings-file.', 'wordpress-seo' ); + return false; } - $this->export_zip_url = $this->dir['url'] . '/settings.zip'; + $this->serve_settings_export(); + $this->remove_zip(); return true; } + + /** + * Creates the zipfile and returns true if it created successful. + * + * @return bool + */ + private function create_zip() { + chdir( $this->dir['path'] ); + $zip = new PclZip( './' . self::ZIP_FILENAME ); + if ( 0 === $zip->create( './' . self::INI_FILENAME ) ) { + return false; + } + + return file_exists( self::ZIP_FILENAME ); + } + + /** + * Downloads the zip file. + */ + private function serve_settings_export() { + // Clean any content that has been already output. For example by other plugins or faulty PHP files. + ob_clean(); + header( 'Content-Type: application/octet-stream; charset=utf-8' ); + header( 'Content-Transfer-Encoding: Binary' ); + header( 'Content-Disposition: attachment; filename=' . self::ZIP_FILENAME ); + header( 'Content-Length: ' . filesize( self::ZIP_FILENAME ) ); + + readfile( self::ZIP_FILENAME ); + } + + /** + * Removes the settings ini file. + */ + private function remove_settings_ini() { + unlink( './' . self::INI_FILENAME ); + } + + /** + * Removes the files because they are already downloaded. + */ + private function remove_zip() { + unlink( './' . self::ZIP_FILENAME ); + } } diff --git a/wp/wp-content/plugins/wordpress-seo/admin/class-help-center-item.php b/wp/wp-content/plugins/wordpress-seo/admin/class-help-center-item.php index 2ab34e6e..cc3449c5 100644 --- a/wp/wp-content/plugins/wordpress-seo/admin/class-help-center-item.php +++ b/wp/wp-content/plugins/wordpress-seo/admin/class-help-center-item.php @@ -8,13 +8,16 @@ */ class WPSEO_Help_Center_Item { - /** @var string Identifier for this tab */ + /** @var string Identifier for this tab. */ private $identifier; - /** @var string Label to display */ + /** @var string Label to display. */ private $label; - /** @var array Optional arguments */ + /** @var string The dashicon classname to display in front of the label. */ + private $dashicon; + + /** @var array Optional arguments. */ private $args = array(); /** @@ -23,16 +26,17 @@ class WPSEO_Help_Center_Item { * @param string $identifier Unique identifier for this tab. * @param string $label Label to display. * @param array $args Optional. Settings for this tab. + * @param string $dashicon Optional. The classname of the dahsicon to put in front of the label. */ - public function __construct( $identifier, $label, $args = array() ) { + public function __construct( $identifier, $label, $args = array(), $dashicon = '' ) { $this->identifier = $identifier; $this->label = $label; - - $this->args = $args; + $this->dashicon = $dashicon; + $this->args = $args; } /** - * Get the label + * Get the label. * * @return string */ @@ -41,7 +45,7 @@ class WPSEO_Help_Center_Item { } /** - * Get the identifier + * Get the identifier. * * @return string */ @@ -50,7 +54,16 @@ class WPSEO_Help_Center_Item { } /** - * Get the content of this tab + * Get the dashicon. + * + * @return string + */ + public function get_dashicon() { + return $this->dashicon; + } + + /** + * Get the content of this tab. * * @return mixed|string */ diff --git a/wp/wp-content/plugins/wordpress-seo/admin/class-help-center.php b/wp/wp-content/plugins/wordpress-seo/admin/class-help-center.php new file mode 100644 index 00000000..13fd6946 --- /dev/null +++ b/wp/wp-content/plugins/wordpress-seo/admin/class-help-center.php @@ -0,0 +1,183 @@ +group_name = $group_name; + $this->tab = $tab; + + $this->add_video_tutorial_item(); + $this->add_kb_search_item(); + $this->add_contact_support_item(); + } + + /** + * Add the knowledge base search help center item to the help center. + */ + private function add_kb_search_item() { + $kb_help_center_item = new WPSEO_Help_Center_Item( + 'knowledge-base', + __( 'Knowledge base', 'wordpress-seo' ), + array( + 'content' => '', + 'view_arguments' => array( 'identifier' => $this->tab->get_name() ), + ), + 'dashicons-search' + ); + array_push( $this->help_center_items, $kb_help_center_item ); + } + + /** + * Add the contact support help center item to the help center. + */ + private function add_contact_support_item() { + $popup_title = sprintf( __( 'Email support is a %s feature', 'wordpress-seo' ), 'Yoast SEO Premium' ); + /* translators: %1$s: expands to 'Yoast SEO Premium', %2$s: links to Yoast SEO Premium plugin page. */ + $popup_content = sprintf( __( 'To be able to contact our support team, you need %1$s. You can buy the plugin, including one year of support, updates and upgrades, on %2$s.', 'wordpress-seo' ), + 'Yoast SEO Premium', + 'yoast.com' ); + + $premium_popup = new WPSEO_Premium_Popup( 'contact-support', 'h2', $popup_title, $popup_content ); + $contact_support_help_center_item = new WPSEO_Help_Center_Item( + 'contact-support', + __( 'Email support', 'wordpress-seo' ), + array( 'content' => $premium_popup->get_premium_message( false ) ), + 'dashicons-email-alt' + ); + + array_push( $this->help_center_items, $contact_support_help_center_item ); + } + + /** + * Add the video tutorial help center item to the help center. + */ + private function add_video_tutorial_item() { + array_push( $this->help_center_items, $this->get_video_help_center_item() ); + } + + /** + * @return mixed (WPSEO_Help_Center_Item | null) Returns a help center item containing a video. + */ + private function get_video_help_center_item() { + $url = $this->tab->get_video_url(); + if ( empty( $url ) ) { + return null; + } + + return new WPSEO_Help_Center_Item( + 'video', + __( 'Video tutorial', 'wordpress-seo' ), + array( + 'view' => 'partial-help-center-video', + 'view_arguments' => array( + 'tab_video_url' => $url, + ), + ), + 'dashicons-video-alt3' + ); + } + + /** + * Outputs the help center. + */ + public function output_help_center() { + $help_center_items = apply_filters( 'wpseo_help_center_items', $this->help_center_items ); + $help_center_items = array_filter( $help_center_items, array( $this, 'is_a_help_center_item' ) ); + if ( empty( $help_center_items ) ) { + return; + } + + $id = sprintf( 'tab-help-center-%s-%s', $this->group_name, $this->tab->get_name() ); + ?> +
+ +
+
+
    + get_identifier(); + $dashicon = $help_center_item->get_dashicon(); + if ( ! empty( $dashicon ) ) { + $dashicon = 'dashicons-before ' . $dashicon; + } + $link_id = "tab-link-{$this->group_name}_{$this->tab->get_name()}__{$id}"; + $panel_id = "tab-panel-{$this->group_name}_{$this->tab->get_name()}__{$id}"; + ?> + + + +
+
+
+ get_identifier(); + + $panel_id = "tab-panel-{$this->group_name}_{$this->tab->get_name()}__{$id}"; + ?> +
+ get_content(); ?> +
+ +
+
+
+ page_title( $post_id ), get_post( $post_id, ARRAY_A ) ) ) ); break; case 'wpseo-metadesc' : - echo esc_html( apply_filters( 'wpseo_metadesc', wpseo_replace_vars( WPSEO_Meta::get_value( 'metadesc', $post_id ), get_post( $post_id, ARRAY_A ) ) ) ); + $metadesc_val = apply_filters( 'wpseo_metadesc', wpseo_replace_vars( WPSEO_Meta::get_value( 'metadesc', $post_id ), get_post( $post_id, ARRAY_A ) ) ); + $metadesc = ( '' === $metadesc_val ) ? '' . __( 'Meta description not set.', 'wordpress-seo' ) . '' : esc_html( $metadesc_val ); + echo $metadesc; break; case 'wpseo-focuskw' : - $focuskw = WPSEO_Meta::get_value( 'focuskw', $post_id ); - echo esc_html( $focuskw ); + $focuskw_val = WPSEO_Meta::get_value( 'focuskw', $post_id ); + $focuskw = ( '' === $focuskw_val ) ? '' . __( 'Focus keyword not set.', 'wordpress-seo' ) . '' : esc_html( $focuskw_val ); + echo $focuskw; break; } } @@ -87,7 +90,6 @@ class WPSEO_Meta_Columns { return $columns; } - $columns['wpseo-score'] = 'wpseo-score'; $columns['wpseo-metadesc'] = 'wpseo-metadesc'; $columns['wpseo-focuskw'] = 'wpseo-focuskw'; @@ -133,7 +135,8 @@ class WPSEO_Meta_Columns { $current_seo_filter = filter_input( INPUT_GET, 'seo_filter' ); echo ' - '; foreach ( $ranks as $rank ) { $sel = selected( $current_seo_filter, $rank->get_rank(), false ); @@ -299,12 +302,6 @@ class WPSEO_Meta_Columns { */ private function filter_order_by( $order_by ) { switch ( $order_by ) { - case 'wpseo-score' : - return array( - 'meta_key' => WPSEO_Meta::$meta_prefix . 'linkdex', - 'orderby' => 'meta_value_num', - ); - break; case 'wpseo-metadesc' : return array( 'meta_key' => WPSEO_Meta::$meta_prefix . 'metadesc', @@ -345,7 +342,7 @@ class WPSEO_Meta_Columns { $title = $rank->get_label(); } - return '
'; + return '' . $title . ''; } diff --git a/wp/wp-content/plugins/wordpress-seo/admin/class-option-tabs-formatter.php b/wp/wp-content/plugins/wordpress-seo/admin/class-option-tabs-formatter.php index a1cba818..7377b80b 100644 --- a/wp/wp-content/plugins/wordpress-seo/admin/class-option-tabs-formatter.php +++ b/wp/wp-content/plugins/wordpress-seo/admin/class-option-tabs-formatter.php @@ -31,29 +31,17 @@ class WPSEO_Option_Tabs_Formatter { } echo ''; - $filter_name = sprintf( 'yoast_option_tab_help_center_%s', $option_tabs->get_base() ); - $base_help_center_items = apply_filters( $filter_name, array() ); - foreach ( $option_tabs->get_tabs() as $tab ) { + // Prepare the help center for each tab. + $help_center = new WPSEO_Help_Center( $option_tabs->get_base(), $tab ); $identifier = $tab->get_name(); - printf( '
', $identifier ); - $filter_name = sprintf( 'yoast_option_tab_help_center_%s_%s', $option_tabs->get_base(), $tab->get_name() ); - $help_center_items = apply_filters( $filter_name, $base_help_center_items ); - - if ( ! empty( $help_center_items ) ) { - $this->create_help_center( $option_tabs->get_base(), $tab->get_name(), $help_center_items ); - } - else { - $video = $tab->get_video_url(); - if ( ! empty( $video ) ) { - $tab_video_url = $video; - include WPSEO_PATH . 'admin/views/partial-settings-tab-video.php'; - } - } + // Output the help center. + $help_center->output_help_center(); + // Output the settings view for all tabs. $tab_view = $this->get_tab_view( $option_tabs, $tab ); if ( is_file( $tab_view ) ) { require_once $tab_view; @@ -62,76 +50,4 @@ class WPSEO_Option_Tabs_Formatter { echo '
'; } } - - /** - * Build the help center - * - * @param string $base The base where the tab belongs to. - * @param string $tab The tab containing these items. - * @param WPSEO_Help_Center_Item[] $help_center_items List of helper items. - */ - private function create_help_center( $base, $tab, $help_center_items ) { - - $id = sprintf( 'tab-help-center-%s-%s', $base, $tab ); - - ?> -
- - -
- register_yoast_plugins(); + $this->register_yoast_plugins_status(); + } + + /** + * Registers all the available Yoast SEO plugins. + */ + protected function register_yoast_plugins() { + $this->plugins = array( + 'yoast-seo-premium' => array( + 'url' => 'https://yoast.com/wordpress/plugins/seo-premium/', + 'title' => 'Yoast SEO Premium', + /* translators: %1$s expands to Yoast SEO */ + 'description' => sprintf( __( 'The premium version of %1$s with more features & support.', 'wordpress-seo' ), 'Yoast SEO' ), + 'installed' => false, + 'slug' => 'wordpress-seo-premium/wp-seo-premium.php', + ), + + 'video-seo-for-wordpress-seo-by-yoast' => array( + 'url' => 'https://yoast.com/wordpress/plugins/video-seo/', + 'title' => 'Video SEO', + 'description' => __( 'Optimize your videos to show them off in search results and get more clicks!', 'wordpress-seo' ), + 'installed' => false, + 'slug' => 'wpseo-video/video-seo.php', + ), + + 'yoast-news-seo' => array( + 'url' => 'https://yoast.com/wordpress/plugins/news-seo/', + 'title' => 'News SEO', + 'description' => __( 'Are you in Google News? Increase your traffic from Google News by optimizing for it!', 'wordpress-seo' ), + 'installed' => false, + 'slug' => 'wpseo-news/wpseo-news.php', + ), + + 'local-seo-for-yoast-seo' => array( + 'url' => 'https://yoast.com/wordpress/plugins/local-seo/', + 'title' => 'Local SEO', + 'description' => __( 'Rank better locally and in Google Maps, without breaking a sweat!', 'wordpress-seo' ), + 'installed' => false, + 'slug' => 'wordpress-seo-local/local-seo.php', + ), + + 'yoast-woocommerce-seo' => array( + 'url' => 'https://yoast.com/wordpress/plugins/yoast-woocommerce-seo/', + 'title' => 'Yoast WooCommerce SEO', + /* translators: %1$s expands to Yoast SEO */ + 'description' => sprintf( __( 'Seamlessly integrate WooCommerce with %1$s and get extra features!', 'wordpress-seo' ), 'Yoast SEO' ), + 'installed' => false, + 'slug' => 'wpseo-woocommerce/wpseo-woocommerce.php', + ), + ); + } + + /** + * Sets certain plugin properties based on WordPress' status. + */ + protected function register_yoast_plugins_status() { + $installed_plugins = get_plugins(); + + foreach ( $this->plugins as $name => $plugin ) { + if ( isset( $installed_plugins[ $plugin['slug'] ] ) ) { + $this->plugins[ $name ]['installed'] = true; + $this->plugins[ $name ]['version'] = $installed_plugins[ $plugin['slug'] ]['Version']; + $this->plugins[ $name ]['active'] = is_plugin_active( $plugin['slug'] ); + } + } + } + + /** + * Checks whether or not a plugin is known within the Yoast SEO collection. + * + * @param {string} $plugin The plugin to search for. + * + * @return bool Whether or not the plugin is exists. + */ + protected function plugin_exists( $plugin ) { + return isset( $this->plugins[ $plugin ] ); + } + + /** + * Gets all the possibly available plugins. + * + * @return array Array containing the information about the plugins. + */ + public function get_plugins() { + return $this->plugins; + } + + /** + * Gets a specific plugin. Returns an empty array if it cannot be found. + * + * @param {string} $plugin The plugin to search for. + * + * @return array The plugin properties. + */ + public function get_plugin( $plugin ) { + if ( ! $this->plugin_exists( $plugin ) ) { + return array(); + } + + return $this->plugins[ $plugin ]; + } + + /** + * Gets the version of the plugin. + * + * @param {string} $plugin The plugin to search for. + * + * @return string The version associated with the plugin. + */ + public function get_version( $plugin ) { + if ( ! isset( $plugin['version'] ) ) { + return ''; + } + + return $plugin['version']; + } + + /** + * Checks if there are dependencies available for the plugin. + * + * @param {string} $plugin The plugin to search for. + * + * @return bool Whether or not there is a dependency present. + */ + public function has_dependencies( $plugin ) { + return ( isset( $plugin['_dependencies'] ) && ! empty( $plugin['_dependencies'] ) ); + } + + /** + * Gets the dependencies for the plugin. + * + * @param {string} $plugin The plugin to search for. + * + * @return array Array containing all the dependencies associated with the plugin. + */ + public function get_dependencies( $plugin ) { + if ( ! $this->has_dependencies( $plugin ) ) { + return array(); + } + + return $plugin['_dependencies']; + } + + /** + * Checks if all dependencies are satisfied. + * + * @param {string} $plugin The plugin to search for. + * + * @return bool Whether or not the dependencies are satisfied. + */ + public function dependencies_are_satisfied( $plugin ) { + if ( ! $this->has_dependencies( $plugin ) ) { + return true; + } + + $dependencies = $this->get_dependencies( $plugin ); + $installed_dependencies = array_filter( $dependencies, array( $this, 'is_dependency_available' ) ); + + return count( $installed_dependencies ) === count( $dependencies ); + } + + /** + * Checks whether or not one of the plugins is properly installed and usable. + * + * @param {string} $plugin The plugin to search for. + * + * @return bool Whether or not the plugin is properly installed. + */ + public function is_installed( $plugin ) { + if ( empty( $plugin ) ) { + return false; + } + + $dependencies_are_satisfied = $this->dependencies_are_satisfied( $plugin ); + + return $dependencies_are_satisfied && $this->is_available( $plugin ); + } + + /** + * Gets all installed plugins. + * + * @return array + */ + public function get_installed_plugins() { + $installed = array(); + + foreach ( $this->plugins as $pluginKey => $plugin ) { + if ( $this->is_installed( $plugin ) ) { + $installed[ $pluginKey ] = $plugin; + } + } + + return $installed; + } + + /** + * Checks for the availability of the plugin. + * + * @param {string} $plugin The plugin to search for. + * + * @return bool Whether or not the plugin is available. + */ + public function is_available( $plugin ) { + return isset( $plugin['installed'] ) && $plugin['installed'] === true; + } + + /** + * Checks whether a dependency is available. + * + * @param {string} $dependency The dependency to look for. + * + * @return bool Whether or not the dependency is available. + */ + public function is_dependency_available( $dependency ) { + return class_exists( $dependency ); + } +} diff --git a/wp/wp-content/plugins/wordpress-seo/admin/class-plugin-compatibility.php b/wp/wp-content/plugins/wordpress-seo/admin/class-plugin-compatibility.php new file mode 100644 index 00000000..9b0ee882 --- /dev/null +++ b/wp/wp-content/plugins/wordpress-seo/admin/class-plugin-compatibility.php @@ -0,0 +1,101 @@ +current_wpseo_version = $this->get_major_minor_version( $version ); + $this->availability_checker = $this->retrieve_availability_checker( $availability_checker ); + $this->installed_plugins = $this->availability_checker->get_installed_plugins(); + } + + /** + * Retrieves the availability checker. + * + * @param null|object $checker The checker to set. + * + * @return WPSEO_Plugin_Availability The checker to use. + */ + private function retrieve_availability_checker( $checker ) { + if ( is_null( $checker ) || ! is_object( $checker ) ) { + return new WPSEO_Plugin_Availability(); + } + + return $checker; + } + + /** + * Wraps the availability checker's get_installed_plugins method. + * + * @return array Array containing all the installed plugins. + */ + public function get_installed_plugins() { + return $this->installed_plugins; + } + + /** + * Creates a list of installed plugins and whether or not they are compatible. + * + * @return array Array containing the installed plugins and compatibility. + */ + public function get_installed_plugins_compatibility() { + foreach ( $this->installed_plugins as $key => $plugin ) { + + $this->installed_plugins[ $key ]['compatible'] = $this->is_compatible( $key ); + } + + return $this->installed_plugins; + } + + /** + * Checks whether or not a plugin is compatible. + * + * @param string $plugin The plugin to look for and match. + * + * @return bool Whether or not the plugin is compatible. + */ + public function is_compatible( $plugin ) { + $plugin = $this->availability_checker->get_plugin( $plugin ); + $plugin_version = $this->availability_checker->get_version( $plugin ); + + return $this->get_major_minor_version( $plugin_version ) === $this->current_wpseo_version; + } + + /** + * Gets the major/minor version of the plugin for easier comparing. + * + * @param string $version The version to trim. + * + * @return string The major/minor version of the plugin. + */ + protected function get_major_minor_version( $version ) { + return substr( $version, 0, 3 ); + } +} diff --git a/wp/wp-content/plugins/wordpress-seo/admin/class-plugin-conflict.php b/wp/wp-content/plugins/wordpress-seo/admin/class-plugin-conflict.php index 29bd2634..db3380e7 100644 --- a/wp/wp-content/plugins/wordpress-seo/admin/class-plugin-conflict.php +++ b/wp/wp-content/plugins/wordpress-seo/admin/class-plugin-conflict.php @@ -115,9 +115,6 @@ class WPSEO_Plugin_Conflict extends Yoast_Plugin_Conflict { */ public static function hook_check_for_plugin_conflicts( $plugin = false ) { - // Just a return, because we want to temporary disable this notice (#3998). - return; - // The instance of itself. $instance = self::get_instance(); @@ -127,22 +124,31 @@ class WPSEO_Plugin_Conflict extends Yoast_Plugin_Conflict { $instance->add_active_plugin( $instance->find_plugin_category( $plugin ), $plugin ); } - $plugin_sections = array( + $plugin_sections = array(); + + // Only check for open graph problems when they are enabled. + $social_options = WPSEO_Options::get_option( 'wpseo_social' ); + if ( $social_options['opengraph'] ) { /* translators: %1$s expands to Yoast SEO, %2%s: 'Facebook' plugin name of possibly conflicting plugin with regard to creating OpenGraph output*/ - 'open_graph' => __( 'Both %1$s and %2$s create OpenGraph output, which might make Facebook, Twitter, LinkedIn and other social networks use the wrong texts and images when your pages are being shared.', 'wordpress-seo' ) - . '

' - . '' - /* translators: %1$s expands to Yoast SEO */ - . sprintf( __( 'Configure %1$s\'s OpenGraph settings', 'wordpress-seo' ), 'Yoast SEO' ) - . '', + $plugin_sections['open_graph'] = __( 'Both %1$s and %2$s create OpenGraph output, which might make Facebook, Twitter, LinkedIn and other social networks use the wrong texts and images when your pages are being shared.', 'wordpress-seo' ) + . '

' + . '' + /* translators: %1$s expands to Yoast SEO */ + . sprintf( __( 'Configure %1$s\'s OpenGraph settings', 'wordpress-seo' ), 'Yoast SEO' ) + . ''; + } + + // Only check for XML conflicts if sitemaps are enabled. + $xml_sitemap_options = WPSEO_Options::get_option( 'wpseo_xml' ); + if ( $xml_sitemap_options['enablexmlsitemap'] ) { /* translators: %1$s expands to Yoast SEO, %2$s: 'Google XML Sitemaps' plugin name of possibly conflicting plugin with regard to the creation of sitemaps*/ - 'xml_sitemaps' => __( 'Both %1$s and %2$s can create XML sitemaps. Having two XML sitemaps is not beneficial for search engines, yet might slow down your site.', 'wordpress-seo' ) - . '

' - . '' - /* translators: %1$s expands to Yoast SEO */ - . sprintf( __( 'Configure %1$s\'s XML Sitemap settings', 'wordpress-seo' ), 'Yoast SEO' ) - . '', - ); + $plugin_sections['xml_sitemaps'] = __( 'Both %1$s and %2$s can create XML sitemaps. Having two XML sitemaps is not beneficial for search engines, yet might slow down your site.', 'wordpress-seo' ) + . '

' + . '' + /* translators: %1$s expands to Yoast SEO */ + . sprintf( __( 'Configure %1$s\'s XML Sitemap settings', 'wordpress-seo' ), 'Yoast SEO' ) + . ''; + } $instance->check_plugin_conflicts( $plugin_sections ); } diff --git a/wp/wp-content/plugins/wordpress-seo/admin/class-pointers.php b/wp/wp-content/plugins/wordpress-seo/admin/class-pointers.php index 8f63ae21..9a5419c5 100644 --- a/wp/wp-content/plugins/wordpress-seo/admin/class-pointers.php +++ b/wp/wp-content/plugins/wordpress-seo/admin/class-pointers.php @@ -104,7 +104,7 @@ class WPSEO_Pointers { return; } - var wpseo_pointer_options = , setup; + var wpseo_pointer_options = , setup; wpseo_pointer_options = $.extend(wpseo_pointer_options, { buttons: function (event, t) { @@ -170,7 +170,7 @@ class WPSEO_Pointers { * Show a pointer that starts the tour for Yoast SEO */ private function start_tour_pointer() { - $selector = 'li.toplevel_page_wpseo_dashboard'; + $selector = 'li.toplevel_page_wpseo_alerts a[href="admin.php?page=' . WPSEO_Admin::PAGE_IDENTIFIER . '"]'; $content = '

' . __( 'Congratulations!', 'wordpress-seo' ) . '

' /* translators: %1$s expands to Yoast SEO */ . '

' . sprintf( __( 'You’ve just installed %1$s! Click “Start Tour” to view a quick introduction of this plugin’s core functionality.', 'wordpress-seo' ), 'Yoast SEO' ) . '

'; @@ -180,7 +180,7 @@ class WPSEO_Pointers { ); $this->button_array['button2']['text'] = __( 'Start Tour', 'wordpress-seo' ); - $this->button_array['button2']['function'] = sprintf( 'document.location="%s";', admin_url( 'admin.php?page=wpseo_dashboard' ) ); + $this->button_array['button2']['function'] = sprintf( 'document.location="%s";', admin_url( 'admin.php?page=' . WPSEO_Admin::PAGE_IDENTIFIER ) ); $this->print_scripts( $selector, $opt_arr ); } diff --git a/wp/wp-content/plugins/wordpress-seo/admin/class-premium-popup.php b/wp/wp-content/plugins/wordpress-seo/admin/class-premium-popup.php new file mode 100644 index 00000000..f0299ae6 --- /dev/null +++ b/wp/wp-content/plugins/wordpress-seo/admin/class-premium-popup.php @@ -0,0 +1,87 @@ +identifier = $identifier; + $this->heading_level = $heading_level; + $this->title = $title; + $this->content = $content; + } + + /** + * Returns the premium popup as an HTML string. + * + * @param bool $popup Show this message as a popup show it straight away. + * + * @return string + */ + public function get_premium_message( $popup = true ) { + // Don't show in Premium. + if ( defined( 'WPSEO_PREMIUM_FILE' ) ) { + return ''; + } + + $assets_uri = trailingslashit( plugin_dir_url( WPSEO_FILE ) ); + $premium_uri = 'https://yoast.com/wordpress/plugins/seo-premium/#utm_source=wordpress-seo-metabox&utm_medium=popup&utm_campaign=help-center-contact-support'; + + /* translators: %s expands to Yoast SEO Premium */ + $cta_text = sprintf( __( 'Buy %s', 'wordpress-seo' ), 'Yoast SEO Premium' ); + $display = ''; + if ( $popup ) { + $display = 'display:none;'; + } + + $popup = << + Yoast SEO + <{$this->heading_level} id="wpseo-contact-support-popup-title" class="wpseo-premium-popup-title">{$this->title}heading_level}> +

{$this->content}

+ {$cta_text} +
+EO_POPUP; + + return $popup; + } +} diff --git a/wp/wp-content/plugins/wordpress-seo/admin/class-social-facebook.php b/wp/wp-content/plugins/wordpress-seo/admin/class-social-facebook.php index 783b928a..0e21599c 100644 --- a/wp/wp-content/plugins/wordpress-seo/admin/class-social-facebook.php +++ b/wp/wp-content/plugins/wordpress-seo/admin/class-social-facebook.php @@ -77,7 +77,7 @@ class Yoast_Social_Facebook { } } - return WPSEO_Utils::json_encode( + return wp_json_encode( array( 'success' => $success, 'html' => $response_body, @@ -463,7 +463,7 @@ class Yoast_Social_Facebook_Form { } /** - * Check if the clear button should be displayed. This is based on the the set options + * Check if the clear button should be displayed. This is based on the set options. * * @return bool */ diff --git a/wp/wp-content/plugins/wordpress-seo/admin/class-yoast-alerts.php b/wp/wp-content/plugins/wordpress-seo/admin/class-yoast-alerts.php new file mode 100644 index 00000000..317d4666 --- /dev/null +++ b/wp/wp-content/plugins/wordpress-seo/admin/class-yoast-alerts.php @@ -0,0 +1,258 @@ +add_hooks(); + } + + /** + * Add hooks + */ + private function add_hooks() { + + $page = filter_input( INPUT_GET, 'page' ); + if ( self::ADMIN_PAGE === $page ) { + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) ); + } + + // Needed for adminbar and Alerts page. + add_action( 'admin_init', array( __CLASS__, 'collect_alerts' ), 99 ); + + // Add AJAX hooks. + add_action( 'wp_ajax_yoast_dismiss_alert', array( $this, 'ajax_dismiss_alert' ) ); + add_action( 'wp_ajax_yoast_restore_alert', array( $this, 'ajax_restore_alert' ) ); + } + + /** + * Enqueue assets + */ + public function enqueue_assets() { + + $asset_manager = new WPSEO_Admin_Asset_Manager(); + $asset_manager->enqueue_style( 'alerts' ); + } + + /** + * Handle ajax request to dismiss an alert + */ + public function ajax_dismiss_alert() { + + $notification = $this->get_notification_from_ajax_request(); + if ( $notification ) { + $notification_center = Yoast_Notification_Center::get(); + $notification_center->maybe_dismiss_notification( $notification ); + + $this->output_ajax_response( $notification->get_type() ); + } + + wp_die(); + } + + /** + * Handle ajax request to restore an alert + */ + public function ajax_restore_alert() { + + $notification = $this->get_notification_from_ajax_request(); + if ( $notification ) { + delete_user_meta( get_current_user_id(), $notification->get_dismissal_key() ); + + $this->output_ajax_response( $notification->get_type() ); + } + + wp_die(); + } + + /** + * Create AJAX response data + * + * @param string $type Alert type. + */ + private function output_ajax_response( $type ) { + + $html = $this->get_view_html( $type ); + echo wp_json_encode( + array( + 'html' => $html, + 'total' => self::get_active_alert_count(), + ) + ); + } + + /** + * Get the HTML to return in the AJAX request + * + * @param string $type Alert type. + * + * @return bool|string + */ + private function get_view_html( $type ) { + + switch ( $type ) { + case 'error': + $view = 'errors'; + break; + + case 'warning': + default: + $view = 'warnings'; + break; + } + + // Re-collect alerts. + self::collect_alerts(); + + /** @noinspection PhpUnusedLocalVariableInspection */ + $alerts_data = self::get_template_variables(); + + ob_start(); + include WPSEO_PATH . 'admin/views/partial-alerts-' . $view . '.php'; + $html = ob_get_clean(); + + return $html; + } + + /** + * Extract the Yoast Notification from the AJAX request + * + * @return null|Yoast_Notification + */ + private function get_notification_from_ajax_request() { + + $notification_center = Yoast_Notification_Center::get(); + $notification_id = filter_input( INPUT_POST, 'notification' ); + + return $notification_center->get_notification_by_id( $notification_id ); + } + + /** + * Show the alerts overview page + */ + public static function show_overview_page() { + + /** @noinspection PhpUnusedLocalVariableInspection */ + $alerts_data = self::get_template_variables(); + + include WPSEO_PATH . 'admin/views/alerts-dashboard.php'; + } + + /** + * Collect the alerts and group them together + */ + public static function collect_alerts() { + + $notification_center = Yoast_Notification_Center::get(); + + $notifications = $notification_center->get_sorted_notifications(); + self::$notification_count = count( $notifications ); + + self::$errors = array_filter( $notifications, array( __CLASS__, 'filter_error_alerts' ) ); + self::$dismissed_errors = array_filter( self::$errors, array( __CLASS__, 'filter_dismissed_alerts' ) ); + self::$active_errors = array_diff( self::$errors, self::$dismissed_errors ); + + self::$warnings = array_filter( $notifications, array( __CLASS__, 'filter_warning_alerts' ) ); + self::$dismissed_warnings = array_filter( self::$warnings, array( __CLASS__, 'filter_dismissed_alerts' ) ); + self::$active_warnings = array_diff( self::$warnings, self::$dismissed_warnings ); + } + + /** + * Get the variables needed in the views + * + * @return array + */ + public static function get_template_variables() { + + return array( + 'metrics' => array( + 'total' => self::$notification_count, + 'active' => self::get_active_alert_count(), + 'errors' => count( self::$errors ), + 'warnings' => count( self::$warnings ), + ), + 'errors' => array( + 'dismissed' => self::$dismissed_errors, + 'active' => self::$active_errors, + ), + 'warnings' => array( + 'dismissed' => self::$dismissed_warnings, + 'active' => self::$active_warnings, + ), + ); + } + + /** + * Get the number of active alerts + * + * @return int + */ + public static function get_active_alert_count() { + + return ( count( self::$active_errors ) + count( self::$active_warnings ) ); + } + + /** + * Filter out any non-errors + * + * @param Yoast_Notification $notification Notification to test. + * + * @return bool + */ + private static function filter_error_alerts( Yoast_Notification $notification ) { + + return $notification->get_type() === 'error'; + } + + /** + * Filter out any non-warnings + * + * @param Yoast_Notification $notification Notification to test. + * + * @return bool + */ + private static function filter_warning_alerts( Yoast_Notification $notification ) { + + return $notification->get_type() !== 'error'; + } + + /** + * Filter out any dismissed notifications + * + * @param Yoast_Notification $notification Notification to test. + * + * @return bool + */ + private static function filter_dismissed_alerts( Yoast_Notification $notification ) { + + return Yoast_Notification_Center::is_notification_dismissed( $notification ); + } +} diff --git a/wp/wp-content/plugins/wordpress-seo/admin/class-yoast-form.php b/wp/wp-content/plugins/wordpress-seo/admin/class-yoast-form.php index 5dc06b3b..02be6dca 100644 --- a/wp/wp-content/plugins/wordpress-seo/admin/class-yoast-form.php +++ b/wp/wp-content/plugins/wordpress-seo/admin/class-yoast-form.php @@ -110,8 +110,16 @@ class Yoast_Form { '; } + /** + * Apply general admin_footer hooks + */ do_action( 'wpseo_admin_footer' ); + /** + * Run possibly set actions to add for example an i18n box + */ + do_action( 'wpseo_admin_promo_footer' ); + echo ' '; @@ -161,17 +169,32 @@ class Yoast_Form { array( 'url' => 'https://yoast.com/hire-us/website-review/#utm_source=wordpress-seo-config&utm_medium=banner&utm_campaign=website-review-banner', 'img' => 'banner-website-review.png', - 'alt' => 'Website Review banner', + 'alt' => __( 'Order a Website Review and we will tell you what to improve to attract more visitors!', 'wordpress-seo' ), + ), + array( + 'url' => 'https://yoast.com/hire-us/website-review/#utm_source=wordpress-seo-config&utm_medium=banner&utm_campaign=website-review-banner', + 'img' => 'banner-website-review.png', + 'alt' => __( 'Order a Website Review and we will tell you what to improve to attract more visitors!', 'wordpress-seo' ), + ), + array( + 'url' => 'https://yoast.com/hire-us/website-review/#utm_source=wordpress-seo-config&utm_medium=banner&utm_campaign=website-review-banner', + 'img' => 'banner-website-review.png', + 'alt' => __( 'Order a Website Review and we will tell you what to improve to attract more visitors!', 'wordpress-seo' ), + ), + array( + 'url' => 'https://yoast.com/academy/course/seo-copywriting-training/#utm_source=wordpress-seo-config&utm_medium=banner&utm_campaign=seo-copywriting-training-banner', + 'img' => 'banner-seo-copywriting-training.png', + 'alt' => __( 'Take the online SEO Copywriting Training course and learn how to write awesome copy that ranks!', 'wordpress-seo' ), ), array( 'url' => 'https://yoast.com/academy/course/basic-seo-training/#utm_source=wordpress-seo-config&utm_medium=banner&utm_campaign=basic-seo-training-banner', 'img' => 'banner-basic-seo-training.png', - 'alt' => 'Basic SEO Training banner', + 'alt' => __( 'Take the online Basic SEO Training course and learn the fundamentals of SEO!', 'wordpress-seo' ), ), array( 'url' => 'https://yoast.com/academy/course/yoast-seo-wordpress-training/#utm_source=wordpress-seo-config&utm_medium=banner&utm_campaign=yoast-seo-plugin-training-banner', 'img' => 'banner-yoast-seo-for-wordpress-training.png', - 'alt' => 'Yoast SEO for WordPress Training banner', + 'alt' => __( 'Take the Yoast SEO for WordPress Training course and become a certified Yoast SEO for WordPress expert!', 'wordpress-seo' ), ), ); @@ -179,7 +202,7 @@ class Yoast_Form { array( 'url' => 'https://yoast.com/wordpress/plugins/seo-premium/#utm_source=wordpress-seo-config&utm_medium=banner&utm_campaign=premium-seo-banner', 'img' => 'banner-premium-seo.png', - 'alt' => 'Banner Yoast SEO Premium', + 'alt' => __( 'Buy the Yoast SEO Premium plugin now and get access to extra features and 24/7 support!', 'wordpress-seo' ), ), ); @@ -187,7 +210,7 @@ class Yoast_Form { $plugin_banners[] = array( 'url' => 'https://yoast.com/wordpress/plugins/video-seo/#utm_source=wordpress-seo-config&utm_medium=banner&utm_campaign=video-seo-banner', 'img' => 'banner-video-seo.png', - 'alt' => 'Banner Yoast Video SEO plugin', + 'alt' => __( 'Buy the Yoast Video SEO plugin now and optimize your videos for video search results and social media!', 'wordpress-seo' ), ); } @@ -195,7 +218,7 @@ class Yoast_Form { $plugin_banners[] = array( 'url' => 'https://yoast.com/wordpress/plugins/yoast-woocommerce-seo/#utm_source=wordpress-seo-config&utm_medium=banner&utm_campaign=woocommerce-seo-banner', 'img' => 'banner-woocommerce-seo.png', - 'alt' => 'Banner Yoast WooCommerce SEO plugin', + 'alt' => __( 'Buy the Yoast WooCommerce SEO plugin now and optimize your shop today to improve your product promotion!', 'wordpress-seo' ), ); } @@ -203,7 +226,7 @@ class Yoast_Form { $plugin_banners[] = array( 'url' => 'https://yoast.com/wordpress/plugins/local-seo/#utm_source=wordpress-seo-config&utm_medium=banner&utm_campaign=local-seo-banner', 'img' => 'banner-local-seo.png', - 'alt' => 'Banner Yoast Local SEO plugin', + 'alt' => __( 'Buy the Yoast Local SEO plugin now to improve your site’s Local SEO and ranking in Google Maps!', 'wordpress-seo' ), ); } @@ -211,7 +234,7 @@ class Yoast_Form { $plugin_banners[] = array( 'url' => 'https://yoast.com/wordpress/plugins/news-seo/#utm_source=wordpress-seo-config&utm_medium=banner&utm_campaign=news-seo-banner', 'img' => 'banner-news-seo.png', - 'alt' => 'Banner Yoast News SEO plugin', + 'alt' => __( 'Buy the Yoast News SEO plugin now and start optimizing to get your site featured in Google News!', 'wordpress-seo' ), ); } @@ -235,10 +258,12 @@ class Yoast_Form { $i ++; } ?> +




+ printf( __( 'Upgrade to %1$s »', 'wordpress-seo' ), 'Yoast SEO Premium' ); ?> +

', - '