From fae09739706fde706b686e45bc356fd90542ff4b Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 31 Mar 2017 18:18:33 +0200 Subject: [PATCH 001/282] :books: Fix some end comments A number of function names have changed in the 0.11.0 release, but some of the end comments still reflected their old function names. --- WordPress/AbstractArrayAssignmentRestrictionsSniff.php | 2 +- WordPress/AbstractFunctionRestrictionsSniff.php | 2 +- WordPress/AbstractVariableRestrictionsSniff.php | 2 +- WordPress/Sniffs/CSRF/NonceVerificationSniff.php | 2 +- WordPress/Sniffs/Files/FileNameSniff.php | 2 +- WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php | 2 +- WordPress/Sniffs/VIP/AdminBarRemovalSniff.php | 2 +- WordPress/Sniffs/VIP/CronIntervalSniff.php | 2 +- WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php | 2 +- WordPress/Sniffs/VIP/ValidatedSanitizedInputSniff.php | 2 +- WordPress/Sniffs/Variables/GlobalVariablesSniff.php | 2 +- WordPress/Sniffs/WP/PreparedSQLSniff.php | 2 +- WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php | 2 +- WordPress/Sniffs/XSS/EscapeOutputSniff.php | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/WordPress/AbstractArrayAssignmentRestrictionsSniff.php b/WordPress/AbstractArrayAssignmentRestrictionsSniff.php index 76be72f9..ae2ccd1b 100644 --- a/WordPress/AbstractArrayAssignmentRestrictionsSniff.php +++ b/WordPress/AbstractArrayAssignmentRestrictionsSniff.php @@ -186,7 +186,7 @@ public function process_token( $stackPtr ) { } } // End foreach(). - } // End process(). + } // End process_token(). /** * Callback to process each confirmed key, to check value. diff --git a/WordPress/AbstractFunctionRestrictionsSniff.php b/WordPress/AbstractFunctionRestrictionsSniff.php index 14e55c51..69a5dbe9 100644 --- a/WordPress/AbstractFunctionRestrictionsSniff.php +++ b/WordPress/AbstractFunctionRestrictionsSniff.php @@ -168,7 +168,7 @@ public function process_token( $stackPtr ) { return $this->check_for_matches( $stackPtr ); } - } // End process(). + } // End process_token(). /** * Verify is the current token is a function call. diff --git a/WordPress/AbstractVariableRestrictionsSniff.php b/WordPress/AbstractVariableRestrictionsSniff.php index a70f20eb..6e51b5e6 100644 --- a/WordPress/AbstractVariableRestrictionsSniff.php +++ b/WordPress/AbstractVariableRestrictionsSniff.php @@ -182,7 +182,7 @@ public function process_token( $stackPtr ) { } // End foreach(). - } // End process(). + } // End process_token(). /** * Transform a wildcard pattern to a usable regex pattern. diff --git a/WordPress/Sniffs/CSRF/NonceVerificationSniff.php b/WordPress/Sniffs/CSRF/NonceVerificationSniff.php index 6335350b..215b67ea 100644 --- a/WordPress/Sniffs/CSRF/NonceVerificationSniff.php +++ b/WordPress/Sniffs/CSRF/NonceVerificationSniff.php @@ -157,7 +157,7 @@ public function process_token( $stackPtr ) { 'NoNonceVerification' ); - } // End process(). + } // End process_token(). /** * Merge custom functions provided via a custom ruleset with the defaults, if we haven't already. diff --git a/WordPress/Sniffs/Files/FileNameSniff.php b/WordPress/Sniffs/Files/FileNameSniff.php index a521845e..1b537794 100644 --- a/WordPress/Sniffs/Files/FileNameSniff.php +++ b/WordPress/Sniffs/Files/FileNameSniff.php @@ -201,6 +201,6 @@ public function process_token( $stackPtr ) { // Only run this sniff once per file, no need to run it again. return ( $this->phpcsFile->numTokens + 1 ); - } // End process(). + } // End process_token(). } // End class. diff --git a/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php b/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php index 7acace6d..851c018b 100644 --- a/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php +++ b/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php @@ -153,7 +153,7 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p $this->phpcsFile->addWarning( $error, $stackPtr, 'UseUnderscores', $data ); } - } // End process(). + } // End process_parameters(). /** * Prepare the punctuation regular expression. diff --git a/WordPress/Sniffs/VIP/AdminBarRemovalSniff.php b/WordPress/Sniffs/VIP/AdminBarRemovalSniff.php index 7bcfd4ed..9f2c519e 100644 --- a/WordPress/Sniffs/VIP/AdminBarRemovalSniff.php +++ b/WordPress/Sniffs/VIP/AdminBarRemovalSniff.php @@ -193,7 +193,7 @@ public function process_token( $stackPtr ) { return parent::process_token( $stackPtr ); } - } // End process(). + } // End process_token(). /** * Process the parameters of a matched function. diff --git a/WordPress/Sniffs/VIP/CronIntervalSniff.php b/WordPress/Sniffs/VIP/CronIntervalSniff.php index 0dc7f45f..b363d41c 100644 --- a/WordPress/Sniffs/VIP/CronIntervalSniff.php +++ b/WordPress/Sniffs/VIP/CronIntervalSniff.php @@ -167,7 +167,7 @@ public function process_token( $stackPtr ) { return; } - } // End process(). + } // End process_token(). /** * Add warning about unclear cron schedule change. diff --git a/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php b/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php index c3710975..9af8fc4b 100644 --- a/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php +++ b/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php @@ -211,7 +211,7 @@ public function process_token( $stackPtr ) { return $endOfStatement; - } // End process(). + } // End process_token(). /** * Merge custom functions provided via a custom ruleset with the defaults, if we haven't already. diff --git a/WordPress/Sniffs/VIP/ValidatedSanitizedInputSniff.php b/WordPress/Sniffs/VIP/ValidatedSanitizedInputSniff.php index 72cc1d37..3edc5754 100644 --- a/WordPress/Sniffs/VIP/ValidatedSanitizedInputSniff.php +++ b/WordPress/Sniffs/VIP/ValidatedSanitizedInputSniff.php @@ -145,7 +145,7 @@ public function process_token( $stackPtr ) { $this->phpcsFile->addError( 'Detected usage of a non-sanitized input variable: %s', $stackPtr, 'InputNotSanitized', $error_data ); } - } // End process(). + } // End process_token(). /** * Merge custom functions provided via a custom ruleset with the defaults, if we haven't already. diff --git a/WordPress/Sniffs/Variables/GlobalVariablesSniff.php b/WordPress/Sniffs/Variables/GlobalVariablesSniff.php index 6710f584..ab20ef72 100644 --- a/WordPress/Sniffs/Variables/GlobalVariablesSniff.php +++ b/WordPress/Sniffs/Variables/GlobalVariablesSniff.php @@ -400,7 +400,7 @@ public function process_token( $stackPtr ) { } } // End if(). - } // End process(). + } // End process_token(). /** * Add the error if there is no whitelist comment present and the assignment diff --git a/WordPress/Sniffs/WP/PreparedSQLSniff.php b/WordPress/Sniffs/WP/PreparedSQLSniff.php index a406907b..99c5472e 100644 --- a/WordPress/Sniffs/WP/PreparedSQLSniff.php +++ b/WordPress/Sniffs/WP/PreparedSQLSniff.php @@ -192,7 +192,7 @@ public function process_token( $stackPtr ) { return $this->end; - } // End process(). + } // End process_token(). /** * Checks whether this is a call to a $wpdb method that we want to sniff. diff --git a/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php b/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php index 36d89977..85a80da2 100644 --- a/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php +++ b/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php @@ -552,6 +552,6 @@ public function process_token( $stackPtr ) { } } // End if(). - } // End process(). + } // End process_token(). } // End class. diff --git a/WordPress/Sniffs/XSS/EscapeOutputSniff.php b/WordPress/Sniffs/XSS/EscapeOutputSniff.php index 849c3638..53515275 100644 --- a/WordPress/Sniffs/XSS/EscapeOutputSniff.php +++ b/WordPress/Sniffs/XSS/EscapeOutputSniff.php @@ -396,7 +396,7 @@ public function process_token( $stackPtr ) { return $end_of_statement; - } // End process(). + } // End process_token(). /** * Merge custom functions provided via a custom ruleset with the defaults, if we haven't already. From 9837980541bf1cfd25a870160e7c025a97bef088 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 31 Mar 2017 21:17:23 +0200 Subject: [PATCH 002/282] :ambulance: Fixes: Whitelist function could sometimes be a bit too eager. If there is no whitelist comment, but a comment on the next line would - for whatever reason - include a whitelist keyword, it was still regarded as a whitelist comment. This commit fixes that by changing two things: 1. The whitelist comment is now expected to be on the same line as the statement end token. 2. The whitelist keyword will no longer be matched if it is part of another phrase. So the whitelist keyword `key` will now only match `key` and not `keyword`. Includes unit tests for both fixes. --- WordPress/Sniff.php | 6 +++--- WordPress/Tests/PHP/StrictComparisonsUnitTest.inc | 12 +++++++++++- WordPress/Tests/PHP/StrictComparisonsUnitTest.php | 4 +++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index e5c8e3c3..a7f0d76d 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -820,13 +820,13 @@ protected function has_whitelist_comment( $comment, $stackPtr ) { $last = $this->tokens[ $lastPtr ]; - // Ignore if not a comment. - if ( T_COMMENT !== $last['code'] ) { + // Ignore if not a comment or not on the same line. + if ( T_COMMENT !== $last['code'] || $last['line'] !== $this->tokens[ $end_of_line ]['line'] ) { return false; } // Now let's see if the comment contains the whitelist remark we're looking for. - return ( preg_match( '#' . preg_quote( $comment, '#' ) . '#i', $last['content'] ) === 1 ); + return ( preg_match( '#\b' . preg_quote( $comment, '#' ) . '\b#i', $last['content'] ) === 1 ); } /** diff --git a/WordPress/Tests/PHP/StrictComparisonsUnitTest.inc b/WordPress/Tests/PHP/StrictComparisonsUnitTest.inc index 1cb1fe41..7c3ce841 100644 --- a/WordPress/Tests/PHP/StrictComparisonsUnitTest.inc +++ b/WordPress/Tests/PHP/StrictComparisonsUnitTest.inc @@ -18,4 +18,14 @@ if ( true != $true ) { // Bad. // Test for whitelisting. if ( true == $true ) { // Loose comparison, OK. echo 'True'; -} \ No newline at end of file +} + +// Test that whitelisting is not too eager. +if ( true == $true ) { + // The line above has a loose comparison, but no whitelist comment. + echo 'True'; +} + +if ( true == $true ) { // Loose comparisons FTW! + echo 'True'; +} diff --git a/WordPress/Tests/PHP/StrictComparisonsUnitTest.php b/WordPress/Tests/PHP/StrictComparisonsUnitTest.php index 1de1ad16..caa032ff 100644 --- a/WordPress/Tests/PHP/StrictComparisonsUnitTest.php +++ b/WordPress/Tests/PHP/StrictComparisonsUnitTest.php @@ -32,9 +32,11 @@ public function getErrorList() { */ public function getWarningList() { return array( - 3 => 1, + 3 => 1, 10 => 1, 12 => 1, + 24 => 1, + 29 => 1, ); } From a610df61ed2768e77bbb39d77a20599bf6136677 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 1 Apr 2017 03:35:41 +0200 Subject: [PATCH 003/282] Document the availability of the `$custom_test_class_whitelist` property in the relevant sniffs. --- WordPress/Sniffs/Files/FileNameSniff.php | 2 ++ WordPress/Sniffs/Variables/GlobalVariablesSniff.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/WordPress/Sniffs/Files/FileNameSniff.php b/WordPress/Sniffs/Files/FileNameSniff.php index 1b537794..76e305b0 100644 --- a/WordPress/Sniffs/Files/FileNameSniff.php +++ b/WordPress/Sniffs/Files/FileNameSniff.php @@ -22,6 +22,8 @@ * - This sniff will now allow for underscores in file names for certain theme * specific exceptions if the `$is_theme` property is set to `true`. * @since 0.12.0 - Now extends the `WordPress_Sniff` class. + * + * @uses WordPress_Sniff::$custom_test_class_whitelist */ class WordPress_Sniffs_Files_FileNameSniff extends WordPress_Sniff { diff --git a/WordPress/Sniffs/Variables/GlobalVariablesSniff.php b/WordPress/Sniffs/Variables/GlobalVariablesSniff.php index dc50e0d5..3774b0bd 100644 --- a/WordPress/Sniffs/Variables/GlobalVariablesSniff.php +++ b/WordPress/Sniffs/Variables/GlobalVariablesSniff.php @@ -16,6 +16,8 @@ * * @since 0.3.0 * @since 0.4.0 This class now extends WordPress_Sniff. + * + * @uses WordPress_Sniff::$custom_test_class_whitelist */ class WordPress_Sniffs_Variables_GlobalVariablesSniff extends WordPress_Sniff { From c53637102cc3d524e6aaa8e57d58ab6124ba7915 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 1 Apr 2017 03:20:25 +0200 Subject: [PATCH 004/282] GlobalVariables: remove an incorrect variable from the list of WP global variables. --- WordPress/Sniffs/Variables/GlobalVariablesSniff.php | 1 - 1 file changed, 1 deletion(-) diff --git a/WordPress/Sniffs/Variables/GlobalVariablesSniff.php b/WordPress/Sniffs/Variables/GlobalVariablesSniff.php index dc50e0d5..6021644e 100644 --- a/WordPress/Sniffs/Variables/GlobalVariablesSniff.php +++ b/WordPress/Sniffs/Variables/GlobalVariablesSniff.php @@ -226,7 +226,6 @@ class WordPress_Sniffs_Variables_GlobalVariablesSniff extends WordPress_Sniff { 'cat', 'lost', 'avail_post_mime_types', - '$var', 'errors', 'cat_id', 'orderby', From e1a09fa713d39478a15e6ad1bd322c003f5c2326 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 1 Apr 2017 03:34:30 +0200 Subject: [PATCH 005/282] GlobalVariables: Order the list of WP global variables alphabetically & change to key => true format Also: rename the property to be slightly more desciptive. --- .../Sniffs/Variables/GlobalVariablesSniff.php | 481 +++++++++--------- 1 file changed, 241 insertions(+), 240 deletions(-) diff --git a/WordPress/Sniffs/Variables/GlobalVariablesSniff.php b/WordPress/Sniffs/Variables/GlobalVariablesSniff.php index 6021644e..b71d3042 100644 --- a/WordPress/Sniffs/Variables/GlobalVariablesSniff.php +++ b/WordPress/Sniffs/Variables/GlobalVariablesSniff.php @@ -24,247 +24,248 @@ class WordPress_Sniffs_Variables_GlobalVariablesSniff extends WordPress_Sniff { * * @since 0.3.0 * @since 0.11.0 Changed visibility from public to protected. + * @since 0.12.0 Renamed from `$globals` to `$wp_globals` to be more descriptive. * * @var array */ - protected $globals = array( - 'comment', - 'comment_alt', - 'comment_depth', - 'comment_thread_alt', - 'wp_rewrite', - 'in_comment_loop', - 'wp_query', - 'withcomments', - 'post', - 'wpdb', - 'id', - 'user_login', - 'user_ID', - 'user_identity', - 'overridden_cpage', - 'wpcommentspopupfile', - 'wpcommentsjavascript', - 'shortcode_tags', - 'wp_version', - 'wp_scripts', - 'comments', - 'is_IE', - '_wp_registered_nav_menus', - '_menu_item_sort_prop', - 'wp_roles', - 'wp_object_cache', - 'currentcat', - 'previouscat', - 'blog_id', - 'is_macIE', - 'is_winIE', - 'plugin_page', - 'wp_themes', - 'wp_rich_edit_exists', - 'allowedposttags', - 'allowedtags', - 'allowedentitynames', - 'pass_allowed_html', - 'pass_allowed_protocols', - 'wp_post_statuses', - 'wp_post_types', - 'wp', - '_wp_post_type_features', - '_wp_suspend_cache_invalidation', - 'wp_theme_directories', - 'wp_locale', - 'locale', - 'l10n', - '_wp_additional_image_sizes', - 'wp_embed', - 'wp_taxonomies', - 'sidebars_widgets', - 'wp_registered_widgets', - 'wp_registered_widget_controls', - 'wp_registered_sidebars', - 'wp_registered_widget_updates', - '_wp_admin_css_colors', - 'concatenate_scripts', - 'compress_scripts', - 'wp_styles', - 'compress_css', - 'wp_the_query', - '_updated_user_settings', - 'wp_filter', - 'wp_actions', - 'merged_filters', - 'wp_current_filter', - 'wp_plugin_paths', - 'GETID3_ERRORARRAY', - 'current_user', - 'phpmailer', - 'is_IIS', - 'wp_hasher', - 'rnd_value', - 'auth_secure_cookie', - 'userdata', - 'user_level', - 'user_email', - 'user_url', - 'wp_customize', - 'wp_widget_factory', - '_wp_deprecated_widgets_callbacks', - '_wp_sidebars_widgets', - 'error', - 'wp_cockneyreplace', - 'wpsmiliestrans', - 'wp_smiliessearch', - '_links_add_base', - '_links_add_target', - 'tinymce_version', - 'PHP_SELF', - 'required_php_version', - 'upgrading', - 'timestart', - 'timeend', - 'table_prefix', - '_wp_using_ext_object_cache', - 'text_direction', - 'custom_image_header', - 'post_default_title', - 'post_default_category', - 'currentday', - 'previousday', - 'wp_header_to_desc', - 'wp_xmlrpc_server', - 'submenu', - 'is_apache', - 'is_iis7', - 'current_site', - 'domain', - 'm', - 'monthnum', - 'year', - 'posts', - 'previousweekday', - 'wp_rich_edit', - 'is_gecko', - 'is_opera', - 'is_safari', - 'is_chrome', - 'wp_local_package', - 'wp_user_roles', - 'super_admins', - '_wp_default_headers', - 'editor_styles', - '_wp_theme_features', - 'custom_background', - 'wp_did_header', - 'wp_admin_bar', - 'tag', - 'show_admin_bar', - 'pagenow', - 'HTTP_RAW_POST_DATA', - 'path', - 'wp_json', - 'page', - 'more', - 'preview', - 'pages', - 'multipage', - 'numpages', - 'paged', - 'authordata', - 'currentmonth', - 'EZSQL_ERROR', - 'required_mysql_version', - 'wp_db_version', - 'opml', - 'map', - 'updated_timestamp', - 'all_links', - 'names', - 'urls', - 'targets', - 'descriptions', - 'feeds', - 'wp_filesystem', - 'menu_order', - 'default_menu_order', - '_wp_nav_menu_max_depth', - '_nav_menu_placeholder', - 'wp_meta_boxes', - 'one_theme_location_no_menus', - 'nav_menu_selected_id', - 'post_ID', - 'link_id', - 'action', - 'link', - 'tabs', - 'tab', - 'type', - 'term', - 'redir_tab', - 'post_mime_types', - 'menu', - 'admin_page_hooks', - '_registered_pages', - '_parent_pages', - '_wp_last_object_menu', - '_wp_last_utility_menu', - '_wp_real_parent_file', - '_wp_submenu_nopriv', - 'parent_file', - 'typenow', - '_wp_menu_nopriv', - 'title', - 'new_whitelist_options', - 'whitelist_options', - 'wp_list_table', - 's', - 'mode', - 'post_type_object', - 'avail_post_stati', - 'per_page', - 'locked_post_status', - 'cat', - 'lost', - 'avail_post_mime_types', - 'errors', - 'cat_id', - 'orderby', - 'order', - 'post_type', - 'taxonomy', - 'tax', - 'wp_queries', - 'charset_collate', - 'wp_current_db_version', - 'wp_importers', - 'wp_file_descriptions', - 'theme_field_defaults', - 'themes_allowedtags', - 'post_id', - 'comment_status', - 'search', - 'comment_type', - 'wp_settings_sections', - 'wp_settings_fields', - 'wp_settings_errors', - 'hook_suffix', - 'admin_body_class', - 'current_screen', - 'taxnow', - 'status', - 'totals', - '_old_files', - '_new_bundled_files', - 'usersearch', - 'role', - 'wp_dashboard_control_callbacks', - 'plugins', - 'self', - 'submenu_file', - 'blogname', - 'blog_title', - 'active_signup', - 'interim_login', + protected $wp_globals = array( + '_links_add_base' => true, + '_links_add_target' => true, + '_menu_item_sort_prop' => true, + '_nav_menu_placeholder' => true, + '_new_bundled_files' => true, + '_old_files' => true, + '_parent_pages' => true, + '_registered_pages' => true, + '_updated_user_settings' => true, + '_wp_additional_image_sizes' => true, + '_wp_admin_css_colors' => true, + '_wp_default_headers' => true, + '_wp_deprecated_widgets_callbacks' => true, + '_wp_last_object_menu' => true, + '_wp_last_utility_menu' => true, + '_wp_menu_nopriv' => true, + '_wp_nav_menu_max_depth' => true, + '_wp_post_type_features' => true, + '_wp_real_parent_file' => true, + '_wp_registered_nav_menus' => true, + '_wp_sidebars_widgets' => true, + '_wp_submenu_nopriv' => true, + '_wp_suspend_cache_invalidation' => true, + '_wp_theme_features' => true, + '_wp_using_ext_object_cache' => true, + 'action' => true, + 'active_signup' => true, + 'admin_body_class' => true, + 'admin_page_hooks' => true, + 'all_links' => true, + 'allowedentitynames' => true, + 'allowedposttags' => true, + 'allowedtags' => true, + 'auth_secure_cookie' => true, + 'authordata' => true, + 'avail_post_mime_types' => true, + 'avail_post_stati' => true, + 'blog_id' => true, + 'blog_title' => true, + 'blogname' => true, + 'cat' => true, + 'cat_id' => true, + 'charset_collate' => true, + 'comment' => true, + 'comment_alt' => true, + 'comment_depth' => true, + 'comment_status' => true, + 'comment_thread_alt' => true, + 'comment_type' => true, + 'comments' => true, + 'compress_css' => true, + 'compress_scripts' => true, + 'concatenate_scripts' => true, + 'current_screen' => true, + 'current_site' => true, + 'current_user' => true, + 'currentcat' => true, + 'currentday' => true, + 'currentmonth' => true, + 'custom_background' => true, + 'custom_image_header' => true, + 'default_menu_order' => true, + 'descriptions' => true, + 'domain' => true, + 'editor_styles' => true, + 'error' => true, + 'errors' => true, + 'EZSQL_ERROR' => true, + 'feeds' => true, + 'GETID3_ERRORARRAY' => true, + 'hook_suffix' => true, + 'HTTP_RAW_POST_DATA' => true, + 'id' => true, + 'in_comment_loop' => true, + 'interim_login' => true, + 'is_apache' => true, + 'is_chrome' => true, + 'is_gecko' => true, + 'is_IE' => true, + 'is_IIS' => true, + 'is_iis7' => true, + 'is_macIE' => true, + 'is_opera' => true, + 'is_safari' => true, + 'is_winIE' => true, + 'l10n' => true, + 'link' => true, + 'link_id' => true, + 'locale' => true, + 'locked_post_status' => true, + 'lost' => true, + 'm' => true, + 'map' => true, + 'menu' => true, + 'menu_order' => true, + 'merged_filters' => true, + 'mode' => true, + 'monthnum' => true, + 'more' => true, + 'multipage' => true, + 'names' => true, + 'nav_menu_selected_id' => true, + 'new_whitelist_options' => true, + 'numpages' => true, + 'one_theme_location_no_menus' => true, + 'opml' => true, + 'order' => true, + 'orderby' => true, + 'overridden_cpage' => true, + 'page' => true, + 'paged' => true, + 'pagenow' => true, + 'pages' => true, + 'parent_file' => true, + 'pass_allowed_html' => true, + 'pass_allowed_protocols' => true, + 'path' => true, + 'per_page' => true, + 'PHP_SELF' => true, + 'phpmailer' => true, + 'plugin_page' => true, + 'plugins' => true, + 'post' => true, + 'post_default_category' => true, + 'post_default_title' => true, + 'post_ID' => true, + 'post_id' => true, + 'post_mime_types' => true, + 'post_type' => true, + 'post_type_object' => true, + 'posts' => true, + 'preview' => true, + 'previouscat' => true, + 'previousday' => true, + 'previousweekday' => true, + 'redir_tab' => true, + 'required_mysql_version' => true, + 'required_php_version' => true, + 'rnd_value' => true, + 'role' => true, + 's' => true, + 'search' => true, + 'self' => true, + 'shortcode_tags' => true, + 'show_admin_bar' => true, + 'sidebars_widgets' => true, + 'status' => true, + 'submenu' => true, + 'submenu_file' => true, + 'super_admins' => true, + 'tab' => true, + 'table_prefix' => true, + 'tabs' => true, + 'tag' => true, + 'targets' => true, + 'tax' => true, + 'taxnow' => true, + 'taxonomy' => true, + 'term' => true, + 'text_direction' => true, + 'theme_field_defaults' => true, + 'themes_allowedtags' => true, + 'timeend' => true, + 'timestart' => true, + 'tinymce_version' => true, + 'title' => true, + 'totals' => true, + 'type' => true, + 'typenow' => true, + 'updated_timestamp' => true, + 'upgrading' => true, + 'urls' => true, + 'user_email' => true, + 'user_ID' => true, + 'user_identity' => true, + 'user_level' => true, + 'user_login' => true, + 'user_url' => true, + 'userdata' => true, + 'usersearch' => true, + 'whitelist_options' => true, + 'withcomments' => true, + 'wp' => true, + 'wp_actions' => true, + 'wp_admin_bar' => true, + 'wp_cockneyreplace' => true, + 'wp_current_db_version' => true, + 'wp_current_filter' => true, + 'wp_customize' => true, + 'wp_dashboard_control_callbacks' => true, + 'wp_db_version' => true, + 'wp_did_header' => true, + 'wp_embed' => true, + 'wp_file_descriptions' => true, + 'wp_filesystem' => true, + 'wp_filter' => true, + 'wp_hasher' => true, + 'wp_header_to_desc' => true, + 'wp_importers' => true, + 'wp_json' => true, + 'wp_list_table' => true, + 'wp_local_package' => true, + 'wp_locale' => true, + 'wp_meta_boxes' => true, + 'wp_object_cache' => true, + 'wp_plugin_paths' => true, + 'wp_post_statuses' => true, + 'wp_post_types' => true, + 'wp_queries' => true, + 'wp_query' => true, + 'wp_registered_sidebars' => true, + 'wp_registered_widget_controls' => true, + 'wp_registered_widget_updates' => true, + 'wp_registered_widgets' => true, + 'wp_rewrite' => true, + 'wp_rich_edit' => true, + 'wp_rich_edit_exists' => true, + 'wp_roles' => true, + 'wp_scripts' => true, + 'wp_settings_errors' => true, + 'wp_settings_fields' => true, + 'wp_settings_sections' => true, + 'wp_smiliessearch' => true, + 'wp_styles' => true, + 'wp_taxonomies' => true, + 'wp_the_query' => true, + 'wp_theme_directories' => true, + 'wp_themes' => true, + 'wp_user_roles' => true, + 'wp_version' => true, + 'wp_widget_factory' => true, + 'wp_xmlrpc_server' => true, + 'wpcommentsjavascript' => true, + 'wpcommentspopupfile' => true, + 'wpdb' => true, + 'wpsmiliestrans' => true, + 'year' => true, ); /** @@ -311,7 +312,7 @@ public function process_token( $stackPtr ) { } } - if ( ! in_array( $var_name, $this->globals, true ) ) { + if ( ! isset( $this->wp_globals[ $var_name ] ) ) { return; } @@ -334,7 +335,7 @@ public function process_token( $stackPtr ) { } if ( T_VARIABLE === $var['code'] ) { - if ( in_array( substr( $var['content'], 1 ), $this->globals, true ) ) { + if ( isset( $this->wp_globals[ substr( $var['content'], 1 ) ] ) ) { $search[] = $var['content']; } } From 552e2f1957a728c6046d0fbd3b959fac60c48e84 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 1 Apr 2017 10:26:17 +0200 Subject: [PATCH 006/282] Move & improve two namespace related utility methods. * Move the namespace determination methods to the `WordPress_Sniff` class. * Port in improvements to these methods which have since been made to them (by me) in the PHPCompatibility standard. --- WordPress/AbstractClassRestrictionsSniff.php | 43 ------- WordPress/Sniff.php | 116 +++++++++++++++++++ 2 files changed, 116 insertions(+), 43 deletions(-) diff --git a/WordPress/AbstractClassRestrictionsSniff.php b/WordPress/AbstractClassRestrictionsSniff.php index 8ef5d8b7..f568d5bd 100644 --- a/WordPress/AbstractClassRestrictionsSniff.php +++ b/WordPress/AbstractClassRestrictionsSniff.php @@ -232,47 +232,4 @@ protected function get_namespaced_classname( $classname, $search_from ) { return $classname; } - /** - * Determine the namespace name based on whether this is a scoped namespace or a file namespace. - * - * @param int $search_from The token position to search up from. - * @return string Namespace name or empty string if it couldn't be determined or no namespace applied. - */ - protected function determine_namespace( $search_from ) { - $namespace = ''; - - if ( ! empty( $this->tokens[ $search_from ]['conditions'] ) ) { - // Scoped namespace {}. - foreach ( $this->tokens[ $search_from ]['conditions'] as $pointer => $type ) { - if ( T_NAMESPACE === $type && $this->tokens[ $pointer ]['scope_closer'] > $search_from ) { - $namespace = $this->get_namespace_name( $pointer ); - } - break; // We only need to check the highest level condition. - } - } else { - // Let's see if we can find a file namespace instead. - $first = $this->phpcsFile->findNext( T_NAMESPACE, 0, $search_from ); - - if ( false !== $first && empty( $this->tokens[ $first ]['scope_condition'] ) ) { - $namespace = $this->get_namespace_name( $first ); - } - } - - return $namespace; - } - - /** - * Get the namespace name based on the position of the namespace scope opener. - * - * @param int $namespace_token The token position to search from. - * @return string Namespace name. - */ - protected function get_namespace_name( $namespace_token ) { - $nameEnd = ( $this->phpcsFile->findNext( array( T_OPEN_CURLY_BRACKET, T_WHITESPACE, T_SEMICOLON ), ( $namespace_token + 2 ) ) - 1 ); - $length = ( $nameEnd - ( $namespace_token + 1 ) ); - $namespace = $this->phpcsFile->getTokensAsString( ( $namespace_token + 2 ), $length ); - - return $namespace; - } - } // End class. diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index cf0ca498..db579fe9 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -1754,6 +1754,122 @@ public function get_function_call_parameter( $stackPtr, $param_offset ) { return $parameters[ $param_offset ]; } + /** + * Determine the namespace name an arbitrary token lives in. + * + * @since 0.10.0 + * @since 0.12.0 Moved from the WordPress_AbstractClassRestrictionsSniff to this sniff. + * + * @param int $stackPtr The token position for which to determine the namespace. + * + * @return string Namespace name or empty string if it couldn't be determined or no namespace applies. + */ + public function determine_namespace( $stackPtr ) { + + // Check for the existence of the token. + if ( ! isset( $this->tokens[ $stackPtr ] ) ) { + return ''; + } + + // Check for scoped namespace {}. + if ( ! empty( $this->tokens[ $stackPtr ]['conditions'] ) ) { + $namespacePtr = $this->phpcsFile->getCondition( $stackPtr, T_NAMESPACE ); + if ( false !== $namespacePtr ) { + $namespace = $this->get_declared_namespace_name( $namespacePtr ); + if ( false !== $namespace ) { + return $namespace; + } + + // We are in a scoped namespace, but couldn't determine the name. + // Searching for a global namespace is futile. + return ''; + } + } + + /* + * Not in a scoped namespace, so let's see if we can find a non-scoped namespace instead. + * Keeping in mind that: + * - there can be multiple non-scoped namespaces in a file (bad practice, but it happens). + * - the namespace keyword can also be used as part of a function/method call and such. + * - that a non-named namespace resolves to the global namespace. + */ + $previousNSToken = $stackPtr; + $namespace = false; + do { + $previousNSToken = $this->phpcsFile->findPrevious( T_NAMESPACE, ( $previousNSToken - 1 ) ); + + // Stop if we encounter a scoped namespace declaration as we already know we're not in one. + if ( ! empty( $this->tokens[ $previousNSToken ]['scope_condition'] ) + && $this->tokens[ $previousNSToken ]['scope_condition'] === $previousNSToken + ) { + break; + } + + $namespace = $this->get_declared_namespace_name( $previousNSToken ); + + } while ( false === $namespace && false !== $previousNSToken ); + + // If we still haven't got a namespace, return an empty string. + if ( false === $namespace ) { + return ''; + } + + return $namespace; + } + + /** + * Get the complete namespace name for a namespace declaration. + * + * For hierarchical namespaces, the name will be composed of several tokens, + * i.e. MyProject\Sub\Level which will be returned together as one string. + * + * @since 0.12.0 A lesser variant of this method previously existed in the + * WordPress_AbstractClassRestrictionsSniff. + * + * @param int|bool $stackPtr The position of a T_NAMESPACE token. + * + * @return string|false Namespace name or false if not a namespace declaration. + * Namespace name can be an empty string for global namespace declaration. + */ + public function get_declared_namespace_name( $stackPtr ) { + + // Check for the existence of the token. + if ( false === $stackPtr || ! isset( $this->tokens[ $stackPtr ] ) ) { + return false; + } + + if ( T_NAMESPACE !== $this->tokens[ $stackPtr ]['code'] ) { + return false; + } + + if ( T_NS_SEPARATOR === $this->tokens[ ( $stackPtr + 1 ) ]['code'] ) { + // Not a namespace declaration, but use of, i.e. `namespace\someFunction();`. + return false; + } + + $nextToken = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true, null, true ); + if ( T_OPEN_CURLY_BRACKET === $this->tokens[ $nextToken ]['code'] ) { + // Declaration for global namespace when using multiple namespaces in a file. + // I.e.: `namespace {}`. + return ''; + } + + // Ok, this should be a namespace declaration, so get all the parts together. + $validTokens = array( + T_STRING => true, + T_NS_SEPARATOR => true, + T_WHITESPACE => true, + ); + + $namespaceName = ''; + while ( isset( $validTokens[ $this->tokens[ $nextToken ]['code'] ] ) ) { + $namespaceName .= trim( $this->tokens[ $nextToken ]['content'] ); + $nextToken++; + } + + return $namespaceName; + } + /** * Check if a content string contains a specific html open tag. * From e76bc905436f20dc50482c91f4ac789173357777 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 1 Apr 2017 21:08:01 +0200 Subject: [PATCH 007/282] :books: Document the list style used for properties in the `WordPress_Sniff`. --- WordPress/Sniff.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index cf0ca498..d8c9e461 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -14,6 +14,17 @@ * * @package WPCS\WordPressCodingStandards * @since 0.4.0 + * + * {@internal This class contains numerous properties where the array format looks + * like `'string' => true`, i.e. the array item is set as the array key. + * This allows for sniffs to verify whether something is in one of these + * lists using `isset()` rather than `in_array()` which is a much more + * efficient (faster) check to execute and therefore improves the + * performance of the sniffs. + * The `true` value in those cases is used as a placeholder and has no + * meaning in and of itself. + * In the rare few cases where the array values *do* have meaning, this + * is documented in the property documentation.}} */ abstract class WordPress_Sniff implements PHP_CodeSniffer_Sniff { From 6569fb35c8b932f3407b15ee838c032e73b130f3 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 1 Apr 2017 04:14:33 +0200 Subject: [PATCH 008/282] Move the `$wp_globals` property to the WordPress_Sniff class. --- WordPress/Sniff.php | 250 +++++++++++++++++ .../Sniffs/Variables/GlobalVariablesSniff.php | 252 +----------------- 2 files changed, 252 insertions(+), 250 deletions(-) diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index d00e727e..b388ea9f 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -488,6 +488,256 @@ abstract class WordPress_Sniff implements PHP_CodeSniffer_Sniff { 'current_filter' => 0, // No hook name argument. ); + /** + * List of global WP variables. + * + * @since 0.3.0 + * @since 0.11.0 Changed visibility from public to protected. + * @since 0.12.0 Renamed from `$globals` to `$wp_globals` to be more descriptive. + * @since 0.12.0 Moved from WordPress_Sniffs_Variables_GlobalVariablesSniff to WordPress_Sniff + * + * @var array + */ + protected $wp_globals = array( + '_links_add_base' => true, + '_links_add_target' => true, + '_menu_item_sort_prop' => true, + '_nav_menu_placeholder' => true, + '_new_bundled_files' => true, + '_old_files' => true, + '_parent_pages' => true, + '_registered_pages' => true, + '_updated_user_settings' => true, + '_wp_additional_image_sizes' => true, + '_wp_admin_css_colors' => true, + '_wp_default_headers' => true, + '_wp_deprecated_widgets_callbacks' => true, + '_wp_last_object_menu' => true, + '_wp_last_utility_menu' => true, + '_wp_menu_nopriv' => true, + '_wp_nav_menu_max_depth' => true, + '_wp_post_type_features' => true, + '_wp_real_parent_file' => true, + '_wp_registered_nav_menus' => true, + '_wp_sidebars_widgets' => true, + '_wp_submenu_nopriv' => true, + '_wp_suspend_cache_invalidation' => true, + '_wp_theme_features' => true, + '_wp_using_ext_object_cache' => true, + 'action' => true, + 'active_signup' => true, + 'admin_body_class' => true, + 'admin_page_hooks' => true, + 'all_links' => true, + 'allowedentitynames' => true, + 'allowedposttags' => true, + 'allowedtags' => true, + 'auth_secure_cookie' => true, + 'authordata' => true, + 'avail_post_mime_types' => true, + 'avail_post_stati' => true, + 'blog_id' => true, + 'blog_title' => true, + 'blogname' => true, + 'cat' => true, + 'cat_id' => true, + 'charset_collate' => true, + 'comment' => true, + 'comment_alt' => true, + 'comment_depth' => true, + 'comment_status' => true, + 'comment_thread_alt' => true, + 'comment_type' => true, + 'comments' => true, + 'compress_css' => true, + 'compress_scripts' => true, + 'concatenate_scripts' => true, + 'current_screen' => true, + 'current_site' => true, + 'current_user' => true, + 'currentcat' => true, + 'currentday' => true, + 'currentmonth' => true, + 'custom_background' => true, + 'custom_image_header' => true, + 'default_menu_order' => true, + 'descriptions' => true, + 'domain' => true, + 'editor_styles' => true, + 'error' => true, + 'errors' => true, + 'EZSQL_ERROR' => true, + 'feeds' => true, + 'GETID3_ERRORARRAY' => true, + 'hook_suffix' => true, + 'HTTP_RAW_POST_DATA' => true, + 'id' => true, + 'in_comment_loop' => true, + 'interim_login' => true, + 'is_apache' => true, + 'is_chrome' => true, + 'is_gecko' => true, + 'is_IE' => true, + 'is_IIS' => true, + 'is_iis7' => true, + 'is_macIE' => true, + 'is_opera' => true, + 'is_safari' => true, + 'is_winIE' => true, + 'l10n' => true, + 'link' => true, + 'link_id' => true, + 'locale' => true, + 'locked_post_status' => true, + 'lost' => true, + 'm' => true, + 'map' => true, + 'menu' => true, + 'menu_order' => true, + 'merged_filters' => true, + 'mode' => true, + 'monthnum' => true, + 'more' => true, + 'multipage' => true, + 'names' => true, + 'nav_menu_selected_id' => true, + 'new_whitelist_options' => true, + 'numpages' => true, + 'one_theme_location_no_menus' => true, + 'opml' => true, + 'order' => true, + 'orderby' => true, + 'overridden_cpage' => true, + 'page' => true, + 'paged' => true, + 'pagenow' => true, + 'pages' => true, + 'parent_file' => true, + 'pass_allowed_html' => true, + 'pass_allowed_protocols' => true, + 'path' => true, + 'per_page' => true, + 'PHP_SELF' => true, + 'phpmailer' => true, + 'plugin_page' => true, + 'plugins' => true, + 'post' => true, + 'post_default_category' => true, + 'post_default_title' => true, + 'post_ID' => true, + 'post_id' => true, + 'post_mime_types' => true, + 'post_type' => true, + 'post_type_object' => true, + 'posts' => true, + 'preview' => true, + 'previouscat' => true, + 'previousday' => true, + 'previousweekday' => true, + 'redir_tab' => true, + 'required_mysql_version' => true, + 'required_php_version' => true, + 'rnd_value' => true, + 'role' => true, + 's' => true, + 'search' => true, + 'self' => true, + 'shortcode_tags' => true, + 'show_admin_bar' => true, + 'sidebars_widgets' => true, + 'status' => true, + 'submenu' => true, + 'submenu_file' => true, + 'super_admins' => true, + 'tab' => true, + 'table_prefix' => true, + 'tabs' => true, + 'tag' => true, + 'targets' => true, + 'tax' => true, + 'taxnow' => true, + 'taxonomy' => true, + 'term' => true, + 'text_direction' => true, + 'theme_field_defaults' => true, + 'themes_allowedtags' => true, + 'timeend' => true, + 'timestart' => true, + 'tinymce_version' => true, + 'title' => true, + 'totals' => true, + 'type' => true, + 'typenow' => true, + 'updated_timestamp' => true, + 'upgrading' => true, + 'urls' => true, + 'user_email' => true, + 'user_ID' => true, + 'user_identity' => true, + 'user_level' => true, + 'user_login' => true, + 'user_url' => true, + 'userdata' => true, + 'usersearch' => true, + 'whitelist_options' => true, + 'withcomments' => true, + 'wp' => true, + 'wp_actions' => true, + 'wp_admin_bar' => true, + 'wp_cockneyreplace' => true, + 'wp_current_db_version' => true, + 'wp_current_filter' => true, + 'wp_customize' => true, + 'wp_dashboard_control_callbacks' => true, + 'wp_db_version' => true, + 'wp_did_header' => true, + 'wp_embed' => true, + 'wp_file_descriptions' => true, + 'wp_filesystem' => true, + 'wp_filter' => true, + 'wp_hasher' => true, + 'wp_header_to_desc' => true, + 'wp_importers' => true, + 'wp_json' => true, + 'wp_list_table' => true, + 'wp_local_package' => true, + 'wp_locale' => true, + 'wp_meta_boxes' => true, + 'wp_object_cache' => true, + 'wp_plugin_paths' => true, + 'wp_post_statuses' => true, + 'wp_post_types' => true, + 'wp_queries' => true, + 'wp_query' => true, + 'wp_registered_sidebars' => true, + 'wp_registered_widget_controls' => true, + 'wp_registered_widget_updates' => true, + 'wp_registered_widgets' => true, + 'wp_rewrite' => true, + 'wp_rich_edit' => true, + 'wp_rich_edit_exists' => true, + 'wp_roles' => true, + 'wp_scripts' => true, + 'wp_settings_errors' => true, + 'wp_settings_fields' => true, + 'wp_settings_sections' => true, + 'wp_smiliessearch' => true, + 'wp_styles' => true, + 'wp_taxonomies' => true, + 'wp_the_query' => true, + 'wp_theme_directories' => true, + 'wp_themes' => true, + 'wp_user_roles' => true, + 'wp_version' => true, + 'wp_widget_factory' => true, + 'wp_xmlrpc_server' => true, + 'wpcommentsjavascript' => true, + 'wpcommentspopupfile' => true, + 'wpdb' => true, + 'wpsmiliestrans' => true, + 'year' => true, + ); + /** * Whitelist of classes which test classes can extend. * diff --git a/WordPress/Sniffs/Variables/GlobalVariablesSniff.php b/WordPress/Sniffs/Variables/GlobalVariablesSniff.php index 324c4059..4b710a1e 100644 --- a/WordPress/Sniffs/Variables/GlobalVariablesSniff.php +++ b/WordPress/Sniffs/Variables/GlobalVariablesSniff.php @@ -15,261 +15,13 @@ * @package WPCS\WordPressCodingStandards * * @since 0.3.0 - * @since 0.4.0 This class now extends WordPress_Sniff. + * @since 0.4.0 This class now extends WordPress_Sniff. + * @since 0.12.0 The $wp_globals property has been moved to the WordPress_Sniff. * * @uses WordPress_Sniff::$custom_test_class_whitelist */ class WordPress_Sniffs_Variables_GlobalVariablesSniff extends WordPress_Sniff { - /** - * List of global WP variables. - * - * @since 0.3.0 - * @since 0.11.0 Changed visibility from public to protected. - * @since 0.12.0 Renamed from `$globals` to `$wp_globals` to be more descriptive. - * - * @var array - */ - protected $wp_globals = array( - '_links_add_base' => true, - '_links_add_target' => true, - '_menu_item_sort_prop' => true, - '_nav_menu_placeholder' => true, - '_new_bundled_files' => true, - '_old_files' => true, - '_parent_pages' => true, - '_registered_pages' => true, - '_updated_user_settings' => true, - '_wp_additional_image_sizes' => true, - '_wp_admin_css_colors' => true, - '_wp_default_headers' => true, - '_wp_deprecated_widgets_callbacks' => true, - '_wp_last_object_menu' => true, - '_wp_last_utility_menu' => true, - '_wp_menu_nopriv' => true, - '_wp_nav_menu_max_depth' => true, - '_wp_post_type_features' => true, - '_wp_real_parent_file' => true, - '_wp_registered_nav_menus' => true, - '_wp_sidebars_widgets' => true, - '_wp_submenu_nopriv' => true, - '_wp_suspend_cache_invalidation' => true, - '_wp_theme_features' => true, - '_wp_using_ext_object_cache' => true, - 'action' => true, - 'active_signup' => true, - 'admin_body_class' => true, - 'admin_page_hooks' => true, - 'all_links' => true, - 'allowedentitynames' => true, - 'allowedposttags' => true, - 'allowedtags' => true, - 'auth_secure_cookie' => true, - 'authordata' => true, - 'avail_post_mime_types' => true, - 'avail_post_stati' => true, - 'blog_id' => true, - 'blog_title' => true, - 'blogname' => true, - 'cat' => true, - 'cat_id' => true, - 'charset_collate' => true, - 'comment' => true, - 'comment_alt' => true, - 'comment_depth' => true, - 'comment_status' => true, - 'comment_thread_alt' => true, - 'comment_type' => true, - 'comments' => true, - 'compress_css' => true, - 'compress_scripts' => true, - 'concatenate_scripts' => true, - 'current_screen' => true, - 'current_site' => true, - 'current_user' => true, - 'currentcat' => true, - 'currentday' => true, - 'currentmonth' => true, - 'custom_background' => true, - 'custom_image_header' => true, - 'default_menu_order' => true, - 'descriptions' => true, - 'domain' => true, - 'editor_styles' => true, - 'error' => true, - 'errors' => true, - 'EZSQL_ERROR' => true, - 'feeds' => true, - 'GETID3_ERRORARRAY' => true, - 'hook_suffix' => true, - 'HTTP_RAW_POST_DATA' => true, - 'id' => true, - 'in_comment_loop' => true, - 'interim_login' => true, - 'is_apache' => true, - 'is_chrome' => true, - 'is_gecko' => true, - 'is_IE' => true, - 'is_IIS' => true, - 'is_iis7' => true, - 'is_macIE' => true, - 'is_opera' => true, - 'is_safari' => true, - 'is_winIE' => true, - 'l10n' => true, - 'link' => true, - 'link_id' => true, - 'locale' => true, - 'locked_post_status' => true, - 'lost' => true, - 'm' => true, - 'map' => true, - 'menu' => true, - 'menu_order' => true, - 'merged_filters' => true, - 'mode' => true, - 'monthnum' => true, - 'more' => true, - 'multipage' => true, - 'names' => true, - 'nav_menu_selected_id' => true, - 'new_whitelist_options' => true, - 'numpages' => true, - 'one_theme_location_no_menus' => true, - 'opml' => true, - 'order' => true, - 'orderby' => true, - 'overridden_cpage' => true, - 'page' => true, - 'paged' => true, - 'pagenow' => true, - 'pages' => true, - 'parent_file' => true, - 'pass_allowed_html' => true, - 'pass_allowed_protocols' => true, - 'path' => true, - 'per_page' => true, - 'PHP_SELF' => true, - 'phpmailer' => true, - 'plugin_page' => true, - 'plugins' => true, - 'post' => true, - 'post_default_category' => true, - 'post_default_title' => true, - 'post_ID' => true, - 'post_id' => true, - 'post_mime_types' => true, - 'post_type' => true, - 'post_type_object' => true, - 'posts' => true, - 'preview' => true, - 'previouscat' => true, - 'previousday' => true, - 'previousweekday' => true, - 'redir_tab' => true, - 'required_mysql_version' => true, - 'required_php_version' => true, - 'rnd_value' => true, - 'role' => true, - 's' => true, - 'search' => true, - 'self' => true, - 'shortcode_tags' => true, - 'show_admin_bar' => true, - 'sidebars_widgets' => true, - 'status' => true, - 'submenu' => true, - 'submenu_file' => true, - 'super_admins' => true, - 'tab' => true, - 'table_prefix' => true, - 'tabs' => true, - 'tag' => true, - 'targets' => true, - 'tax' => true, - 'taxnow' => true, - 'taxonomy' => true, - 'term' => true, - 'text_direction' => true, - 'theme_field_defaults' => true, - 'themes_allowedtags' => true, - 'timeend' => true, - 'timestart' => true, - 'tinymce_version' => true, - 'title' => true, - 'totals' => true, - 'type' => true, - 'typenow' => true, - 'updated_timestamp' => true, - 'upgrading' => true, - 'urls' => true, - 'user_email' => true, - 'user_ID' => true, - 'user_identity' => true, - 'user_level' => true, - 'user_login' => true, - 'user_url' => true, - 'userdata' => true, - 'usersearch' => true, - 'whitelist_options' => true, - 'withcomments' => true, - 'wp' => true, - 'wp_actions' => true, - 'wp_admin_bar' => true, - 'wp_cockneyreplace' => true, - 'wp_current_db_version' => true, - 'wp_current_filter' => true, - 'wp_customize' => true, - 'wp_dashboard_control_callbacks' => true, - 'wp_db_version' => true, - 'wp_did_header' => true, - 'wp_embed' => true, - 'wp_file_descriptions' => true, - 'wp_filesystem' => true, - 'wp_filter' => true, - 'wp_hasher' => true, - 'wp_header_to_desc' => true, - 'wp_importers' => true, - 'wp_json' => true, - 'wp_list_table' => true, - 'wp_local_package' => true, - 'wp_locale' => true, - 'wp_meta_boxes' => true, - 'wp_object_cache' => true, - 'wp_plugin_paths' => true, - 'wp_post_statuses' => true, - 'wp_post_types' => true, - 'wp_queries' => true, - 'wp_query' => true, - 'wp_registered_sidebars' => true, - 'wp_registered_widget_controls' => true, - 'wp_registered_widget_updates' => true, - 'wp_registered_widgets' => true, - 'wp_rewrite' => true, - 'wp_rich_edit' => true, - 'wp_rich_edit_exists' => true, - 'wp_roles' => true, - 'wp_scripts' => true, - 'wp_settings_errors' => true, - 'wp_settings_fields' => true, - 'wp_settings_sections' => true, - 'wp_smiliessearch' => true, - 'wp_styles' => true, - 'wp_taxonomies' => true, - 'wp_the_query' => true, - 'wp_theme_directories' => true, - 'wp_themes' => true, - 'wp_user_roles' => true, - 'wp_version' => true, - 'wp_widget_factory' => true, - 'wp_xmlrpc_server' => true, - 'wpcommentsjavascript' => true, - 'wpcommentspopupfile' => true, - 'wpdb' => true, - 'wpsmiliestrans' => true, - 'year' => true, - ); - /** * Returns an array of tokens this test wants to listen for. * From b5286d4a74679e440b0930b9826901ac9d515c9f Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 1 Apr 2017 04:15:19 +0200 Subject: [PATCH 009/282] WordPress_Sniff: Move the $input_superglobals property up to a more logical place. --- WordPress/Sniff.php | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index b388ea9f..75d81417 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -738,6 +738,23 @@ abstract class WordPress_Sniff implements PHP_CodeSniffer_Sniff { 'year' => true, ); + /** + * A list of superglobals that incorporate user input. + * + * @since 0.5.0 + * @since 0.11.0 Changed from static to non-static. + * + * @var string[] + */ + protected $input_superglobals = array( + '$_COOKIE', + '$_GET', + '$_FILES', + '$_POST', + '$_REQUEST', + '$_SERVER', + ); + /** * Whitelist of classes which test classes can extend. * @@ -791,23 +808,6 @@ abstract class WordPress_Sniff implements PHP_CodeSniffer_Sniff { */ protected $tokens; - /** - * A list of superglobals that incorporate user input. - * - * @since 0.5.0 - * @since 0.11.0 Changed from static to non-static. - * - * @var string[] - */ - protected $input_superglobals = array( - '$_COOKIE', - '$_GET', - '$_FILES', - '$_POST', - '$_REQUEST', - '$_SERVER', - ); - /** * Set sniff properties and hand off to child class for processing of the token. * From c02c350a671765cf734653b2d588644f073c6a23 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Mon, 3 Apr 2017 20:29:58 +0200 Subject: [PATCH 010/282] :sparkles: New sniff to verify that everything in the global namespace is prefixed. **Important**: This sniff will not do anything **unless** the `prefixes` property has been added to the custom ruleset or provided via the command line. This new sniff intends to verify that all functions, classes, interfaces, traits, variables, constants and hook names which are declared/defined in the global namespace are prefixed with one of the `prefixes` provided via a custom property or via the command line. Prefixing is best practice to prevent naming collisions what with there being so many plugins and themes out there in the wider WordPress arena. The sniff has been added to the `WordPress-Extra` ruleset. This sniff has the following features: * Allows for more than one prefix to be set as some plugins/themes use libraries and those may use their own prefix. * It will validate the passed prefixes against the PHP naming rule for characters allowed to be used. * It will throw an error if someone tries to use `wp` or `_` as a prefix. This list can be extended with other prefixes which should not be used. * Prefix vs _name_ comparisons are always done in a case-insensitive manner as the typical case for variables (lowercase), constants (uppercase), class names (Camelcase), function names (lowercase) are all different. * It is allowed to have a _name_ which is just and only the prefix. * If the _name_ is used as a prefix, it is expected to be separated from the rest of the _name_ by an underscore `_` * There are some valid use-cases for using non-prefixed _names_. Such as back-fills for PHP functions later introduced, calling a WP core hook etc. To this end, use of non-prefixed _names_ can be whitelisted via a whitelist comment. For some examples of use-cases, see the unit test file. * Anything in classes extending known unit test classes is exempted from this sniff as this is, generally speaking, code which will not be executed during a WP run and therefore will not cause conflicts. Additional unit test classes can be whitelisted using the `custom_test_class_whitelist` property. * The PHP superglobals and all known WP globals are whitelisted from prefixing of the variable name. * Hook names clearly indicated as deprecated through usage of the `do_action_deprecated()` or `apply_filters_deprecated()` functions will be disregarded. * Anything outside of the global namespace will be disregarded by this sniff. Includes extensive unit tests. --- WordPress-Extra/ruleset.xml | 3 + WordPress/Sniff.php | 4 +- .../PrefixAllGlobalsSniff.php | 524 ++++++++++++++++++ .../PrefixAllGlobalsUnitTest.1.inc | 15 + .../PrefixAllGlobalsUnitTest.inc | 201 +++++++ .../PrefixAllGlobalsUnitTest.php | 83 +++ 6 files changed, 828 insertions(+), 2 deletions(-) create mode 100644 WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php create mode 100644 WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.1.inc create mode 100644 WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc create mode 100644 WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php diff --git a/WordPress-Extra/ruleset.xml b/WordPress-Extra/ruleset.xml index d82b8631..53886e0a 100644 --- a/WordPress-Extra/ruleset.xml +++ b/WordPress-Extra/ruleset.xml @@ -97,5 +97,8 @@ error + + + diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index 75d81417..2a13194d 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -774,8 +774,8 @@ abstract class WordPress_Sniff implements PHP_CodeSniffer_Sniff { * This property allows end-users to add to the $test_class_whitelist via their ruleset. * This property will need to be set for each sniff which uses the * `is_test_class()` method. - * Currently the method is used by the `WordPress.Variables.GlobalVariables` - * and the `WordPress.Files.Filename` sniffs. + * Currently the method is used by the `WordPress.Variables.GlobalVariables`, + * `WordPress.NamingConventions.PrefixAllGlobals` and the `WordPress.Files.Filename` sniffs. * * Example usage: * diff --git a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php new file mode 100644 index 00000000..ab1f0081 --- /dev/null +++ b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php @@ -0,0 +1,524 @@ + true, + '_' => true, + ); + + /** + * Target prefixes after validation. + * + * @since 0.12.0 + * + * @var string[] + */ + private $validated_prefixes = array(); + + /** + * Cache of previously set prefixes. + * + * Prevents having to do the same prefix validation over and over again. + * + * @since 0.12.0 + * + * @var string[] + */ + private $previous_prefixes = array(); + + /** + * A list of all PHP superglobals with the exception of $GLOBALS which is handled separately. + * + * @since 0.12.0 + * + * @var array + */ + protected $superglobals = array( + '_COOKIE' => true, + '_ENV' => true, + '_GET' => true, + '_FILES' => true, + '_POST' => true, + '_REQUEST' => true, + '_SERVER' => true, + '_SESSION' => true, + ); + + /** + * Returns an array of tokens this test wants to listen for. + * + * @since 0.12.0 + * + * @return array + */ + public function register() { + $targets = array( + T_FUNCTION => T_FUNCTION, + T_CLASS => T_CLASS, + T_INTERFACE => T_INTERFACE, + T_TRAIT => T_TRAIT, + T_CONST => T_CONST, + T_VARIABLE => T_VARIABLE, + ); + + // Add function call target for hook names and constants defined using define(). + $parent = parent::register(); + if ( ! empty( $parent ) ) { + $targets[] = T_STRING; + } + + return $targets; + } + + /** + * Groups of functions to restrict. + * + * @since 0.12.0 + * + * @return array + */ + public function getGroups() { + $this->target_functions = $this->hookInvokeFunctions; + $this->target_functions['define'] = true; + + return parent::getGroups(); + } + + /** + * Processes this test, when one of its tokens is encountered. + * + * @since 0.12.0 + * + * @param int $stackPtr The position of the current token in the stack. + * + * @return int|void Integer stack pointer to skip forward or void to continue + * normal file processing. + */ + public function process_token( $stackPtr ) { + /* + * Allow for whitelisting. + * + * Generally speaking a theme/plugin should *only* execute their own hooks, but there may be a + * good reason to execute a core hook. + * + * Similarly, newer PHP or WP functions or constants may need to be emulated for continued support + * of older PHP and WP versions. + */ + if ( $this->has_whitelist_comment( 'prefix', $stackPtr ) ) { + return; + } + + // Allow overruling the prefixes set in a ruleset via the command line. + $cl_prefixes = trim( PHP_CodeSniffer::getConfigData( 'prefixes' ) ); + if ( ! empty( $cl_prefixes ) ) { + $this->prefixes = $cl_prefixes; + } + + $this->prefixes = $this->merge_custom_array( $this->prefixes, array(), false ); + if ( empty( $this->prefixes ) ) { + // No prefixes passed, nothing to do. + return; + } + + $this->validate_prefixes(); + if ( empty( $this->validated_prefixes ) ) { + // No _valid_ prefixes passed, nothing to do. + return; + } + + if ( T_STRING === $this->tokens[ $stackPtr ]['code'] ) { + // Disallow excluding function groups for this sniff. + $this->exclude = ''; + + return parent::process_token( $stackPtr ); + + } elseif ( T_VARIABLE === $this->tokens[ $stackPtr ]['code'] ) { + + return $this->process_variable_assignment( $stackPtr ); + + } else { + + // Namespaced methods, classes and constants do not need to be prefixed. + $namespace = $this->determine_namespace( $stackPtr ); + if ( '' !== $namespace && '\\' !== $namespace ) { + return; + } + + $item_name = ''; + $error_text = 'Unknown syntax used by'; + $error_code = 'NonPrefixedSyntaxFound'; + + switch ( $this->tokens[ $stackPtr ]['type'] ) { + case 'T_FUNCTION': + // Methods in a class do not need to be prefixed. + if ( $this->phpcsFile->hasCondition( $stackPtr, array( T_CLASS, T_ANON_CLASS, T_INTERFACE, T_TRAIT ) ) === true ) { + return; + } + + $item_name = $this->phpcsFile->getDeclarationName( $stackPtr ); + $error_text = 'Functions declared'; + $error_code = 'NonPrefixedFunctionFound'; + break; + + case 'T_CLASS': + case 'T_INTERFACE': + case 'T_TRAIT': + // Ignore test classes. + if ( true === $this->is_test_class( $stackPtr ) ) { + if ( $this->tokens[ $stackPtr ]['scope_condition'] === $stackPtr && isset( $this->tokens[ $stackPtr ]['scope_closer'] ) ) { + // Skip forward to end of test class. + return $this->tokens[ $stackPtr ]['scope_closer']; + } + return; + } + + $item_name = $this->phpcsFile->getDeclarationName( $stackPtr ); + $error_text = 'Classes declared'; + $error_code = 'NonPrefixedClassFound'; + break; + + case 'T_CONST': + // Constants in a class do not need to be prefixed. + if ( $this->phpcsFile->hasCondition( $stackPtr, array( T_CLASS, T_ANON_CLASS, T_INTERFACE, T_TRAIT ) ) === true ) { + return; + } + + $constant_name_ptr = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true, null, true ); + if ( false === $constant_name_ptr ) { + // Live coding. + return; + } + + $item_name = $this->tokens[ $constant_name_ptr ]['content']; + $error_text = 'Global constants defined'; + $error_code = 'NonPrefixedConstantFound'; + break; + + default: + // Left empty on purpose. + break; + + } // End switch(). + + if ( empty( $item_name ) || $this->is_prefixed( $item_name ) === true ) { + return; + } + + $this->phpcsFile->addError( + self::ERROR_MSG, + $stackPtr, + $error_code, + array( + $error_text, + $item_name, + ) + ); + } // End if(). + + } // End process_token(). + + /** + * Check that defined global variables are prefixed. + * + * @since 0.12.0 + * + * @param int $stackPtr The position of the current token in the stack. + * + * @return int|void Integer stack pointer to skip forward or void to continue + * normal file processing. + */ + protected function process_variable_assignment( $stackPtr ) { + + // We're only concerned with variables which are being defined. + if ( false === $this->is_assignment( $stackPtr ) ) { + return; + } + + $variable_name = substr( $this->tokens[ $stackPtr ]['content'], 1 ); // Strip the dollar sign. + + // Bow out early if we know for certain no prefix is needed. + if ( $this->variable_prefixed_or_whitelisted( $variable_name ) === true ) { + return; + } + + if ( 'GLOBALS' === $variable_name ) { + $array_open = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true, null, true ); + if ( false === $array_open || T_OPEN_SQUARE_BRACKET !== $this->tokens[ $array_open ]['code'] ) { + // Live coding or something very silly. + return; + } + + $array_key = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $array_open + 1 ), null, true, null, true ); + if ( false === $array_key || T_CONSTANT_ENCAPSED_STRING !== $this->tokens[ $array_key ]['code'] ) { + // Key is not a string, nothing to do. + return; + } + + $stackPtr = $array_key; + $variable_name = $this->strip_quotes( $this->tokens[ $array_key ]['content'] ); + + // Check whether a prefix is needed. + if ( $this->variable_prefixed_or_whitelisted( $variable_name ) === true ) { + return; + } + } else { + // Function parameters do not need to be prefixed. + if ( isset( $this->tokens[ $stackPtr ]['nested_parenthesis'] ) ) { + foreach ( $this->tokens[ $stackPtr ]['nested_parenthesis'] as $opener => $closer ) { + if ( isset( $this->tokens[ $opener ]['parenthesis_owner'] ) && T_FUNCTION === $this->tokens[ $this->tokens[ $opener ]['parenthesis_owner'] ]['code'] ) { + return; + } + } + unset( $opener, $closer ); + } + + // Properties in a class do not need to be prefixed. + $conditions = array_keys( $this->tokens[ $stackPtr ]['conditions'] ); + $ptr = array_pop( $conditions ); + if ( isset( $this->tokens[ $ptr ] ) + && in_array( $this->tokens[ $ptr ]['code'], array( T_CLASS, T_ANON_CLASS, T_TRAIT ), true ) + ) { + return; + } + + // Local variables in a function do not need to be prefixed unless they are being imported. + if ( $this->phpcsFile->hasCondition( $stackPtr, array( T_FUNCTION, T_CLOSURE ) ) === true ) { + $condition = $this->phpcsFile->getCondition( $stackPtr, T_FUNCTION ); + if ( false === $condition ) { + $condition = $this->phpcsFile->getCondition( $stackPtr, T_CLOSURE ); + } + + $has_global = $this->phpcsFile->findPrevious( T_GLOBAL, ( $stackPtr - 1 ), $this->tokens[ $condition ]['scope_opener'] ); + if ( false === $has_global ) { + // No variable import happening. + return; + } + + // Ok, this may be an imported global variable. + $end_of_statement = $this->phpcsFile->findNext( T_SEMICOLON, ( $has_global + 1 ) ); + if ( false === $end_of_statement ) { + // No semi-colon - live coding. + return; + } + + for ( $ptr = ( $has_global + 1 ); $ptr <= $end_of_statement; $ptr++ ) { + // Move the stack pointer to the next variable. + $ptr = $this->phpcsFile->findNext( T_VARIABLE, $ptr, $end_of_statement, false, null, true ); + + if ( false === $ptr ) { + // Reached the end of the global statement without finding the variable, + // so this must be a local variable. + return; + } + + if ( substr( $this->tokens[ $ptr ]['content'], 1 ) === $variable_name ) { + break; + } + } + + unset( $condition, $has_global, $end_of_statement, $ptr, $imported ); + + } // End if(). + } // End if(). + + // Still here ? In that case, the variable name should be prefixed. + $this->phpcsFile->addError( + self::ERROR_MSG, + $stackPtr, + 'NonPrefixedVariableFound', + array( + 'Variables defined', + $variable_name, + ) + ); + + } // End process_variable_assignment(). + + /** + * Process the parameters of a matched function. + * + * @since 0.12.0 + * + * @param int $stackPtr The position of the current token in the stack. + * @param array $group_name The name of the group which was matched. + * @param string $matched_content The token content (function name) which was matched. + * @param array $parameters Array with information about the parameters. + * + * @return void + */ + public function process_parameters( $stackPtr, $group_name, $matched_content, $parameters ) { + + // Ignore deprecated hook names. + if ( strpos( $matched_content, '_deprecated' ) > 0 ) { + return; + } + + // No matter whether it is a constant definition or a hook call, both use the first parameter. + if ( ! isset( $parameters[1] ) ) { + return; + } + + $raw_content = $this->strip_quotes( $parameters[1]['raw'] ); + + if ( $this->is_prefixed( $raw_content ) === true ) { + return; + } + + if ( 'define' === $matched_content ) { + $data = array( 'Global constants defined' ); + $error_code = 'NonPrefixedConstantFound'; + } else { + $data = array( 'Hook names invoked' ); + $error_code = 'NonPrefixedHooknameFound'; + } + + $data[] = $raw_content; + + $this->phpcsFile->addError( self::ERROR_MSG, $parameters[1]['start'], $error_code, $data ); + + } // End process_parameters(). + + /** + * Check if a function/class/constant/variable name is prefixed with one of the expected prefixes. + * + * @since 0.12.0 + * + * @param string $name Name to check for a prefix. + * + * @return bool True when the name is the prefix or starts with the prefix + an underscore. + * False otherwise. + */ + private function is_prefixed( $name ) { + + foreach ( $this->validated_prefixes as $prefix ) { + if ( strtolower( $name ) === $prefix ) { + // Ok, prefix *is* the hook/constant name. + return true; + + } else { + $prefix_found = stripos( $name, $prefix . '_' ); + + if ( 0 === $prefix_found ) { + // Ok, prefix found as start of hook/constant name. + return true; + } + } + } + + return false; + } + + /** + * Check if a variable name might need a prefix. + * + * Prefix is not needed for: + * - superglobals, + * - WP native globals, + * - variables which are already prefixed. + * + * @param string $name Variable name without the dollar sign. + * @return bool True if the variable name is whitelisted or already prefixed. + * False otherwise. + */ + private function variable_prefixed_or_whitelisted( $name ) { + // Ignore superglobals and WP global variables. + if ( isset( $this->superglobals[ $name ] ) || isset( $this->wp_globals[ $name ] ) ) { + return true; + } + + return $this->is_prefixed( $name ); + } + + /** + * Validate an array of prefixes as passed through a custom property or via the command line. + * + * Checks that the prefix: + * - is not one of the blacklisted ones. + * - complies with the PHP rules for valid function, class, variable, constant names. + * + * @since 0.12.0 + */ + private function validate_prefixes() { + if ( $this->previous_prefixes === $this->prefixes ) { + return; + } + + // Set the cache *before* validation so as to not break the above compare. + $this->previous_prefixes = $this->prefixes; + + // Validate the passed prefix(es). + foreach ( $this->prefixes as $key => $prefix ) { + $prefixLC = strtolower( $prefix ); + + if ( isset( $this->prefix_blacklist[ $prefixLC ] ) ) { + $this->phpcsFile->addError( + 'The "%s" prefix is not allowed.', + 0, + 'ForbiddenPrefixPassed', + array( $prefix ) + ); + unset( $this->prefixes[ $key ] ); + continue; + } + + // Validate the prefix against characters allowed for function, class, constant names etc. + if ( preg_match( '`^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$`', $prefix ) !== 1 ) { + $this->phpcsFile->addError( + 'The "%s" prefix is not a valid function/class/variable/constant prefix in PHP.', + 0, + 'InvalidPrefixPassed', + array( $prefix ) + ); + unset( $this->prefixes[ $key ] ); + } + + // Lowercase the prefix to allow for direct compare. + $this->prefixes[ $key ] = $prefixLC; + } + + // Set the validated prefixes cache. + $this->validated_prefixes = $this->prefixes; + + } // End validate_prefixes(). + +} // End class. diff --git a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.1.inc b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.1.inc new file mode 100644 index 00000000..d8562e2e --- /dev/null +++ b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.1.inc @@ -0,0 +1,15 @@ + => + */ + public function getErrorList( $testFile = 'PrefixAllGlobalsUnitTest.inc' ) { + + switch ( $testFile ) { + case 'PrefixAllGlobalsUnitTest.inc': + return array( + 1 => 2, // 2 x error for incorrect prefix. + 10 => 1, + 18 => 1, + 21 => 1, + 22 => 1, + 25 => 1, + 27 => 1, + 28 => 1, + 30 => 1, + 31 => 1, + 32 => 1, + 34 => 1, + 35 => 1, + 79 => 1, + 80 => 1, + 134 => ( PHP_VERSION_ID >= 50300 ) ? 0 : 1, // PHPCS on PHP 5.2 does not recognize namespaces. + 136 => ( PHP_VERSION_ID >= 50300 ) ? 0 : 1, // PHPCS on PHP 5.2 does not recognize namespaces. + 138 => ( PHP_VERSION_ID >= 50300 ) ? 0 : 1, // PHPCS on PHP 5.2 does not recognize namespaces. + 139 => ( PHP_VERSION_ID >= 50300 ) ? 0 : 1, // PHPCS on PHP 5.2 does not recognize namespaces. + 140 => ( PHP_VERSION_ID >= 50300 ) ? 0 : 1, // PHPCS on PHP 5.2 does not recognize namespaces. + ); + + case 'PrefixAllGlobalsUnitTest.1.inc': + // Namespaced - all OK. + if ( PHP_VERSION_ID >= 50300 ) { + return array(); + } + + // PHPCS on PHP 5.2 does not recognize namespaces. + return array( + 9 => 1, + 11 => 1, + 13 => 1, + 14 => 1, + 15 => 1, + ); + + default: + return array(); + + } // End switch(). + + } // end getErrorList() + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array(); + + } + +} // End class. From 1fe9e7073926f9337577ce60f6a1499afb76a24c Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 4 Apr 2017 04:02:32 +0200 Subject: [PATCH 011/282] :sparkles: New CapitalPDangitSniff This PR adds a new sniff which checks whether `WordPress` is spelled correctly in text strings, comment text and class/interface/trait names and can catch a wide range of typical misspellings. For this sniff, I've erred on the side of caution as this is **_very_** prone to false positives. This means that some misspellings will likely be missed by this sniff, but that seemed the better choice than to have everyone be terribly annoyed by the sniff being really buggy. Notes: * The sniff has been added to the `WordPress-Core` ruleset. * The sniff will throw a `warning` when a misspelling is found. * The sniff will only throw one warning per token, even when more than one misspelling is found in the same phrase. The warning will in that case contain a count of the number of misspellings found + list them. * For misspellings in text strings and comments, the sniff includes a fixer. For class names and the like, no fixer is included as that will always need attention from a developer. * The fixer has been primed to be able to deal with text strings which contain exceptions as well as misspellings which should be corrected, and will deal with this properly. * The sniff adds a new whitelist comment `spelling`, though this can obviously not be used to whitelist misspellings in comments. The sniff takes the following situation into account and will ignore these when encountered: - URLs for wordpress.org/com/net/tv. - `@...` usernames starting with `wordpress` - email addresses with a domain starting with `wordpress` - email addresses with a user name ending with `wordpress` (typical default email address set up by core) - (most) variable names (as used in docblock @param comments). - directory paths containing a folder starting or ending with `wordpress`. - file names containing `wordpress` for a limited set of extensions. - `wordpress` prefixed or suffixed with dashes as those are indicators that the term is probably used as part of a CSS class, such as `fa-wordpress` or filename/path like `class-wordpress-importer.php`. - back-tick quoted `wordpress` (to help with deliberate misspellings in comments) - URL query strings containing `wordpress` - Any docblock `@link` tag content (if not previously ignored already) - HTML attributes containing `wordpress` - escape quoted `\`wordpress\`` as used in xpath queries. The sniff will ignore *anything* within an array, as well as string array keys like `$var['wordpress']` as these will generate false positives in 80% of the cases. The sniff will skip forward to the end of the array when one is encountered. This also prevents the sniff "hanging" when processing large configuration arrays. The sniff is accompanied by extensive unit tests and has been run over both WP core as well as some 180+ recently updated themes (7500+ php files) to try and eliminate most false positives. The only "common" (1 instance in core) false positive I've not eliminated is when the term is used in a parameter in a function call. Excluding that would also exclude examining text string passed to translation functions which would be counter-productive. --- WordPress-Core/ruleset.xml | 2 + WordPress/Sniffs/WP/CapitalPDangitSniff.php | 282 ++++++++++++++++++ .../Tests/WP/CapitalPDangitUnitTest.1.inc | 10 + WordPress/Tests/WP/CapitalPDangitUnitTest.inc | 173 +++++++++++ .../Tests/WP/CapitalPDangitUnitTest.inc.fixed | 173 +++++++++++ WordPress/Tests/WP/CapitalPDangitUnitTest.php | 74 +++++ 6 files changed, 714 insertions(+) create mode 100644 WordPress/Sniffs/WP/CapitalPDangitSniff.php create mode 100644 WordPress/Tests/WP/CapitalPDangitUnitTest.1.inc create mode 100644 WordPress/Tests/WP/CapitalPDangitUnitTest.inc create mode 100644 WordPress/Tests/WP/CapitalPDangitUnitTest.inc.fixed create mode 100644 WordPress/Tests/WP/CapitalPDangitUnitTest.php diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index 42fb63cf..91ef4f51 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -327,5 +327,7 @@ + + diff --git a/WordPress/Sniffs/WP/CapitalPDangitSniff.php b/WordPress/Sniffs/WP/CapitalPDangitSniff.php new file mode 100644 index 00000000..9269b537 --- /dev/null +++ b/WordPress/Sniffs/WP/CapitalPDangitSniff.php @@ -0,0 +1,282 @@ +\'"()]*?\.(?:php|js|css|png|j[e]?pg|gif))#i'; + + /** + * Regex to match a large number or spelling variations of WordPress in class names. + * + * @var string + */ + const WP_CLASSNAME_REGEX = '`(?:^|_)(Word[_]*Pres+)(?:_|$)`i'; + + /** + * String tokens we want to listen for. + * + * @var array + */ + private $text_string_tokens = array( + T_CONSTANT_ENCAPSED_STRING => T_CONSTANT_ENCAPSED_STRING, + T_DOUBLE_QUOTED_STRING => T_DOUBLE_QUOTED_STRING, + T_HEREDOC => T_HEREDOC, + T_NOWDOC => T_NOWDOC, + T_INLINE_HTML => T_INLINE_HTML, + ); + + /** + * Comment tokens we want to listen for as they contain text strings. + * + * @var array + */ + private $comment_text_tokens = array( + T_DOC_COMMENT => T_DOC_COMMENT, + T_DOC_COMMENT_STRING => T_DOC_COMMENT_STRING, + T_COMMENT => T_COMMENT, + ); + + /** + * Class-like structure tokens to listen for. + * + * Using proper spelling in class, interface and trait names does not conflict with the naming conventions. + * + * @var array + */ + private $class_tokens = array( + T_CLASS => T_CLASS, + T_INTERFACE => T_INTERFACE, + T_TRAIT => T_TRAIT, + ); + + /** + * Combined text string and comment tokens array. + * + * This property is set in the register() method and used for lookups. + * + * @var array + */ + private $text_and_comment_tokens = array(); + + /** + * Returns an array of tokens this test wants to listen for. + * + * @since 0.12.0 + * + * @return array + */ + public function register() { + // Union the arrays - keeps the array keys. + $this->text_and_comment_tokens = ( $this->text_string_tokens + $this->comment_text_tokens ); + + $targets = ( $this->text_and_comment_tokens + $this->class_tokens ); + + // Also sniff for array tokens to make skipping anything within those more efficient. + $targets[ T_ARRAY ] = T_ARRAY; + $targets[ T_OPEN_SHORT_ARRAY ] = T_OPEN_SHORT_ARRAY; + + return $targets; + } + + /** + * Processes this test, when one of its tokens is encountered. + * + * @since 0.12.0 + * + * @param int $stackPtr The position of the current token in the stack. + * + * @return int|void Integer stack pointer to skip forward or void to continue + * normal file processing. + */ + public function process_token( $stackPtr ) { + + if ( $this->has_whitelist_comment( 'spelling', $stackPtr ) ) { + return; + } + + /* + * Ignore tokens within an array definition as this is a false positive in 80% of all cases. + * + * The return values skip to the end of the array. + * This prevents the sniff "hanging" on very long configuration arrays. + */ + if ( T_OPEN_SHORT_ARRAY === $this->tokens[ $stackPtr ]['code'] && isset( $this->tokens[ $stackPtr ]['bracket_closer'] ) ) { + return $this->tokens[ $stackPtr ]['bracket_closer']; + } elseif ( T_ARRAY === $this->tokens[ $stackPtr ]['code'] && isset( $this->tokens[ $stackPtr ]['parenthesis_closer'] ) ) { + return $this->tokens[ $stackPtr ]['parenthesis_closer']; + } + + /* + * Deal with misspellings in class/interface/trait names. + * These are not auto-fixable, but need the attention of a developer. + */ + if ( isset( $this->class_tokens[ $this->tokens[ $stackPtr ]['code'] ] ) ) { + $classname = $this->phpcsFile->getDeclarationName( $stackPtr ); + if ( empty( $classname ) ) { + return; + } + + if ( preg_match_all( self::WP_CLASSNAME_REGEX, $classname, $matches, PREG_PATTERN_ORDER ) > 0 ) { + $mispelled = $this->retrieve_misspellings( $matches[1] ); + + if ( ! empty( $mispelled ) ) { + $this->phpcsFile->addWarning( + 'Please spell "WordPress" correctly. Found: "%s" as part of the class/interface/trait name.', + $stackPtr, + 'MisspelledClassName', + array( implode( ', ', $mispelled ) ) + ); + } + } + + return; + } + + /* + * Deal with misspellings in text strings and documentation. + */ + + // Ignore content of docblock @link tags. + if ( T_DOC_COMMENT_STRING === $this->tokens[ $stackPtr ]['code'] + || T_DOC_COMMENT === $this->tokens[ $stackPtr ]['code'] + ) { + + $comment_start = $this->phpcsFile->findPrevious( T_DOC_COMMENT_OPEN_TAG, ( $stackPtr - 1 ) ); + if ( false !== $comment_start ) { + $comment_tag = $this->phpcsFile->findPrevious( T_DOC_COMMENT_TAG, ( $stackPtr - 1 ), $comment_start ); + if ( false !== $comment_tag && '@link' === $this->tokens[ $comment_tag ]['content'] ) { + // @link tag, so ignore. + return; + } + } + } + + // Ignore any text strings which are array keys `$var['key']` as this is a false positive in 80% of all cases. + if ( T_CONSTANT_ENCAPSED_STRING === $this->tokens[ $stackPtr ]['code'] ) { + $prevToken = $this->phpcsFile->findPrevious( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr - 1 ), null, true, null, true ); + if ( false !== $prevToken && T_OPEN_SQUARE_BRACKET === $this->tokens[ $prevToken ]['code'] ) { + $nextToken = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true, null, true ); + if ( false !== $nextToken && T_CLOSE_SQUARE_BRACKET === $this->tokens[ $nextToken ]['code'] ) { + return; + } + } + } + + $content = $this->tokens[ $stackPtr ]['content']; + + if ( preg_match_all( self::WP_REGEX, $content, $matches, ( PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE ) ) > 0 ) { + /* + * Prevent some typical false positives. + */ + if ( isset( $this->text_and_comment_tokens[ $this->tokens[ $stackPtr ]['code'] ] ) ) { + $offset = 0; + foreach ( $matches[1] as $key => $match_data ) { + $next_offset = ( $match_data[1] + strlen( $match_data[0] ) ); + + // Prevent matches on part of a URL. + if ( preg_match( '`http[s]?://[^\s<>\'"()]*' . preg_quote( $match_data[0], '`' ) . '`', $content, $discard, 0, $offset ) === 1 ) { + unset( $matches[1][ $key ] ); + } elseif ( preg_match( '`[a-z]+=(["\'])' . preg_quote( $match_data[0], '`' ) . '\1`', $content, $discard, 0, $offset ) === 1 ) { + // Prevent matches on html attributes like: `value="wordpress"`. + unset( $matches[1][ $key ] ); + } elseif ( preg_match( '`\\\\\'' . preg_quote( $match_data[0], '`' ) . '\\\\\'`', $content, $discard, 0, $offset ) === 1 ) { + // Prevent matches on xpath queries and such: `\'wordpress\'`. + unset( $matches[1][ $key ] ); + } elseif ( preg_match( '`(?:\?|&|&)[a-z0-9_]+=' . preg_quote( $match_data[0], '`' ) . '(?:&|$)`', $content, $discard, 0, $offset ) === 1 ) { + // Prevent matches on url query strings: `?something=wordpress`. + unset( $matches[1][ $key ] ); + } + + $offset = $next_offset; + } + + if ( empty( $matches[1] ) ) { + return; + } + } + + $mispelled = $this->retrieve_misspellings( $matches[1] ); + + if ( empty( $mispelled ) ) { + return; + } + + $fix = $this->phpcsFile->addFixableWarning( + 'Please spell "WordPress" correctly. Found %s misspelling(s): %s', + $stackPtr, + 'Misspelled', + array( + count( $mispelled ), + implode( ', ', $mispelled ), + ) + ); + + if ( true === $fix ) { + // Apply fixes based on offset to ensure we don't replace false positives. + $replacement = $content; + foreach ( $matches[1] as $match ) { + $replacement = substr_replace( $replacement, 'WordPress', $match[1], strlen( $match[0] ) ); + } + + $this->phpcsFile->fixer->replaceToken( $stackPtr, $replacement ); + } + } // End if(). + + } // End process_token(). + + /** + * Retrieve a list of misspellings based on an array of matched variations on the target word. + * + * @param array $match_stack Array of matched variations of the target word. + * @return array Array containing only the misspelled variants. + */ + protected function retrieve_misspellings( $match_stack ) { + $mispelled = array(); + foreach ( $match_stack as $match ) { + // Deal with multi-dimensional arrays when capturing offset. + if ( is_array( $match ) ) { + $match = $match[0]; + } + + if ( 'WordPress' !== $match ) { + $mispelled[] = $match; + } + } + + return $mispelled; + } + +} // End class. diff --git a/WordPress/Tests/WP/CapitalPDangitUnitTest.1.inc b/WordPress/Tests/WP/CapitalPDangitUnitTest.1.inc new file mode 100644 index 00000000..62e82673 --- /dev/null +++ b/WordPress/Tests/WP/CapitalPDangitUnitTest.1.inc @@ -0,0 +1,10 @@ + + + + +

Here we have an inline HTML tag with wordpress spelled incorrectly.

+

Here we have an inline HTML tag with WordPress spelled correctly.

+ +

Here we have an inline HTML tag with a URL, of course this should be coded differently, but even when it isn't, it should be ignored, so here goes: http://wordpress.org/ spelled incorrectly.

+ +

Here we have an inline HTML tag with wordpressers spelled incorrectly.

+ +

Here we have an inline HTML tag with word press spelled incorrectly.

+

Here we have an inline HTML tag with word-press spelled incorrectly.

+

Here we have an inline HTML tag with word - presssss spelled incorrectly.

+ +

In this case it's a CSS class name and we should leave well alone.

+

CSS class, but also wordPres spelled incorrectly in the text.

+

Same again, this time with same spelling in both the class as well as in the text wordpress.

+ +

And lets have another test with wordpress spelled incorrectly more than once. Wordpress, wordPress, word pres.

+ +query('/configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'wordpress\')] | /configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'WordPress\')]'); // OK. + +// If we don't have an email from the input headers default to wordpress@$sitename <= OK. +$from_email = 'wordpress@' . $sitename; // OK. + +if ( $counts['wordpress'] ) { // OK. + /* translators: 1: Number of updates available to WordPress */ + $titles['wordpress'] = sprintf( __( '%d WordPress Update'), $counts['wordpress'] ); // OK. +} + +?> + + +
    + + array( 'installed' => false, 'active' => false ), // OK. + 'widget-importer-exporter' => array( 'installed' => false, 'active' => false ) +); + +$default_editor_settings = [ + 'textarea_name' => $textarea_name, + 'media_buttons' => false, + 'tinymce' => [ 'plugins' => 'wordpress' ] // OK. +]; + + $wp_customize->add_control( + new Arouse_Custom_Content( + $wp_customize, + 'arouse_documentation_link', + array( + 'section' => 'arouse_theme_info', + 'label' => __( 'Arouse Documentation', 'arouse' ), + 'content' => __( 'Read the documentation.', 'arouse' ), // OK. + ) + ) + ); + +?> + + Review this theme on w.org + +

    Adamos. Please use the Wordpress Support Forums if you have experience issues with this theme.', 'adamos' ); ?>

    + + + + apply_filters( 'comment_form_default_fields', $fields ), + /* translators: %s: wordpress login url */ // Bad, but false negative as within an array. + 'must_log_in' => '', + )); + +$wl_theme_options['service_3_icons']="fa fa-wordpress"; // OK. + +if ( get_theme_mod('header_icon', 'fa-wordpress') ) echo ''; // OK. + +/** + * Bootstrap styled Caption shortcode. + * Hat tip: http://justintadlock.com/archives/2011/07/01/captions-in-wordpress <= OK. + */ + +$render = '
     ' . $message . '
    ' . $render; // OK. + +$installed = self::check_plugin_is_installed( 'wordpress-importer' ); // OK. + + +/* + * Test whitelisting + */ +echo 'This is an explanation about wordpress.'; // WPCS: spelling ok. + +/* + * Test fixer with an ignored and a fixable misspelling in the same line. + */ +?> +

    The first two should be ignored for the purpose of replacing, this wordpress however should be fixed and this wordpress too.

    diff --git a/WordPress/Tests/WP/CapitalPDangitUnitTest.inc.fixed b/WordPress/Tests/WP/CapitalPDangitUnitTest.inc.fixed new file mode 100644 index 00000000..16b5bcca --- /dev/null +++ b/WordPress/Tests/WP/CapitalPDangitUnitTest.inc.fixed @@ -0,0 +1,173 @@ + + + + +

    Here we have an inline HTML tag with WordPress spelled incorrectly.

    +

    Here we have an inline HTML tag with WordPress spelled correctly.

    + +

    Here we have an inline HTML tag with a URL, of course this should be coded differently, but even when it isn't, it should be ignored, so here goes: http://wordpress.org/ spelled incorrectly.

    + +

    Here we have an inline HTML tag with wordpressers spelled incorrectly.

    + +

    Here we have an inline HTML tag with WordPress spelled incorrectly.

    +

    Here we have an inline HTML tag with WordPress spelled incorrectly.

    +

    Here we have an inline HTML tag with WordPress spelled incorrectly.

    + +

    In this case it's a CSS class name and we should leave well alone.

    +

    CSS class, but also WordPress spelled incorrectly in the text.

    +

    Same again, this time with same spelling in both the class as well as in the text WordPress.

    + +

    And lets have another test with WordPress spelled incorrectly more than once. WordPress, WordPress, WordPress.

    + +query('/configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'wordpress\')] | /configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'WordPress\')]'); // OK. + +// If we don't have an email from the input headers default to wordpress@$sitename <= OK. +$from_email = 'wordpress@' . $sitename; // OK. + +if ( $counts['wordpress'] ) { // OK. + /* translators: 1: Number of updates available to WordPress */ + $titles['wordpress'] = sprintf( __( '%d WordPress Update'), $counts['wordpress'] ); // OK. +} + +?> + + +
      + + array( 'installed' => false, 'active' => false ), // OK. + 'widget-importer-exporter' => array( 'installed' => false, 'active' => false ) +); + +$default_editor_settings = [ + 'textarea_name' => $textarea_name, + 'media_buttons' => false, + 'tinymce' => [ 'plugins' => 'wordpress' ] // OK. +]; + + $wp_customize->add_control( + new Arouse_Custom_Content( + $wp_customize, + 'arouse_documentation_link', + array( + 'section' => 'arouse_theme_info', + 'label' => __( 'Arouse Documentation', 'arouse' ), + 'content' => __( 'Read the documentation.', 'arouse' ), // OK. + ) + ) + ); + +?> + + Review this theme on w.org + +

      Adamos. Please use the WordPress Support Forums if you have experience issues with this theme.', 'adamos' ); ?>

      + + + + apply_filters( 'comment_form_default_fields', $fields ), + /* translators: %s: wordpress login url */ // Bad, but false negative as within an array. + 'must_log_in' => '', + )); + +$wl_theme_options['service_3_icons']="fa fa-wordpress"; // OK. + +if ( get_theme_mod('header_icon', 'fa-wordpress') ) echo ''; // OK. + +/** + * Bootstrap styled Caption shortcode. + * Hat tip: http://justintadlock.com/archives/2011/07/01/captions-in-wordpress <= OK. + */ + +$render = '
       ' . $message . '
      ' . $render; // OK. + +$installed = self::check_plugin_is_installed( 'wordpress-importer' ); // OK. + + +/* + * Test whitelisting + */ +echo 'This is an explanation about wordpress.'; // WPCS: spelling ok. + +/* + * Test fixer with an ignored and a fixable misspelling in the same line. + */ +?> +

      The first two should be ignored for the purpose of replacing, this WordPress however should be fixed and this WordPress too.

      diff --git a/WordPress/Tests/WP/CapitalPDangitUnitTest.php b/WordPress/Tests/WP/CapitalPDangitUnitTest.php new file mode 100644 index 00000000..2b77cc78 --- /dev/null +++ b/WordPress/Tests/WP/CapitalPDangitUnitTest.php @@ -0,0 +1,74 @@ + => + */ + public function getErrorList() { + return array(); + + } // end getErrorList() + + /** + * Returns the lines where warnings should occur. + * + * @param string $testFile The name of the file being tested. + * @return array => + */ + public function getWarningList( $testFile = 'CapitalPDangitUnitTest.inc' ) { + + switch ( $testFile ) { + case 'CapitalPDangitUnitTest.inc': + return array( + 3 => 1, + 5 => 1, + 8 => 1, + 26 => 1, + 28 => 1, + 34 => 1, + 35 => 1, + 36 => 1, + 40 => 1, + 41 => 1, + 45 => 1, + 53 => 1, + 60 => 1, + 61 => 1, + 62 => 1, + 65 => 1, + 66 => 1, + 68 => ( PHP_VERSION_ID >= 50300 ) ? 1 : 2, // PHPCS on PHP 5.2 apparently breaks the token up into two tokens. + 101 => 1, + 139 => 1, + 146 => 0, // False negative. + 173 => 1, + ); + + case 'CapitalPDangitUnitTest.1.inc': + return array( + 9 => ( PHP_VERSION_ID >= 50300 ) ? 1 : 0, // PHPCS on PHP 5.2 does not recognize nowdocs. + ); + + default: + return array(); + + } // End switch(). + } + +} // End class. From eadc2869ec1b64ddf63eff7e3ba3882f1e13c92a Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 5 Apr 2017 02:51:51 +0200 Subject: [PATCH 012/282] CS: minor whitespace fixes. --- WordPress/Sniffs/WP/I18nSniff.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/WordPress/Sniffs/WP/I18nSniff.php b/WordPress/Sniffs/WP/I18nSniff.php index 284ee429..78d28900 100644 --- a/WordPress/Sniffs/WP/I18nSniff.php +++ b/WordPress/Sniffs/WP/I18nSniff.php @@ -553,8 +553,8 @@ protected function check_for_translator_comment( $stack_ptr, $args ) { if ( T_COMMENT === $this->tokens[ $previous_comment ]['code'] ) { $comment_text = trim( $this->tokens[ $previous_comment ]['content'] ); - // If it's multi-line /* */ comment, collect all the parts. - if ( '*/' === substr( $comment_text, -2 ) && '/*' !== substr( $comment_text, 0, 2 ) ) { + // If it's multi-line /* */ comment, collect all the parts. + if ( '*/' === substr( $comment_text, -2 ) && '/*' !== substr( $comment_text, 0, 2 ) ) { for ( $i = ( $previous_comment - 1 ); 0 <= $i; $i-- ) { if ( T_COMMENT !== $this->tokens[ $i ]['code'] ) { break; @@ -564,7 +564,7 @@ protected function check_for_translator_comment( $stack_ptr, $args ) { } } - if ( true === $this->is_translators_comment( $comment_text ) ) { + if ( true === $this->is_translators_comment( $comment_text ) ) { // Comment is ok. return; } From e1bbe692fb4f5b06e67c3ff50c1a4d83c573d99d Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 5 Apr 2017 04:17:06 +0200 Subject: [PATCH 013/282] :rocket: Lint the XML ruleset files and check them for consistent code style * Runs these checks only once per build --- .travis.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.travis.yml b/.travis.yml index 89ae2f97..ce5fccc0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,6 +40,7 @@ matrix: - env: PHPCS_BRANCH=3.0 before_install: + - export XMLLINT_INDENT=" " - export PHPCS_DIR=/tmp/phpcs - export PHPUNIT_DIR=/tmp/phpunit - export PHPCS_BIN=$(if [[ $PHPCS_BRANCH == 3.0 ]]; then echo $PHPCS_DIR/bin/phpcs; else echo $PHPCS_DIR/scripts/phpcs; fi) @@ -50,7 +51,9 @@ before_install: - if [[ ${TRAVIS_PHP_VERSION:0:2} != "5." ]]; then wget -P $PHPUNIT_DIR https://phar.phpunit.de/phpunit-5.7.phar && chmod +x $PHPUNIT_DIR/phpunit-5.7.phar; fi script: + # Lint the PHP files against parse errors. - if find . -name "*.php" -exec php -l {} \; | grep "^[Parse error|Fatal error]"; then exit 1; fi; + # Run the unit tests. - if [[ ${TRAVIS_PHP_VERSION:0:2} == "5." ]]; then phpunit --filter WordPress /tmp/phpcs/tests/AllTests.php; fi - if [[ ${TRAVIS_PHP_VERSION:0:2} != "5." ]]; then php $PHPUNIT_DIR/phpunit-5.7.phar --filter WordPress /tmp/phpcs/tests/AllTests.php; fi # WordPress Coding Standards. @@ -63,3 +66,14 @@ script: # --standard: Use WordPress as the standard. # --extensions: Only sniff PHP files. - if [[ "$SNIFF" == "1" ]]; then $PHPCS_DIR/scripts/phpcs -p -s -n . --standard=./bin/phpcs.xml --extensions=php; fi + # Validate the xml files. + # @link http://xmlsoft.org/xmllint.html + - if [[ "$SNIFF" == "1" ]]; then xmllint --noout ./*/ruleset.xml; fi + - if [[ "$SNIFF" == "1" ]]; then xmllint --noout ./project.ruleset.xml.example; fi + # Check the code-style consistency of the xml files. + - if [[ "$SNIFF" == "1" ]]; then diff -B --tabsize=4 ./WordPress/ruleset.xml <(xmllint --format "./WordPress/ruleset.xml"); fi + - if [[ "$SNIFF" == "1" ]]; then diff -B --tabsize=4 ./WordPress-Core/ruleset.xml <(xmllint --format "./WordPress-Core/ruleset.xml"); fi + - if [[ "$SNIFF" == "1" ]]; then diff -B --tabsize=4 ./WordPress-Docs/ruleset.xml <(xmllint --format "./WordPress-Docs/ruleset.xml"); fi + - if [[ "$SNIFF" == "1" ]]; then diff -B --tabsize=4 ./WordPress-Extra/ruleset.xml <(xmllint --format "./WordPress-Extra/ruleset.xml"); fi + - if [[ "$SNIFF" == "1" ]]; then diff -B --tabsize=4 ./WordPress-VIP/ruleset.xml <(xmllint --format "./WordPress-VIP/ruleset.xml"); fi + - if [[ "$SNIFF" == "1" ]]; then diff -B --tabsize=4 ./project.ruleset.xml.example <(xmllint --format "./project.ruleset.xml.example"); fi From cb264065c8fa2ccbc99791feda659c08721f1a55 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 5 Apr 2017 04:21:53 +0200 Subject: [PATCH 014/282] Fix the codestyle of the XML files. Most files only needed minor changes for this, the Core ruleset however needed more extensive adjustment. The Core ruleset used additional indentation to show which rules belonged with each handbook paragraph, making the ruleset more easily scannable. As this extra indentation violates the formatting rules, the handbook paragraph headers have been given "fencing" to maintain the scannability of the document. --- WordPress-Core/ruleset.xml | 496 +++++++++++++++++++----------------- WordPress-Docs/ruleset.xml | 8 +- WordPress-Extra/ruleset.xml | 20 +- WordPress-VIP/ruleset.xml | 20 +- WordPress/ruleset.xml | 2 +- project.ruleset.xml.example | 4 +- 6 files changed, 295 insertions(+), 255 deletions(-) diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index 42fb63cf..8824429d 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -3,329 +3,369 @@ Non-controversial generally-agreed upon WordPress Coding Standards - - - - 0 - + + + + 0 + - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - 0 - - - - - - - - - - - - - + + + + 0 + + + + + + + + + + + + + - + - - + + - + - + - - - + + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 - - - 0 - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + 0 + + + + + + + + + + + - + - + - + - - + + - - - + + + - - - - + + + + - - + + - - + + - - - - + + + + - + - + - + - + - - + + - - - + + + - + - + - - + + - - - - - - + + + + + + - - + + - - - + + + - - + + - - + + - - + + diff --git a/WordPress-Docs/ruleset.xml b/WordPress-Docs/ruleset.xml index a55113ab..05f0ec87 100644 --- a/WordPress-Docs/ruleset.xml +++ b/WordPress-Docs/ruleset.xml @@ -83,14 +83,14 @@ - + - - - + + + diff --git a/WordPress-Extra/ruleset.xml b/WordPress-Extra/ruleset.xml index 53886e0a..ca1fb5df 100644 --- a/WordPress-Extra/ruleset.xml +++ b/WordPress-Extra/ruleset.xml @@ -7,7 +7,7 @@ - + @@ -17,7 +17,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -46,13 +46,13 @@ - + - + @@ -75,12 +75,12 @@ - + - + @@ -88,7 +88,7 @@ - + @@ -97,8 +97,8 @@ error - + - + diff --git a/WordPress-VIP/ruleset.xml b/WordPress-VIP/ruleset.xml index 523ede88..bbe5c823 100644 --- a/WordPress-VIP/ruleset.xml +++ b/WordPress-VIP/ruleset.xml @@ -24,19 +24,19 @@ - + - + - + - - - + + + @@ -53,7 +53,7 @@ - + @@ -62,7 +62,7 @@ - + error @@ -72,13 +72,13 @@ - + - + Using cURL functions is highly discouraged within VIP context. Check (Fetching Remote Data) on VIP Documentation. diff --git a/WordPress/ruleset.xml b/WordPress/ruleset.xml index 6fb17425..c2ef3b4a 100644 --- a/WordPress/ruleset.xml +++ b/WordPress/ruleset.xml @@ -11,7 +11,7 @@ - + diff --git a/project.ruleset.xml.example b/project.ruleset.xml.example index 8893a4ea..aee8fea4 100644 --- a/project.ruleset.xml.example +++ b/project.ruleset.xml.example @@ -28,7 +28,7 @@ exclude problematic sniffs like so. --> - - + + From 47a53cadb5b2543192e0491e86cc71e8f5c2eb6e Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 5 Apr 2017 16:55:20 +0200 Subject: [PATCH 015/282] Update the `project.ruleset.xml` example file. * Recommend using the `WordPress-Extra` + `WordPress-Docs` ruleset rather than `WordPress-Core`. * Add example to exclude the Composer vendor directory. * Remove some of the "extra" included rules which are already included by the WP rulesets (and the rest of them down). * Add info and example on how to include the `PHPCompatibility` standard. We already recommend its use in the readme, so we might as well show how. * Add a number of the recommended custom properties to the example ruleset. * Add/Clarify some documentation. --- project.ruleset.xml.example | 71 +++++++++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 10 deletions(-) diff --git a/project.ruleset.xml.example b/project.ruleset.xml.example index aee8fea4..b2e44d94 100644 --- a/project.ruleset.xml.example +++ b/project.ruleset.xml.example @@ -2,6 +2,7 @@ A custom set of rules to check for a WPized WordPress project + /docroot/wp-admin/* /docroot/wp-includes/* /docroot/wp-*.php @@ -10,25 +11,75 @@ /docroot/wp-content/plugins/* *.twig - - - - - + + /vendor/* - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From dbf73b2a12f765d39d0b0a532b7e2a772887e72d Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 6 Apr 2017 06:33:37 +0200 Subject: [PATCH 016/282] Fix codestyle for latest XML rule addition. --- WordPress-Core/ruleset.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index ceea6f5e..d468abcc 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -367,7 +367,7 @@ - - + + From 882ae6012420f7e45cb654701c64e4d81c1aa8fa Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 7 Apr 2017 12:20:03 +0200 Subject: [PATCH 017/282] PrefixAllGlobalsSniff: Allow for backfills of native PHP functions/classes etc. This will only prevent false positives when the sniffs are run on a PHP version which contains the backfilled function/class etc. --- .../PrefixAllGlobalsSniff.php | 46 ++++++++++++++++++- .../PrefixAllGlobalsUnitTest.inc | 22 +++++++++ .../PrefixAllGlobalsUnitTest.php | 4 ++ 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php index ab1f0081..6ffc9d62 100644 --- a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php +++ b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php @@ -195,7 +195,12 @@ public function process_token( $stackPtr ) { return; } - $item_name = $this->phpcsFile->getDeclarationName( $stackPtr ); + $item_name = $this->phpcsFile->getDeclarationName( $stackPtr ); + if ( function_exists( $item_name ) ) { + // Backfill for PHP native function. + return; + } + $error_text = 'Functions declared'; $error_code = 'NonPrefixedFunctionFound'; break; @@ -212,7 +217,34 @@ public function process_token( $stackPtr ) { return; } - $item_name = $this->phpcsFile->getDeclarationName( $stackPtr ); + $item_name = $this->phpcsFile->getDeclarationName( $stackPtr ); + switch ( $this->tokens[ $stackPtr ]['type'] ) { + case 'T_CLASS': + if ( class_exists( $item_name ) ) { + // Backfill for PHP native class. + return; + } + break; + + case 'T_INTERFACE': + if ( interface_exists( $item_name ) ) { + // Backfill for PHP native interface. + return; + } + break; + + case 'T_TRAIT': + if ( function_exists( 'trait_exists' ) && trait_exists( $item_name ) ) { + // Backfill for PHP native trait. + return; + } + break; + + default: + // Left empty on purpose. + break; + } + $error_text = 'Classes declared'; $error_code = 'NonPrefixedClassFound'; break; @@ -230,6 +262,11 @@ public function process_token( $stackPtr ) { } $item_name = $this->tokens[ $constant_name_ptr ]['content']; + if ( defined( $item_name ) ) { + // Backfill for PHP native constant. + return; + } + $error_text = 'Global constants defined'; $error_code = 'NonPrefixedConstantFound'; break; @@ -405,6 +442,11 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p } if ( 'define' === $matched_content ) { + if ( defined( $raw_content ) ) { + // Backfill for PHP native constant. + return; + } + $data = array( 'Global constants defined' ); $error_code = 'NonPrefixedConstantFound'; } else { diff --git a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc index b63aba18..4c52e079 100644 --- a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc +++ b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc @@ -199,3 +199,25 @@ $something = 'abc'; // WPCS: prefix ok. // Executing a WP core action or filter is sometimes ok. do_action( 'set_current_user' ); // WPCS: prefix ok. apply_filters( 'excerpt_edit_pre', $var ); // WPCS: prefix ok. + +/* + * Issue 915: OK/Bad - backfilled PHP functions will be recognized depending on the PHP version PHPCS runs on + * and the extensions loaded in that version. + */ +if ( ! function_exists( 'mb_strpos' ) ) { + // Fill in for a PHP function which is not always available (extension needs to be loaded). + function mb_strpos() {} +} + +if ( ! function_exists( 'array_column' ) ) { + // Fill in for a PHP function which is not always available - introduced in PHP 5.5. + function array_column() {} +} + +if ( ! defined( 'E_DEPRECATED' ) ) { + define( 'E_DEPRECATED', true ); // Introduced in PHP 5.3.0. +} + +if ( ! class_exists( 'IntlTimeZone' ) ) { + class IntlTimeZone {} // Introduced in PHP 5.5.0. +} diff --git a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php index b15400d6..b0eec5f3 100644 --- a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php +++ b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php @@ -46,6 +46,10 @@ public function getErrorList( $testFile = 'PrefixAllGlobalsUnitTest.inc' ) { 138 => ( PHP_VERSION_ID >= 50300 ) ? 0 : 1, // PHPCS on PHP 5.2 does not recognize namespaces. 139 => ( PHP_VERSION_ID >= 50300 ) ? 0 : 1, // PHPCS on PHP 5.2 does not recognize namespaces. 140 => ( PHP_VERSION_ID >= 50300 ) ? 0 : 1, // PHPCS on PHP 5.2 does not recognize namespaces. + 209 => ( function_exists( 'mb_strpos' ) ) ? 0 : 1, + 214 => ( function_exists( 'array_column' ) ) ? 0 : 1, + 218 => ( defined( 'E_DEPRECATED' ) ) ? 0 : 1, + 222 => ( class_exists( 'IntlTimeZone' ) ) ? 0 : 1, ); case 'PrefixAllGlobalsUnitTest.1.inc': From 69b6b54e05a0b0d60864955468095bfd0dcf496b Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 7 Apr 2017 03:36:04 -0700 Subject: [PATCH 018/282] Add Squiz.Classes.SelfMemberReference to WordPress-Core (#918) Add Squiz.Classes.SelfMemberReference sniff * `Core`: add the sniff with the exception of the `NotUsed` rule which checks whether `self` should be used instead of the classname. * `Extra`: re-enable the `NotUsed` rule. --- WordPress-Core/ruleset.xml | 7 +++++++ WordPress-Extra/ruleset.xml | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index d468abcc..a67acfb3 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -356,6 +356,13 @@ + + + + 0 + + + + 5 + + diff --git a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php new file mode 100644 index 00000000..35d4091d --- /dev/null +++ b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php @@ -0,0 +1,178 @@ +tab_width ) ) { + $cli_values = $this->phpcsFile->phpcs->cli->getCommandLineValues(); + if ( ! isset( $cli_values['tabWidth'] ) || 0 === $cli_values['tabWidth'] ) { + // We have no idea how wide tabs are, so assume 4 spaces for fixing. + $this->tab_width = 4; + } else { + $this->tab_width = $cli_values['tabWidth']; + } + } + + /* + * Determine the array opener & closer. + */ + if ( T_ARRAY === $this->tokens[ $stackPtr ]['code'] ) { + if ( ! isset( $this->tokens[ $stackPtr ]['parenthesis_opener'] ) ) { + return; // Live coding. + } + $opener = $this->tokens[ $stackPtr ]['parenthesis_opener']; + + if ( ! isset( $this->tokens[ $opener ]['parenthesis_closer'] ) ) { + return; // Live coding. + } + $closer = $this->tokens[ $opener ]['parenthesis_closer']; + } else { + // Short array syntax. + $opener = $stackPtr; + + if ( ! isset( $this->tokens[ $stackPtr ]['bracket_closer'] ) ) { + return; // Live coding. + } + $closer = $this->tokens[ $stackPtr ]['bracket_closer']; + } + + if ( $this->tokens[ $opener ]['line'] === $this->tokens[ $closer ]['line'] ) { + // Not interested in single line arrays. + return; + } + + /* + * Determine the indentation of the line containing the array opener. + */ + $indentation = ''; + $column = 1; + for ( $i = $stackPtr; $i >= 0; $i-- ) { + if ( $this->tokens[ $i ]['line'] === $this->tokens[ $stackPtr ]['line'] ) { + continue; + } + + if ( T_WHITESPACE === $this->tokens[ ( $i + 1 ) ]['code'] ) { + // Something weird going on with tabs vs spaces, but this fixes it. + $indentation = str_replace( ' ', "\t", $this->tokens[ ( $i + 1 ) ]['content'] ); + $column = $this->tokens[ ( $i + 2 ) ]['column']; + } + break; + } + unset( $i ); + + /* + * Check the closing bracket is lined up with the start of the content on the line + * containing the array opener. + */ + if ( $this->tokens[ $closer ]['column'] !== $column ) { + $expected = ( $column - 1 ); + $found = ( $this->tokens[ $closer ]['column'] - 1 ); + $error = 'Array closer not aligned correctly; expected %s space(s) but found %s'; + $data = array( + $expected, + $found, + ); + + $fix = $this->phpcsFile->addFixableError( $error, $closer, 'CloseBraceNotAligned', $data ); + if ( true === $fix ) { + if ( 0 === $found ) { + $this->phpcsFile->fixer->addContent( ( $closer - 1 ), $indentation ); + } else { + $this->phpcsFile->fixer->replaceToken( ( $closer - 1 ), $indentation ); + } + } + } + + $array_items = $this->get_function_call_parameters( $stackPtr ); + if ( empty( $array_items ) ) { + // Strange, no array items found. + return; + } + + $expected_indent = "\t" . $indentation; + $expected_column = ( $column + $this->tab_width ); + + foreach ( $array_items as $item ) { + // Find the line on which the item starts. + $first_content = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, $item['start'], ( $item['end'] + 1 ), true ); + if ( false === $first_content ) { + continue; + } + + $whitespace = ''; + if ( 1 !== $this->tokens[ $first_content ]['column'] ) { + $whitespace = $this->tokens[ ( $first_content - 1 ) ]['content']; + + // If tabs are being converted to spaces by the tokenizer, the + // original content should be checked instead of the converted content. + if ( isset( $this->tokens[ ( $first_content - 1 ) ]['orig_content'] ) ) { + $whitespace = $this->tokens[ ( $first_content - 1 ) ]['orig_content']; + } + } + + if ( $whitespace !== $expected_indent ) { + $expected = ( $expected_column - 1 ); + $found = ( $this->tokens[ $first_content ]['column'] - 1 ); + $error = 'Array item not aligned correctly; expected %s spaces but found %s'; + $data = array( + $expected, + $found, + ); + + $fix = $this->phpcsFile->addFixableError( $error, $first_content, 'ItemNotAligned', $data ); + if ( true === $fix ) { + if ( 0 === $found ) { + $this->phpcsFile->fixer->addContent( ( $first_content - 1 ), $expected_indent ); + } else { + $this->phpcsFile->fixer->replaceToken( ( $first_content - 1 ), $expected_indent ); + } + } + } + } // End foreach(). + + } // End process_token(). + +} // End class. diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc new file mode 100644 index 00000000..a328f96d --- /dev/null +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc @@ -0,0 +1,66 @@ + 'value', + 'key2' => 'value', // Comment after item. +]; + +$ok_nested = array( + 'key1' => array( + 'key1' => 'value', + 'key2' => 'value', + ), + 'key2' => 'value', +); + + +$bad_phpcs_style = array( + 'value', + 123, // Comment after item. + ); + +$bad_phpcs_style_with_keys = array( + 'key1' => 'value', + 'key2' => 'value', + ); + +$bad_phpcs_style_nested = array( + 'key1' => [ + 'key1' => 'value', + + 'key2' => 'value', + + ], + 'key2' => 'value', + ); + +// Arrays with initial indent. + $bad_mixed_indent = [ +'value', + 123, + ]; + + $bad_mixed_indent_with_keys = array( + + 'key1' => 'value', +'key2' => 'value', + ); + + $bad_mixed_indent_nested = [ + 'key1' => array( + 'key1' => 'value', + 'key2' => 'value', + ), + + 'key2' => 'value', + ]; + +$empty = [ + + + ]; diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc.fixed b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc.fixed new file mode 100644 index 00000000..cf423e31 --- /dev/null +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc.fixed @@ -0,0 +1,66 @@ + 'value', + 'key2' => 'value', // Comment after item. +]; + +$ok_nested = array( + 'key1' => array( + 'key1' => 'value', + 'key2' => 'value', + ), + 'key2' => 'value', +); + + +$bad_phpcs_style = array( + 'value', + 123, // Comment after item. +); + +$bad_phpcs_style_with_keys = array( + 'key1' => 'value', + 'key2' => 'value', +); + +$bad_phpcs_style_nested = array( + 'key1' => [ + 'key1' => 'value', + + 'key2' => 'value', + + ], + 'key2' => 'value', +); + +// Arrays with initial indent. + $bad_mixed_indent = [ + 'value', + 123, + ]; + + $bad_mixed_indent_with_keys = array( + + 'key1' => 'value', + 'key2' => 'value', + ); + + $bad_mixed_indent_nested = [ + 'key1' => array( + 'key1' => 'value', + 'key2' => 'value', + ), + + 'key2' => 'value', + ]; + +$empty = [ + + +]; diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php new file mode 100644 index 00000000..53883bb6 --- /dev/null +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php @@ -0,0 +1,62 @@ + => + */ + public function getErrorList() { + return array( + 23 => 1, + 24 => 1, + 25 => 1, + 28 => 1, + 29 => 1, + 30 => 1, + 33 => 1, + 34 => 1, + 36 => 1, + 38 => 1, + 39 => 1, + 40 => 1, + 44 => 1, + 45 => 1, + 46 => 1, + 50 => 1, + 51 => 1, + 52 => 1, + 55 => 1, + 57 => 1, + 58 => 1, + 60 => 1, + 61 => 1, + 66 => 1, + ); + } + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array(); + + } + +} // End class. From a10e79a3d73c9e7123d9e6314b69791c9a6cdfbf Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 6 May 2017 03:15:20 +0200 Subject: [PATCH 039/282] Fix violations in the WPCS codebase found by the new `ArrayIndentation` sniff. --- WordPress/Sniffs/VIP/RestrictedVariablesSniff.php | 2 +- .../Arrays/ArrayAssignmentRestrictionsUnitTest.php | 2 +- .../WhiteSpace/CastStructureSpacingUnitTest.php | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/WordPress/Sniffs/VIP/RestrictedVariablesSniff.php b/WordPress/Sniffs/VIP/RestrictedVariablesSniff.php index 51822b4d..2e669692 100644 --- a/WordPress/Sniffs/VIP/RestrictedVariablesSniff.php +++ b/WordPress/Sniffs/VIP/RestrictedVariablesSniff.php @@ -51,7 +51,7 @@ public function getGroups() { 'message' => 'Due to using Batcache, server side based client related logic will not work, use JS instead.', 'variables' => array( '$_COOKIE', - ), + ), 'array_members' => array( '$_SERVER[\'HTTP_USER_AGENT\']', '$_SERVER[\'REMOTE_ADDR\']', diff --git a/WordPress/Tests/Arrays/ArrayAssignmentRestrictionsUnitTest.php b/WordPress/Tests/Arrays/ArrayAssignmentRestrictionsUnitTest.php index 11cd629d..d4d82e92 100644 --- a/WordPress/Tests/Arrays/ArrayAssignmentRestrictionsUnitTest.php +++ b/WordPress/Tests/Arrays/ArrayAssignmentRestrictionsUnitTest.php @@ -44,7 +44,7 @@ public function getErrorList() { 5 => 1, 7 => 2, 20 => 1, - ); + ); } diff --git a/WordPress/Tests/WhiteSpace/CastStructureSpacingUnitTest.php b/WordPress/Tests/WhiteSpace/CastStructureSpacingUnitTest.php index 0f3e9e78..4376c179 100644 --- a/WordPress/Tests/WhiteSpace/CastStructureSpacingUnitTest.php +++ b/WordPress/Tests/WhiteSpace/CastStructureSpacingUnitTest.php @@ -22,13 +22,13 @@ class WordPress_Tests_WhiteSpace_CastStructureSpacingUnitTest extends AbstractSn */ public function getErrorList() { return array( - 3 => 2, - 6 => 2, - 9 => 2, - 12 => 2, - 15 => 2, - 18 => 2, - 21 => 2, + 3 => 2, + 6 => 2, + 9 => 2, + 12 => 2, + 15 => 2, + 18 => 2, + 21 => 2, ); } From 08195fad2b44257ccb3e6833c3d3feb6402d7a92 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 6 May 2017 04:59:59 +0200 Subject: [PATCH 040/282] ArrayIndentationSniff: Prevent making invalid fixes for mixed arrays. --- WordPress/Sniffs/Arrays/ArrayIndentationSniff.php | 15 +++++++++++++-- .../Tests/Arrays/ArrayIndentationUnitTest.inc | 15 +++++++++++++++ .../Arrays/ArrayIndentationUnitTest.inc.fixed | 15 +++++++++++++++ .../Tests/Arrays/ArrayIndentationUnitTest.php | 1 + 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php index 35d4091d..37409b03 100644 --- a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php @@ -132,16 +132,24 @@ public function process_token( $stackPtr ) { return; } - $expected_indent = "\t" . $indentation; - $expected_column = ( $column + $this->tab_width ); + $expected_indent = "\t" . $indentation; + $expected_column = ( $column + $this->tab_width ); + $end_of_last_item = $opener; foreach ( $array_items as $item ) { // Find the line on which the item starts. $first_content = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, $item['start'], ( $item['end'] + 1 ), true ); if ( false === $first_content ) { + $end_of_last_item = ( $item['end'] + 1 ); continue; } + // Bow out from reporting and fixing mixed multi-line/single-line arrays. + // That is handled by the ArrayDeclarationSniff. + if ( $this->tokens[ $first_content ]['line'] === $this->tokens[ $end_of_last_item ]['line'] ) { + return $closer; + } + $whitespace = ''; if ( 1 !== $this->tokens[ $first_content ]['column'] ) { $whitespace = $this->tokens[ ( $first_content - 1 ) ]['content']; @@ -171,6 +179,9 @@ public function process_token( $stackPtr ) { } } } + + $end_of_last_item = ( $item['end'] + 1 ); + } // End foreach(). } // End process_token(). diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc index a328f96d..b0c4bf6e 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc @@ -64,3 +64,18 @@ $empty = [ ]; + +// Same-line items in mixed arrays should be ignored. +$mixed_1 = array('something', 'else', array( + 'key1' => 'value', + 'key2' => 'value', // Comment after item. + ), +); + +$mixed_2 = array( + array( + 'key1' => 'value', + 'key2' => 'value', // Comment after item. + ), + 'something', 'else', +); diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc.fixed b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc.fixed index cf423e31..a85ad615 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc.fixed +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc.fixed @@ -64,3 +64,18 @@ $empty = [ ]; + +// Same-line items in mixed arrays should be ignored. +$mixed_1 = array('something', 'else', array( + 'key1' => 'value', + 'key2' => 'value', // Comment after item. + ), +); + +$mixed_2 = array( + array( + 'key1' => 'value', + 'key2' => 'value', // Comment after item. + ), + 'something', 'else', +); diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php index 53883bb6..67f8abe9 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php @@ -46,6 +46,7 @@ public function getErrorList() { 60 => 1, 61 => 1, 66 => 1, + 80 => 1, ); } From 3682c0df4c4343c4759256acc3c742f4d4c05b76 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 6 May 2017 21:57:54 +0200 Subject: [PATCH 041/282] :sparkles: New sniff to verify that spaces are used for mid-line alignment > Tabs should be used at the beginning of the line for indentation, while spaces can be used mid-line for alignment. This new sniff covers the second part of this rule. (The first part is already covered by the `Generic.WhiteSpace.DisallowSpaceIndent` sniff). The error which is thrown is auto-fixable. The new sniff has been added to the `WordPress-Core` ruleset. --- WordPress-Core/ruleset.xml | 2 + .../WhiteSpace/DisallowInlineTabsSniff.php | 105 ++++++++++++++++++ .../WhiteSpace/DisallowInlineTabsUnitTest.inc | 27 +++++ .../DisallowInlineTabsUnitTest.inc.fixed | 27 +++++ .../WhiteSpace/DisallowInlineTabsUnitTest.php | 43 +++++++ 5 files changed, 204 insertions(+) create mode 100644 WordPress/Sniffs/WhiteSpace/DisallowInlineTabsSniff.php create mode 100644 WordPress/Tests/WhiteSpace/DisallowInlineTabsUnitTest.inc create mode 100644 WordPress/Tests/WhiteSpace/DisallowInlineTabsUnitTest.inc.fixed create mode 100644 WordPress/Tests/WhiteSpace/DisallowInlineTabsUnitTest.php diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index 8a9de132..615fc270 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -54,6 +54,8 @@ + + - - - - - - - - From c798ae1045359d649c2bea2c76d4bf6e11da2695 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 15 Jun 2017 17:34:09 +0200 Subject: [PATCH 050/282] Remove now superfluous end comments for long conditions --- ...stractArrayAssignmentRestrictionsSniff.php | 2 +- .../AbstractVariableRestrictionsSniff.php | 2 +- WordPress/Sniff.php | 4 ++-- .../Sniffs/Arrays/ArrayIndentationSniff.php | 2 +- WordPress/Sniffs/Files/FileNameSniff.php | 2 +- .../PrefixAllGlobalsSniff.php | 10 ++++---- .../NamingConventions/ValidHookNameSniff.php | 2 +- .../ValidVariableNameSniff.php | 6 ++--- .../Sniffs/Variables/GlobalVariablesSniff.php | 2 +- WordPress/Sniffs/WP/CapitalPDangitSniff.php | 2 +- WordPress/Sniffs/WP/I18nSniff.php | 14 +++++------ WordPress/Sniffs/WP/PreparedSQLSniff.php | 2 +- .../ControlStructureSpacingSniff.php | 24 +++++++++---------- .../WhiteSpace/DisallowInlineTabsSniff.php | 2 +- .../WhiteSpace/OperatorSpacingSniff.php | 10 ++++---- WordPress/Sniffs/XSS/EscapeOutputSniff.php | 4 ++-- 16 files changed, 45 insertions(+), 45 deletions(-) diff --git a/WordPress/AbstractArrayAssignmentRestrictionsSniff.php b/WordPress/AbstractArrayAssignmentRestrictionsSniff.php index 8bbeea7c..89005221 100644 --- a/WordPress/AbstractArrayAssignmentRestrictionsSniff.php +++ b/WordPress/AbstractArrayAssignmentRestrictionsSniff.php @@ -184,7 +184,7 @@ public function process_token( $stackPtr ) { ); } } - } // End foreach(). + } } // End process_token(). diff --git a/WordPress/AbstractVariableRestrictionsSniff.php b/WordPress/AbstractVariableRestrictionsSniff.php index 18eca49e..b1bb20e0 100644 --- a/WordPress/AbstractVariableRestrictionsSniff.php +++ b/WordPress/AbstractVariableRestrictionsSniff.php @@ -180,7 +180,7 @@ public function process_token( $stackPtr ) { return; // Show one error only. - } // End foreach(). + } } // End process_token(). diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index 18a4fa82..390f9c6e 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -1641,7 +1641,7 @@ protected function is_validated( $stackPtr, $array_key = null, $in_condition_onl $scope_end = $stackPtr; - } // End if(). + } for ( $i = ( $scope_start + 1 ); $i < $scope_end; $i++ ) { @@ -1988,7 +1988,7 @@ public function get_function_call_parameters( $stackPtr ) { // Prepare for the next parameter. $param_start = ( $next_comma + 1 ); $cnt++; - } // End while(). + } return $parameters; } diff --git a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php index 37409b03..a0ae020d 100644 --- a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php @@ -182,7 +182,7 @@ public function process_token( $stackPtr ) { $end_of_last_item = ( $item['end'] + 1 ); - } // End foreach(). + } } // End process_token(). diff --git a/WordPress/Sniffs/Files/FileNameSniff.php b/WordPress/Sniffs/Files/FileNameSniff.php index 3e7dcc3e..cec2fa4f 100644 --- a/WordPress/Sniffs/Files/FileNameSniff.php +++ b/WordPress/Sniffs/Files/FileNameSniff.php @@ -206,7 +206,7 @@ public function process_token( $stackPtr ) { } } } - } // End if(). + } // Only run this sniff once per file, no need to run it again. return ( $this->phpcsFile->numTokens + 1 ); diff --git a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php index ee9bb652..856aed26 100644 --- a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php +++ b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php @@ -287,7 +287,7 @@ public function process_token( $stackPtr ) { // Left empty on purpose. break; - } // End switch(). + } if ( empty( $item_name ) || $this->is_prefixed( $item_name ) === true ) { return; @@ -302,7 +302,7 @@ public function process_token( $stackPtr ) { $item_name, ) ); - } // End if(). + } } // End process_token(). @@ -526,8 +526,8 @@ protected function process_variable_assignment( $stackPtr ) { unset( $condition, $has_global, $end_of_statement, $ptr, $imported ); - } // End if(). - } // End if(). + } + } // Still here ? In that case, the variable name should be prefixed. $this->addMessage( @@ -611,7 +611,7 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p // Dynamic hook/constant name, throw a warning. $is_error = false; } - } // End if(). + } if ( 'define' === $matched_content ) { if ( defined( $raw_content ) ) { diff --git a/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php b/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php index 851c018b..bc4b1361 100644 --- a/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php +++ b/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php @@ -137,7 +137,7 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p $underscores++; } } - } // End for(). + } $data = array( implode( '', $expected ), diff --git a/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php b/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php index fcc30f2b..55a353b7 100644 --- a/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php +++ b/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php @@ -166,9 +166,9 @@ protected function processVariable( PHP_CodeSniffer_File $phpcs_file, $stack_ptr $data = array( $original_var_name ); $phpcs_file->addError( $error, $var, 'NotSnakeCaseMemberVar', $data ); } - } // End if(). - } // End if(). - } // End if(). + } + } + } $in_class = false; $obj_operator = $phpcs_file->findPrevious( array( T_WHITESPACE ), ( $stack_ptr - 1 ), null, true ); diff --git a/WordPress/Sniffs/Variables/GlobalVariablesSniff.php b/WordPress/Sniffs/Variables/GlobalVariablesSniff.php index 4b710a1e..55214417 100644 --- a/WordPress/Sniffs/Variables/GlobalVariablesSniff.php +++ b/WordPress/Sniffs/Variables/GlobalVariablesSniff.php @@ -152,7 +152,7 @@ public function process_token( $stackPtr ) { } } } - } // End if(). + } } // End process_token(). diff --git a/WordPress/Sniffs/WP/CapitalPDangitSniff.php b/WordPress/Sniffs/WP/CapitalPDangitSniff.php index 9269b537..9f03b567 100644 --- a/WordPress/Sniffs/WP/CapitalPDangitSniff.php +++ b/WordPress/Sniffs/WP/CapitalPDangitSniff.php @@ -253,7 +253,7 @@ public function process_token( $stackPtr ) { $this->phpcsFile->fixer->replaceToken( $stackPtr, $replacement ); } - } // End if(). + } } // End process_token(). diff --git a/WordPress/Sniffs/WP/I18nSniff.php b/WordPress/Sniffs/WP/I18nSniff.php index 7c87001e..65f99ca3 100644 --- a/WordPress/Sniffs/WP/I18nSniff.php +++ b/WordPress/Sniffs/WP/I18nSniff.php @@ -203,7 +203,7 @@ public function process_token( $stack_ptr ) { } $i = $this_token['parenthesis_closer']; } - } // End for(). + } if ( ! empty( $argument_tokens ) ) { $arguments_tokens[] = $argument_tokens; @@ -295,7 +295,7 @@ public function process_token( $stack_ptr ) { 'arg_name' => 'domain', 'tokens' => array_shift( $arguments_tokens ), ); - } // End if(). + } if ( ! empty( $arguments_tokens ) ) { $this->phpcsFile->addError( 'Too many arguments for function "%s".', $func_open_paren_token, 'TooManyFunctionArgs', array( $translation_function ) ); @@ -481,7 +481,7 @@ protected function check_text( $context ) { $this->phpcsFile->fixer->replaceToken( $stack_ptr, $fixed_str ); $this->phpcsFile->fixer->endChangeset(); } - } // End if(). + } /* * NoEmptyStrings. @@ -580,8 +580,8 @@ protected function check_for_translator_comment( $stack_ptr, $args ) { return; } } - } // End if(). - } // End if(). + } + } // Found placeholders but no translators comment. $this->phpcsFile->addWarning( @@ -590,8 +590,8 @@ protected function check_for_translator_comment( $stack_ptr, $args ) { 'MissingTranslatorsComment' ); return; - } // End foreach(). - } // End foreach(). + } + } } // End check_for_translator_comment(). diff --git a/WordPress/Sniffs/WP/PreparedSQLSniff.php b/WordPress/Sniffs/WP/PreparedSQLSniff.php index 8b16f6da..85d3202a 100644 --- a/WordPress/Sniffs/WP/PreparedSQLSniff.php +++ b/WordPress/Sniffs/WP/PreparedSQLSniff.php @@ -188,7 +188,7 @@ public function process_token( $stackPtr ) { 'NotPrepared', array( $this->tokens[ $this->i ]['content'] ) ); - } // End for(). + } return $this->end; diff --git a/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php b/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php index 85a80da2..dde402c1 100644 --- a/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php +++ b/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php @@ -164,7 +164,7 @@ public function process_token( $stackPtr ) { } } } - } // End if(). + } $parenthesisOpener = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true ); @@ -232,7 +232,7 @@ public function process_token( $stackPtr ) { $scopeOpener = $usePtr; } } - } // End if(). + } if ( T_COLON !== $this->tokens[ $parenthesisOpener ]['code'] @@ -273,7 +273,7 @@ public function process_token( $stackPtr ) { $this->phpcsFile->fixer->endChangeset(); } } - } // End if(). + } if ( T_WHITESPACE === $this->tokens[ ( $stackPtr + 1 ) ]['code'] @@ -376,7 +376,7 @@ public function process_token( $stackPtr ) { $this->phpcsFile->fixer->endChangeset(); } } - } // End if(). + } if ( isset( $this->tokens[ $parenthesisOpener ]['parenthesis_owner'] ) && ( isset( $scopeOpener ) @@ -416,8 +416,8 @@ public function process_token( $stackPtr ) { $this->phpcsFile->fixer->replaceToken( ( $parenthesisCloser + 1 ), ' ' ); $this->phpcsFile->fixer->endChangeset(); } - } // End if(). - } // End if(). + } + } if ( false !== $this->blank_line_check && isset( $scopeOpener ) ) { $firstContent = $this->phpcsFile->findNext( T_WHITESPACE, ( $scopeOpener + 1 ), null, true ); @@ -485,12 +485,12 @@ public function process_token( $stackPtr ) { $this->phpcsFile->fixer->endChangeset(); } break; - } // End if(). - } // End for(). - } // End if(). - } // End if(). + } + } + } + } unset( $ignore ); - } // End if(). + } if ( ! isset( $scopeCloser ) || true !== $this->blank_line_after_check ) { return; @@ -550,7 +550,7 @@ public function process_token( $stackPtr ) { $this->phpcsFile->fixer->endChangeset(); } } - } // End if(). + } } // End process_token(). diff --git a/WordPress/Sniffs/WhiteSpace/DisallowInlineTabsSniff.php b/WordPress/Sniffs/WhiteSpace/DisallowInlineTabsSniff.php index d3e2df2b..b817d33e 100644 --- a/WordPress/Sniffs/WhiteSpace/DisallowInlineTabsSniff.php +++ b/WordPress/Sniffs/WhiteSpace/DisallowInlineTabsSniff.php @@ -95,7 +95,7 @@ public function process_token( $stackPtr ) { $this->phpcsFile->fixer->replaceToken( $i, $newContent ); } } - } // End for(). + } // Ignore the rest of the file. return ( $this->phpcsFile->numTokens + 1 ); diff --git a/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php b/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php index 57978f9a..34176e9b 100644 --- a/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php +++ b/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php @@ -139,7 +139,7 @@ public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { } } } - } // End if(). + } $operator = $tokens[ $stackPtr ]['content']; @@ -170,7 +170,7 @@ public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { $phpcsFile->fixer->endChangeset(); } } - } // End if(). + } if ( '-' !== $operator ) { if ( T_WHITESPACE !== $tokens[ ( $stackPtr + 1 ) ]['code'] ) { @@ -197,9 +197,9 @@ public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { $phpcsFile->fixer->replaceToken( ( $stackPtr + 1 ), ' ' ); $phpcsFile->fixer->endChangeset(); } - } // End if(). - } // End if(). - } // End if(). + } + } + } } // End process(). diff --git a/WordPress/Sniffs/XSS/EscapeOutputSniff.php b/WordPress/Sniffs/XSS/EscapeOutputSniff.php index 5e654abb..52e2396e 100644 --- a/WordPress/Sniffs/XSS/EscapeOutputSniff.php +++ b/WordPress/Sniffs/XSS/EscapeOutputSniff.php @@ -384,7 +384,7 @@ public function process_token( $stackPtr ) { } else { $content = $this->tokens[ $i ]['content']; $ptr = $i; - } // End if(). + } $this->phpcsFile->addError( "Expected next thing to be an escaping function (see Codex for 'Data Validation'), not '%s'", @@ -392,7 +392,7 @@ public function process_token( $stackPtr ) { 'OutputNotEscaped', $content ); - } // End for(). + } return $end_of_statement; From b30338f54665beb10982958b95d5e1b99854f550 Mon Sep 17 00:00:00 2001 From: Barry Ceelen Date: Sun, 26 Mar 2017 14:27:59 +0200 Subject: [PATCH 051/282] Add 'slow query' flag to SlowDBQuerySniff --- WordPress/Sniffs/VIP/SlowDBQuerySniff.php | 8 +++++++- WordPress/Tests/VIP/SlowDBQueryUnitTest.inc | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/WordPress/Sniffs/VIP/SlowDBQuerySniff.php b/WordPress/Sniffs/VIP/SlowDBQuerySniff.php index 5cb08240..ddec07ad 100644 --- a/WordPress/Sniffs/VIP/SlowDBQuerySniff.php +++ b/WordPress/Sniffs/VIP/SlowDBQuerySniff.php @@ -42,6 +42,7 @@ public function getGroups() { * Processes this test, when one of its tokens is encountered. * * @since 0.10.0 + * @since 0.12.0 Introduced new 'slow query' whitelist comment. * * @param int $stackPtr The position of the current token in the stack. * @@ -50,7 +51,12 @@ public function getGroups() { */ public function process_token( $stackPtr ) { - if ( $this->has_whitelist_comment( 'tax_query', $stackPtr ) ) { + if ( + $this->has_whitelist_comment( 'slow query', $stackPtr ) + || + $this->has_whitelist_comment( 'tax_query', $stackPtr ) + ) { + return; } diff --git a/WordPress/Tests/VIP/SlowDBQueryUnitTest.inc b/WordPress/Tests/VIP/SlowDBQueryUnitTest.inc index cf40bacb..a4038c3f 100644 --- a/WordPress/Tests/VIP/SlowDBQueryUnitTest.inc +++ b/WordPress/Tests/VIP/SlowDBQueryUnitTest.inc @@ -28,7 +28,7 @@ $test = array( // Single-line statements. 'tax_query' => array(), // Bad. - 'tax_query' => array(), // WPCS: tax_query ok. + 'tax_query' => array(), // WPCS: slow query ok. // Multi-line statement. 'tax_query' => array( // WPCS: tax_query ok. From 317ad9527b36be1ef1f7e8845095aeea2d3454af Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 15 Jun 2017 21:20:45 +0200 Subject: [PATCH 052/282] Fix up the PR * Move the changelog comment from the function docblock to the class docblock. * Use `slow_query` instead of `slow query` (underscore, not space). * Throw a "deprecated whitelist comment" when the `tax_query` whitelist comment is encountered. * Prevent that message being thrown more than once. --- WordPress/Sniffs/VIP/SlowDBQuerySniff.php | 25 ++++++++++++++++----- WordPress/Tests/VIP/SlowDBQueryUnitTest.inc | 3 ++- WordPress/Tests/VIP/SlowDBQueryUnitTest.php | 1 + 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/WordPress/Sniffs/VIP/SlowDBQuerySniff.php b/WordPress/Sniffs/VIP/SlowDBQuerySniff.php index ddec07ad..9485cd41 100644 --- a/WordPress/Sniffs/VIP/SlowDBQuerySniff.php +++ b/WordPress/Sniffs/VIP/SlowDBQuerySniff.php @@ -15,6 +15,9 @@ * @package WPCS\WordPressCodingStandards * * @since 0.3.0 + * @since 0.12.0 Introduced new and more intuitively named 'slow query' whitelist + * comment, replacing the 'tax_query' whitelist comment which is now + * deprecated. */ class WordPress_Sniffs_VIP_SlowDBQuerySniff extends WordPress_AbstractArrayAssignmentRestrictionsSniff { @@ -42,7 +45,6 @@ public function getGroups() { * Processes this test, when one of its tokens is encountered. * * @since 0.10.0 - * @since 0.12.0 Introduced new 'slow query' whitelist comment. * * @param int $stackPtr The position of the current token in the stack. * @@ -51,11 +53,22 @@ public function getGroups() { */ public function process_token( $stackPtr ) { - if ( - $this->has_whitelist_comment( 'slow query', $stackPtr ) - || - $this->has_whitelist_comment( 'tax_query', $stackPtr ) - ) { + if ( $this->has_whitelist_comment( 'slow query', $stackPtr ) ) { + return; + } + + if ( $this->has_whitelist_comment( 'tax_query', $stackPtr ) ) { + /* + * Only throw the warning about a deprecated comment when the sniff would otherwise + * have been triggered on the array key. + */ + if ( in_array( $this->tokens[ $stackPtr ]['code'], array( T_CONSTANT_ENCAPSED_STRING, T_DOUBLE_QUOTED_STRING ), true ) ) { + $this->phpcsFile->addWarning( + 'The "tax_query" whitelist comment is deprecated in favor of the "slow query" whitelist comment.', + $stackPtr, + 'DeprecatedWhitelistFlagFound' + ); + } return; } diff --git a/WordPress/Tests/VIP/SlowDBQueryUnitTest.inc b/WordPress/Tests/VIP/SlowDBQueryUnitTest.inc index a4038c3f..6c8791aa 100644 --- a/WordPress/Tests/VIP/SlowDBQueryUnitTest.inc +++ b/WordPress/Tests/VIP/SlowDBQueryUnitTest.inc @@ -29,9 +29,10 @@ $test = array( // Single-line statements. 'tax_query' => array(), // Bad. 'tax_query' => array(), // WPCS: slow query ok. + 'tax_query' => array(), // WPCS: tax_query ok. // Multi-line statement. - 'tax_query' => array( // WPCS: tax_query ok. + 'tax_query' => array( // WPCS: slow query ok. array( 'taxonomy' => 'foo', ), diff --git a/WordPress/Tests/VIP/SlowDBQueryUnitTest.php b/WordPress/Tests/VIP/SlowDBQueryUnitTest.php index 57a0c4b5..7b1d4210 100644 --- a/WordPress/Tests/VIP/SlowDBQueryUnitTest.php +++ b/WordPress/Tests/VIP/SlowDBQueryUnitTest.php @@ -38,6 +38,7 @@ public function getWarningList() { 16 => 1, 19 => 2, 30 => 1, + 32 => 1, // Warning about deprecated whitelist comment. ); } From 6caf57c00955bb1d8e0e9429f232d632abf7a3d6 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 15 Jun 2017 21:15:16 +0200 Subject: [PATCH 053/282] Leverage the WordPress_Sniff class for (most of) the remaining sniffs Most WPCS sniffs extend the `WordPress_Sniff` class. However there were some which so far didn't. This PR changes that whenever possible. The affected sniffs do not necessarily *need* to use the `WordPress_Sniff` class as they don't use any of the utility methods or properties contained therein, however it will make future development slightly more intuitive as (nearly) all sniffs now follow the same pattern, as well as make life easier for the PHPCS 3.x branch which is being developed. The following exceptions still remain: * `WordPress_Sniffs_Arrays_ArrayDeclarationSniff extends Squiz_Sniffs_Arrays_ArrayDeclarationSniff` - this sniff is a partial copy of the upstream sniff with some commented out code * `WordPress_Sniffs_Arrays_ArrayDeclarationSpacingSniff extends Squiz_Sniffs_Arrays_ArrayDeclarationSniff` - this sniff uses the upstream sniff for the single line/multiline determination. Once the upstream sniff has been refactored into several sniffs, we may be able to decouple them. See upstream issue 582 * `WordPress_Sniffs_NamingConventions_ValidFunctionNameSniff extends PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff` - this sniff uses certain properties from the upstream sniff. We may choose to decouple this at some point by having a local copy of the relevant properties, though the maintenance burden would then also fall within WPCS. * `WordPress_Sniffs_NamingConventions_ValidVariableNameSniff extends PHP_CodeSniffer_Standards_AbstractVariableSniff` - uses the upstream abstract sniff logic for determination of variable vs property. --- .../ArrayKeySpacingRestrictionsSniff.php | 36 +++--- WordPress/Sniffs/PHP/YodaConditionsSniff.php | 34 +++--- .../Sniffs/VIP/SessionVariableUsageSniff.php | 21 ++-- .../Sniffs/WP/EnqueuedResourcesSniff.php | 24 ++-- .../WhiteSpace/CastStructureSpacingSniff.php | 22 ++-- .../WhiteSpace/OperatorSpacingSniff.php | 110 +++++++++--------- 6 files changed, 127 insertions(+), 120 deletions(-) diff --git a/WordPress/Sniffs/Arrays/ArrayKeySpacingRestrictionsSniff.php b/WordPress/Sniffs/Arrays/ArrayKeySpacingRestrictionsSniff.php index ba1147fc..851bf91e 100644 --- a/WordPress/Sniffs/Arrays/ArrayKeySpacingRestrictionsSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayKeySpacingRestrictionsSniff.php @@ -15,9 +15,10 @@ * @package WPCS\WordPressCodingStandards * * @since 0.3.0 - * @since 0.7.0 This sniff now has the ability to fix a number of the issues it flags. + * @since 0.7.0 This sniff now has the ability to fix a number of the issues it flags. + * @since 0.12.0 This class now extends WordPress_Sniff. */ -class WordPress_Sniffs_Arrays_ArrayKeySpacingRestrictionsSniff implements PHP_CodeSniffer_Sniff { +class WordPress_Sniffs_Arrays_ArrayKeySpacingRestrictionsSniff extends WordPress_Sniff { /** * Returns an array of tokens this test wants to listen for. @@ -34,52 +35,49 @@ public function register() { /** * Processes this test, when one of its tokens is encountered. * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. + * @param int $stackPtr The position of the current token in the stack. * * @return void */ - public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { - $tokens = $phpcsFile->getTokens(); + public function process_token( $stackPtr ) { - $token = $tokens[ $stackPtr ]; + $token = $this->tokens[ $stackPtr ]; if ( ! isset( $token['bracket_closer'] ) ) { - $phpcsFile->addWarning( 'Missing bracket closer.', $stackPtr, 'MissingBracketCloser' ); + $this->phpcsFile->addWarning( 'Missing bracket closer.', $stackPtr, 'MissingBracketCloser' ); return; } - $need_spaces = $phpcsFile->findNext( + $need_spaces = $this->phpcsFile->findNext( array( T_CONSTANT_ENCAPSED_STRING, T_LNUMBER, T_WHITESPACE, T_MINUS ), ( $stackPtr + 1 ), $token['bracket_closer'], true ); - $spaced1 = ( T_WHITESPACE === $tokens[ ( $stackPtr + 1 ) ]['code'] ); - $spaced2 = ( T_WHITESPACE === $tokens[ ( $token['bracket_closer'] - 1 ) ]['code'] ); + $spaced1 = ( T_WHITESPACE === $this->tokens[ ( $stackPtr + 1 ) ]['code'] ); + $spaced2 = ( T_WHITESPACE === $this->tokens[ ( $token['bracket_closer'] - 1 ) ]['code'] ); - // It should have spaces only if it only has strings or numbers as the key. + // It should have spaces unless if it only has strings or numbers as the key. if ( false !== $need_spaces && ! ( $spaced1 && $spaced2 ) ) { $error = 'Array keys must be surrounded by spaces unless they contain a string or an integer.'; - $fix = $phpcsFile->addFixableError( $error, $stackPtr, 'NoSpacesAroundArrayKeys' ); + $fix = $this->phpcsFile->addFixableError( $error, $stackPtr, 'NoSpacesAroundArrayKeys' ); if ( true === $fix ) { if ( ! $spaced1 ) { - $phpcsFile->fixer->addContentBefore( ( $stackPtr + 1 ), ' ' ); + $this->phpcsFile->fixer->addContentBefore( ( $stackPtr + 1 ), ' ' ); } if ( ! $spaced2 ) { - $phpcsFile->fixer->addContentBefore( $token['bracket_closer'], ' ' ); + $this->phpcsFile->fixer->addContentBefore( $token['bracket_closer'], ' ' ); } } } elseif ( false === $need_spaces && ( $spaced1 || $spaced2 ) ) { $error = 'Array keys must NOT be surrounded by spaces if they only contain a string or an integer.'; - $fix = $phpcsFile->addFixableError( $error, $stackPtr, 'SpacesAroundArrayKeys' ); + $fix = $this->phpcsFile->addFixableError( $error, $stackPtr, 'SpacesAroundArrayKeys' ); if ( true === $fix ) { if ( $spaced1 ) { - $phpcsFile->fixer->replaceToken( ( $stackPtr + 1 ), '' ); + $this->phpcsFile->fixer->replaceToken( ( $stackPtr + 1 ), '' ); } if ( $spaced2 ) { - $phpcsFile->fixer->replaceToken( ( $token['bracket_closer'] - 1 ), '' ); + $this->phpcsFile->fixer->replaceToken( ( $token['bracket_closer'] - 1 ), '' ); } } } diff --git a/WordPress/Sniffs/PHP/YodaConditionsSniff.php b/WordPress/Sniffs/PHP/YodaConditionsSniff.php index c20972e7..eddeaa7a 100644 --- a/WordPress/Sniffs/PHP/YodaConditionsSniff.php +++ b/WordPress/Sniffs/PHP/YodaConditionsSniff.php @@ -15,8 +15,9 @@ * @package WPCS\WordPressCodingStandards * * @since 0.3.0 + * @since 0.12.0 This class now extends WordPress_Sniff. */ -class WordPress_Sniffs_PHP_YodaConditionsSniff implements PHP_CodeSniffer_Sniff { +class WordPress_Sniffs_PHP_YodaConditionsSniff extends WordPress_Sniff { /** * Returns an array of tokens this test wants to listen for. @@ -36,20 +37,17 @@ public function register() { /** * Processes this test, when one of its tokens is encountered. * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token in the - * stack passed in $tokens. + * @param int $stackPtr The position of the current token in the stack. * * @return void */ - public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { - $tokens = $phpcsFile->getTokens(); + public function process_token( $stackPtr ) { $beginners = PHP_CodeSniffer_Tokens::$booleanOperators; $beginners[] = T_IF; $beginners[] = T_ELSEIF; - $beginning = $phpcsFile->findPrevious( $beginners, $stackPtr, null, false, null, true ); + $beginning = $this->phpcsFile->findPrevious( $beginners, $stackPtr, null, false, null, true ); $needs_yoda = false; @@ -57,18 +55,20 @@ public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { for ( $i = $stackPtr; $i > $beginning; $i-- ) { // Ignore whitespace. - if ( isset( PHP_CodeSniffer_Tokens::$emptyTokens[ $tokens[ $i ]['code'] ] ) ) { + if ( isset( PHP_CodeSniffer_Tokens::$emptyTokens[ $this->tokens[ $i ]['code'] ] ) ) { continue; } // If this is a variable or array, we've seen all we need to see. - if ( T_VARIABLE === $tokens[ $i ]['code'] || T_CLOSE_SQUARE_BRACKET === $tokens[ $i ]['code'] ) { + if ( T_VARIABLE === $this->tokens[ $i ]['code'] + || T_CLOSE_SQUARE_BRACKET === $this->tokens[ $i ]['code'] + ) { $needs_yoda = true; break; } // If this is a function call or something, we are OK. - if ( in_array( $tokens[ $i ]['code'], array( T_CONSTANT_ENCAPSED_STRING, T_CLOSE_PARENTHESIS, T_OPEN_PARENTHESIS, T_RETURN ), true ) ) { + if ( in_array( $this->tokens[ $i ]['code'], array( T_CONSTANT_ENCAPSED_STRING, T_CLOSE_PARENTHESIS, T_OPEN_PARENTHESIS, T_RETURN ), true ) ) { return; } } @@ -78,14 +78,14 @@ public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { } // Check if this is a var to var comparison, e.g.: if ( $var1 == $var2 ). - $next_non_empty = $phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true ); + $next_non_empty = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true ); - if ( isset( PHP_CodeSniffer_Tokens::$castTokens[ $tokens[ $next_non_empty ]['code'] ] ) ) { - $next_non_empty = $phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $next_non_empty + 1 ), null, true ); + if ( isset( PHP_CodeSniffer_Tokens::$castTokens[ $this->tokens[ $next_non_empty ]['code'] ] ) ) { + $next_non_empty = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $next_non_empty + 1 ), null, true ); } - if ( in_array( $tokens[ $next_non_empty ]['code'], array( T_SELF, T_PARENT, T_STATIC ), true ) ) { - $next_non_empty = $phpcsFile->findNext( + if ( in_array( $this->tokens[ $next_non_empty ]['code'], array( T_SELF, T_PARENT, T_STATIC ), true ) ) { + $next_non_empty = $this->phpcsFile->findNext( array_merge( PHP_CodeSniffer_Tokens::$emptyTokens, array( T_DOUBLE_COLON ) ) , ( $next_non_empty + 1 ) , null @@ -93,11 +93,11 @@ public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { ); } - if ( T_VARIABLE === $tokens[ $next_non_empty ]['code'] ) { + if ( T_VARIABLE === $this->tokens[ $next_non_empty ]['code'] ) { return; } - $phpcsFile->addError( 'Use Yoda Condition checks, you must.', $stackPtr, 'NotYoda' ); + $this->phpcsFile->addError( 'Use Yoda Condition checks, you must.', $stackPtr, 'NotYoda' ); } // End process(). diff --git a/WordPress/Sniffs/VIP/SessionVariableUsageSniff.php b/WordPress/Sniffs/VIP/SessionVariableUsageSniff.php index 70db76e0..f4b48639 100644 --- a/WordPress/Sniffs/VIP/SessionVariableUsageSniff.php +++ b/WordPress/Sniffs/VIP/SessionVariableUsageSniff.php @@ -18,8 +18,9 @@ * @since 0.3.0 * @since 0.10.0 The sniff no longer needlessly extends the Generic_Sniffs_PHP_ForbiddenFunctionsSniff * which it didn't use. + * @since 0.12.0 This class now extends WordPress_Sniff. */ -class WordPress_Sniffs_VIP_SessionVariableUsageSniff implements PHP_CodeSniffer_Sniff { +class WordPress_Sniffs_VIP_SessionVariableUsageSniff extends WordPress_Sniff { /** * Returns an array of tokens this test wants to listen for. @@ -36,18 +37,18 @@ public function register() { /** * Processes this test, when one of its tokens is encountered. * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. + * @param int $stackPtr The position of the current token in the stack. + * * @return void */ - public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { - $tokens = $phpcsFile->getTokens(); - - if ( '$_SESSION' === $tokens[ $stackPtr ]['content'] ) { - $phpcsFile->addError( 'Usage of $_SESSION variable is prohibited.', $stackPtr, 'SessionVarsProhibited' ); + public function process_token( $stackPtr ) { + if ( '$_SESSION' === $this->tokens[ $stackPtr ]['content'] ) { + $this->phpcsFile->addError( + 'Usage of $_SESSION variable is prohibited.', + $stackPtr, + 'SessionVarsProhibited' + ); } - } } // End class. diff --git a/WordPress/Sniffs/WP/EnqueuedResourcesSniff.php b/WordPress/Sniffs/WP/EnqueuedResourcesSniff.php index 6b0ddfd3..8b2fe574 100644 --- a/WordPress/Sniffs/WP/EnqueuedResourcesSniff.php +++ b/WordPress/Sniffs/WP/EnqueuedResourcesSniff.php @@ -15,8 +15,9 @@ * @package WPCS\WordPressCodingStandards * * @since 0.3.0 + * @since 0.12.0 This class now extends WordPress_Sniff. */ -class WordPress_Sniffs_WP_EnqueuedResourcesSniff implements PHP_CodeSniffer_Sniff { +class WordPress_Sniffs_WP_EnqueuedResourcesSniff extends WordPress_Sniff { /** * Returns an array of tokens this test wants to listen for. @@ -30,22 +31,27 @@ public function register() { /** * Processes this test, when one of its tokens is encountered. * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. + * @param int $stackPtr The position of the current token in the stack. * * @return void */ - public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { - $tokens = $phpcsFile->getTokens(); - $token = $tokens[ $stackPtr ]; + public function process_token( $stackPtr ) { + $token = $this->tokens[ $stackPtr ]; if ( preg_match( '#rel=\\\\?[\'"]?stylesheet\\\\?[\'"]?#', $token['content'] ) > 0 ) { - $phpcsFile->addError( 'Stylesheets must be registered/enqueued via wp_enqueue_style', $stackPtr, 'NonEnqueuedStylesheet' ); + $this->phpcsFile->addError( + 'Stylesheets must be registered/enqueued via wp_enqueue_style', + $stackPtr, + 'NonEnqueuedStylesheet' + ); } if ( preg_match( '#]*(?<=src=)#', $token['content'] ) > 0 ) { - $phpcsFile->addError( 'Scripts must be registered/enqueued via wp_enqueue_script', $stackPtr, 'NonEnqueuedScript' ); + $this->phpcsFile->addError( + 'Scripts must be registered/enqueued via wp_enqueue_script', + $stackPtr, + 'NonEnqueuedScript' + ); } } // End process(). diff --git a/WordPress/Sniffs/WhiteSpace/CastStructureSpacingSniff.php b/WordPress/Sniffs/WhiteSpace/CastStructureSpacingSniff.php index 5c4a646c..16bc7de9 100755 --- a/WordPress/Sniffs/WhiteSpace/CastStructureSpacingSniff.php +++ b/WordPress/Sniffs/WhiteSpace/CastStructureSpacingSniff.php @@ -17,8 +17,9 @@ * @since 0.3.0 * @since 0.11.0 This sniff now has the ability to fix the issues it flags. * @since 0.11.0 The error level for all errors thrown by this sniff has been raised from warning to error. + * @since 0.12.0 This class now extends WordPress_Sniff. */ -class WordPress_Sniffs_WhiteSpace_CastStructureSpacingSniff implements PHP_CodeSniffer_Sniff { +class WordPress_Sniffs_WhiteSpace_CastStructureSpacingSniff extends WordPress_Sniff { /** * Returns an array of tokens this test wants to listen for. @@ -32,28 +33,25 @@ public function register() { /** * Processes this test, when one of its tokens is encountered. * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token in the - * stack passed in $tokens. + * @param int $stackPtr The position of the current token in the stack. * * @return void */ - public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { - $tokens = $phpcsFile->getTokens(); + public function process_token( $stackPtr ) { - if ( T_WHITESPACE !== $tokens[ ( $stackPtr - 1 ) ]['code'] ) { + if ( T_WHITESPACE !== $this->tokens[ ( $stackPtr - 1 ) ]['code'] ) { $error = 'No space before opening casting parenthesis is prohibited'; - $fix = $phpcsFile->addFixableError( $error, $stackPtr, 'NoSpaceBeforeOpenParenthesis' ); + $fix = $this->phpcsFile->addFixableError( $error, $stackPtr, 'NoSpaceBeforeOpenParenthesis' ); if ( true === $fix ) { - $phpcsFile->fixer->addContentBefore( $stackPtr, ' ' ); + $this->phpcsFile->fixer->addContentBefore( $stackPtr, ' ' ); } } - if ( T_WHITESPACE !== $tokens[ ( $stackPtr + 1 ) ]['code'] ) { + if ( T_WHITESPACE !== $this->tokens[ ( $stackPtr + 1 ) ]['code'] ) { $error = 'No space after closing casting parenthesis is prohibited'; - $fix = $phpcsFile->addFixableError( $error, $stackPtr, 'NoSpaceAfterCloseParenthesis' ); + $fix = $this->phpcsFile->addFixableError( $error, $stackPtr, 'NoSpaceAfterCloseParenthesis' ); if ( true === $fix ) { - $phpcsFile->fixer->addContent( $stackPtr, ' ' ); + $this->phpcsFile->fixer->addContent( $stackPtr, ' ' ); } } } diff --git a/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php b/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php index 34176e9b..cf2dc24b 100644 --- a/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php +++ b/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php @@ -18,11 +18,12 @@ * * @since 0.1.0 * @since 0.3.0 This sniff now has the ability to fix the issues it flags. + * @since 0.12.0 This class now extends WordPress_Sniff. * * Last synced with base class December 2008 at commit f01746fd1c89e98174b16c76efd325825eb58bf1. * @link https://github.com/squizlabs/PHP_CodeSniffer/blob/master/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/OperatorSpacingSniff.php */ -class WordPress_Sniffs_WhiteSpace_OperatorSpacingSniff implements PHP_CodeSniffer_Sniff { +class WordPress_Sniffs_WhiteSpace_OperatorSpacingSniff extends WordPress_Sniff { /** * A list of tokenizers this sniff supports. @@ -53,32 +54,31 @@ public function register() { } /** - * Processes this sniff, when one of its tokens is encountered. + * Processes this test, when one of its tokens is encountered. * - * @param PHP_CodeSniffer_File $phpcsFile The current file being checked. - * @param int $stackPtr The position of the current token in the - * stack passed in $tokens. + * @param int $stackPtr The position of the current token in the stack. * * @return void */ - public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { - $tokens = $phpcsFile->getTokens(); + public function process_token( $stackPtr ) { - if ( T_EQUAL === $tokens[ $stackPtr ]['code'] ) { + if ( T_EQUAL === $this->tokens[ $stackPtr ]['code'] ) { // Skip for '=&' case. - if ( isset( $tokens[ ( $stackPtr + 1 ) ] ) && T_BITWISE_AND === $tokens[ ( $stackPtr + 1 ) ]['code'] ) { + if ( isset( $this->tokens[ ( $stackPtr + 1 ) ] ) + && T_BITWISE_AND === $this->tokens[ ( $stackPtr + 1 ) ]['code'] + ) { return; } // Skip default values in function declarations. // Skip declare statements. - if ( isset( $tokens[ $stackPtr ]['nested_parenthesis'] ) ) { - $bracket = end( $tokens[ $stackPtr ]['nested_parenthesis'] ); - if ( isset( $tokens[ $bracket ]['parenthesis_owner'] ) ) { - $function = $tokens[ $bracket ]['parenthesis_owner']; - if ( T_FUNCTION === $tokens[ $function ]['code'] - || T_CLOSURE === $tokens[ $function ]['code'] - || T_DECLARE === $tokens[ $function ]['code'] + if ( isset( $this->tokens[ $stackPtr ]['nested_parenthesis'] ) ) { + $bracket = end( $this->tokens[ $stackPtr ]['nested_parenthesis'] ); + if ( isset( $this->tokens[ $bracket ]['parenthesis_owner'] ) ) { + $function = $this->tokens[ $bracket ]['parenthesis_owner']; + if ( T_FUNCTION === $this->tokens[ $function ]['code'] + || T_CLOSURE === $this->tokens[ $function ]['code'] + || T_DECLARE === $this->tokens[ $function ]['code'] ) { return; } @@ -86,32 +86,32 @@ public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { } } - if ( T_BITWISE_AND === $tokens[ $stackPtr ]['code'] ) { + if ( T_BITWISE_AND === $this->tokens[ $stackPtr ]['code'] ) { /* // If it's not a reference, then we expect one space either side of the // bitwise operator. - if ( false === $phpcsFile->isReference( $stackPtr ) ) { + if ( false === $this->phpcsFile->isReference( $stackPtr ) ) { // @todo Implement or remove ? } */ return; } else { - if ( T_MINUS === $tokens[ $stackPtr ]['code'] ) { + if ( T_MINUS === $this->tokens[ $stackPtr ]['code'] ) { // Check minus spacing, but make sure we aren't just assigning // a minus value or returning one. - $prev = $phpcsFile->findPrevious( T_WHITESPACE, ( $stackPtr - 1 ), null, true ); - if ( T_RETURN === $tokens[ $prev ]['code'] ) { + $prev = $this->phpcsFile->findPrevious( T_WHITESPACE, ( $stackPtr - 1 ), null, true ); + if ( T_RETURN === $this->tokens[ $prev ]['code'] ) { // Just returning a negative value; eg. return -1. return; } - if ( isset( PHP_CodeSniffer_Tokens::$operators[ $tokens[ $prev ]['code'] ] ) ) { + if ( isset( PHP_CodeSniffer_Tokens::$operators[ $this->tokens[ $prev ]['code'] ] ) ) { // Just trying to operate on a negative value; eg. ($var * -1). return; } - if ( isset( PHP_CodeSniffer_Tokens::$comparisonTokens[ $tokens[ $prev ]['code'] ] ) ) { + if ( isset( PHP_CodeSniffer_Tokens::$comparisonTokens[ $this->tokens[ $prev ]['code'] ] ) ) { // Just trying to compare a negative value; eg. ($var === -1). return; } @@ -124,16 +124,18 @@ public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { T_OPEN_SQUARE_BRACKET, ); - if ( in_array( $tokens[ $prev ]['code'], $invalidTokens, true ) ) { + if ( in_array( $this->tokens[ $prev ]['code'], $invalidTokens, true ) ) { // Just trying to use a negative value; eg. myFunction($var, -2). return; } - $number = $phpcsFile->findNext( T_WHITESPACE, ( $stackPtr + 1 ), null, true ); - if ( T_LNUMBER === $tokens[ $number ]['code'] ) { - $semi = $phpcsFile->findNext( T_WHITESPACE, ( $number + 1 ), null, true ); - if ( T_SEMICOLON === $tokens[ $semi ]['code'] ) { - if ( false !== $prev && isset( PHP_CodeSniffer_Tokens::$assignmentTokens[ $tokens[ $prev ]['code'] ] ) ) { + $number = $this->phpcsFile->findNext( T_WHITESPACE, ( $stackPtr + 1 ), null, true ); + if ( T_LNUMBER === $this->tokens[ $number ]['code'] ) { + $semi = $this->phpcsFile->findNext( T_WHITESPACE, ( $number + 1 ), null, true ); + if ( T_SEMICOLON === $this->tokens[ $semi ]['code'] ) { + if ( false !== $prev && + isset( PHP_CodeSniffer_Tokens::$assignmentTokens[ $this->tokens[ $prev ]['code'] ] ) + ) { // This is a negative assignment. return; } @@ -141,61 +143,63 @@ public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { } } - $operator = $tokens[ $stackPtr ]['content']; + $operator = $this->tokens[ $stackPtr ]['content']; - if ( T_WHITESPACE !== $tokens[ ( $stackPtr - 1 ) ]['code'] ) { + if ( T_WHITESPACE !== $this->tokens[ ( $stackPtr - 1 ) ]['code'] ) { $error = 'Expected 1 space before "%s"; 0 found'; $data = array( $operator ); - $fix = $phpcsFile->addFixableError( $error, $stackPtr, 'NoSpaceBefore', $data ); + $fix = $this->phpcsFile->addFixableError( $error, $stackPtr, 'NoSpaceBefore', $data ); if ( true === $fix ) { - $phpcsFile->fixer->beginChangeset(); - $phpcsFile->fixer->addContentBefore( $stackPtr, ' ' ); - $phpcsFile->fixer->endChangeset(); + $this->phpcsFile->fixer->beginChangeset(); + $this->phpcsFile->fixer->addContentBefore( $stackPtr, ' ' ); + $this->phpcsFile->fixer->endChangeset(); } - } elseif ( 1 !== strlen( $tokens[ ( $stackPtr - 1 ) ]['content'] ) && 1 !== $tokens[ ( $stackPtr - 1 ) ]['column'] ) { + } elseif ( 1 !== strlen( $this->tokens[ ( $stackPtr - 1 ) ]['content'] ) + && 1 !== $this->tokens[ ( $stackPtr - 1 ) ]['column'] + ) { // Don't throw an error for assignments, because other standards allow // multiple spaces there to align multiple assignments. - if ( false === isset( PHP_CodeSniffer_Tokens::$assignmentTokens[ $tokens[ $stackPtr ]['code'] ] ) ) { - $found = strlen( $tokens[ ( $stackPtr - 1 ) ]['content'] ); + if ( false === isset( PHP_CodeSniffer_Tokens::$assignmentTokens[ $this->tokens[ $stackPtr ]['code'] ] ) ) { + $found = strlen( $this->tokens[ ( $stackPtr - 1 ) ]['content'] ); $error = 'Expected 1 space before "%s"; %s found'; $data = array( $operator, $found, ); - $fix = $phpcsFile->addFixableError( $error, $stackPtr, 'SpacingBefore', $data ); + $fix = $this->phpcsFile->addFixableError( $error, $stackPtr, 'SpacingBefore', $data ); if ( true === $fix ) { - $phpcsFile->fixer->beginChangeset(); - $phpcsFile->fixer->replaceToken( ( $stackPtr - 1 ), ' ' ); - $phpcsFile->fixer->endChangeset(); + $this->phpcsFile->fixer->beginChangeset(); + $this->phpcsFile->fixer->replaceToken( ( $stackPtr - 1 ), ' ' ); + $this->phpcsFile->fixer->endChangeset(); } } } if ( '-' !== $operator ) { - if ( T_WHITESPACE !== $tokens[ ( $stackPtr + 1 ) ]['code'] ) { + if ( T_WHITESPACE !== $this->tokens[ ( $stackPtr + 1 ) ]['code'] ) { $error = 'Expected 1 space after "%s"; 0 found'; $data = array( $operator ); - $fix = $phpcsFile->addFixableError( $error, $stackPtr, 'NoSpaceAfter', $data ); + $fix = $this->phpcsFile->addFixableError( $error, $stackPtr, 'NoSpaceAfter', $data ); if ( true === $fix ) { - $phpcsFile->fixer->beginChangeset(); - $phpcsFile->fixer->addContent( $stackPtr, ' ' ); - $phpcsFile->fixer->endChangeset(); + $this->phpcsFile->fixer->beginChangeset(); + $this->phpcsFile->fixer->addContent( $stackPtr, ' ' ); + $this->phpcsFile->fixer->endChangeset(); } - } elseif ( 1 !== strlen( $tokens[ ( $stackPtr + 1 ) ]['content'] ) ) { - $found = strlen( $tokens[ ( $stackPtr + 1 ) ]['content'] ); + } elseif ( 1 !== strlen( $this->tokens[ ( $stackPtr + 1 ) ]['content'] ) ) { + $found = strlen( $this->tokens[ ( $stackPtr + 1 ) ]['content'] ); $error = 'Expected 1 space after "%s"; %s found'; $data = array( $operator, $found, ); - $fix = $phpcsFile->addFixableError( $error, $stackPtr, 'SpacingAfter', $data ); + $fix = $this->phpcsFile->addFixableError( $error, $stackPtr, 'SpacingAfter', $data ); if ( true === $fix ) { - $phpcsFile->fixer->beginChangeset(); - $phpcsFile->fixer->replaceToken( ( $stackPtr + 1 ), ' ' ); - $phpcsFile->fixer->endChangeset(); + $this->phpcsFile->fixer->beginChangeset(); + $this->phpcsFile->fixer->replaceToken( ( $stackPtr + 1 ), ' ' ); + $this->phpcsFile->fixer->endChangeset(); } } } From edb353a66b8cab651b1a68a8beb82f04abf1607c Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 17 Jun 2017 04:14:13 +0200 Subject: [PATCH 054/282] :sparkles: New sniff: FunctionCallSignatureNoParams Report on and remove whitespace between function call parenthesis when the function call has no parameters. This sniff *will* result in contradictory messages when run with PHPCS, but that can't really be helped. ``` 5 | ERROR | [x] Expected 1 spaces after opening bracket; 6 found | | (PEAR.Functions.FunctionCallSignature.SpaceAfterOpenBracket) 5 | ERROR | [x] Expected 1 spaces before closing bracket; 6 found | | (PEAR.Functions.FunctionCallSignature.SpaceBeforeCloseBracket) 5 | ERROR | [x] Function calls without parameters should have no spaces | | between the parenthesis. | | (WordPress.Functions.FunctionCallSignatureNoParams.WhitespaceFound) ``` Includes an auto-fixer. This auto-fixer has been tested to not conflict with the `PEAR.Functions.FunctionCallSignature` sniff. Fixes issue 970 --- WordPress-Core/ruleset.xml | 2 + .../FunctionCallSignatureNoParamsSniff.php | 86 +++++++++++++++++++ .../FunctionCallSignatureNoParamsUnitTest.inc | 9 ++ ...ionCallSignatureNoParamsUnitTest.inc.fixed | 9 ++ .../FunctionCallSignatureNoParamsUnitTest.php | 40 +++++++++ 5 files changed, 146 insertions(+) create mode 100644 WordPress/Sniffs/Functions/FunctionCallSignatureNoParamsSniff.php create mode 100644 WordPress/Tests/Functions/FunctionCallSignatureNoParamsUnitTest.inc create mode 100644 WordPress/Tests/Functions/FunctionCallSignatureNoParamsUnitTest.inc.fixed create mode 100644 WordPress/Tests/Functions/FunctionCallSignatureNoParamsUnitTest.php diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index 1f90007c..3e821d28 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -171,6 +171,8 @@ 0 + + diff --git a/WordPress/Sniffs/Functions/FunctionCallSignatureNoParamsSniff.php b/WordPress/Sniffs/Functions/FunctionCallSignatureNoParamsSniff.php new file mode 100644 index 00000000..1d9bcafc --- /dev/null +++ b/WordPress/Sniffs/Functions/FunctionCallSignatureNoParamsSniff.php @@ -0,0 +1,86 @@ +phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true ); + + if ( T_OPEN_PARENTHESIS !== $this->tokens[ $openParenthesis ]['code'] ) { + // Not a function call. + return; + } + + if ( ! isset( $this->tokens[ $openParenthesis ]['parenthesis_closer'] ) ) { + // Not a function call. + return; + } + + // Find the previous non-empty token. + $search = PHP_CodeSniffer_Tokens::$emptyTokens; + $search[] = T_BITWISE_AND; + $previous = $this->phpcsFile->findPrevious( $search, ( $stackPtr - 1 ), null, true ); + if ( T_FUNCTION === $this->tokens[ $previous ]['code'] ) { + // It's a function definition, not a function call. + return; + } + + $closer = $this->tokens[ $openParenthesis ]['parenthesis_closer']; + + if ( ( $closer - 1 ) === $openParenthesis ) { + return; + } + + $nextNonWhitespace = $this->phpcsFile->findNext( T_WHITESPACE, ( $openParenthesis + 1 ), null, true ); + + if ( $nextNonWhitespace !== $closer ) { + // Function has params or comment between parenthesis. + return; + } + + $fix = $this->phpcsFile->addFixableError( + 'Function calls without parameters should have no spaces between the parenthesis.', + ( $openParenthesis + 1 ), + 'WhitespaceFound' + ); + if ( true === $fix ) { + // If there is only whitespace between the parenthesis, it will just be the one token. + $this->phpcsFile->fixer->replaceToken( ( $openParenthesis + 1 ), '' ); + } + + } // End process_token(). + +} // End class. diff --git a/WordPress/Tests/Functions/FunctionCallSignatureNoParamsUnitTest.inc b/WordPress/Tests/Functions/FunctionCallSignatureNoParamsUnitTest.inc new file mode 100644 index 00000000..788da75d --- /dev/null +++ b/WordPress/Tests/Functions/FunctionCallSignatureNoParamsUnitTest.inc @@ -0,0 +1,9 @@ + => + */ + public function getErrorList() { + return array( + 4 => 1, + 5 => 1, + ); + } + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array(); + + } + +} // End class. From 330da2853edc0c228d7b87ac838e76496e3b1d52 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 17 Jun 2017 20:33:10 +0200 Subject: [PATCH 055/282] :sparkles: New `CodeAnalysis.EmptyStatement` sniff New sniff to detect superfluous semi-colons and empty PHP open-close tag combinations. Includes an auto-fixer. Added into a new `CodeAnalysis` category to be in line with the related upstream sniff. As these issues are not explicitly mentioned in the WP Core Coding Style Handbook and are more along the lines of best practices, I've added the sniff to the `WordPress-Extra` ruleset. For that same reason, I've elected to let the sniff throw warnings instead of errors. For the current WP Core codestyle update, it would, however, be advisable to explicitly enable this sniff from the ruleset as issues which this sniff will fix, *have* already been detected in WP Core during a visual inspection. Fixes 975 N.B. This sniff should eventually be merged with the upstream `Generic.CodeAnalysis.EmptyStatement` sniff and pulled there. This would fix upstream issue #1119. --- WordPress-Extra/ruleset.xml | 1 + .../CodeAnalysis/EmptyStatementSniff.php | 138 ++++++++++++++++++ .../CodeAnalysis/EmptyStatementUnitTest.inc | 45 ++++++ .../EmptyStatementUnitTest.inc.fixed | 40 +++++ .../CodeAnalysis/EmptyStatementUnitTest.php | 47 ++++++ 5 files changed, 271 insertions(+) create mode 100644 WordPress/Sniffs/CodeAnalysis/EmptyStatementSniff.php create mode 100644 WordPress/Tests/CodeAnalysis/EmptyStatementUnitTest.inc create mode 100644 WordPress/Tests/CodeAnalysis/EmptyStatementUnitTest.inc.fixed create mode 100644 WordPress/Tests/CodeAnalysis/EmptyStatementUnitTest.php diff --git a/WordPress-Extra/ruleset.xml b/WordPress-Extra/ruleset.xml index dcfa0358..8d6e2ce2 100644 --- a/WordPress-Extra/ruleset.xml +++ b/WordPress-Extra/ruleset.xml @@ -20,6 +20,7 @@ + diff --git a/WordPress/Sniffs/CodeAnalysis/EmptyStatementSniff.php b/WordPress/Sniffs/CodeAnalysis/EmptyStatementSniff.php new file mode 100644 index 00000000..07ad7d47 --- /dev/null +++ b/WordPress/Sniffs/CodeAnalysis/EmptyStatementSniff.php @@ -0,0 +1,138 @@ +tokens[ $stackPtr ]['type'] ) { + /* + * Detect `something();;`. + */ + case 'T_SEMICOLON': + $prevNonEmpty = $this->phpcsFile->findPrevious( + PHP_CodeSniffer_Tokens::$emptyTokens, + ( $stackPtr - 1 ), + null, + true + ); + + if ( false === $prevNonEmpty + || ( T_SEMICOLON !== $this->tokens[ $prevNonEmpty ]['code'] + && T_OPEN_TAG !== $this->tokens[ $prevNonEmpty ]['code'] ) + ) { + return; + } + + $fix = $this->phpcsFile->addFixableWarning( + 'Empty PHP statement detected: superfluous semi-colon.', + $stackPtr, + 'SemicolonWithoutCodeDetected' + ); + if ( true === $fix ) { + $this->phpcsFile->fixer->beginChangeset(); + + if ( T_OPEN_TAG === $this->tokens[ $prevNonEmpty ]['code'] ) { + /* + * Check for superfluous whitespace after the semi-colon which will be + * removed as the `tokens[ ( $stackPtr + 1 ) ]['code'] ) { + $replacement = str_replace( ' ', '', $this->tokens[ ( $stackPtr + 1 ) ]['content'] ); + $this->phpcsFile->fixer->replaceToken( ( $stackPtr + 1 ), $replacement ); + } + } + + for ( $i = $stackPtr; $i > $prevNonEmpty; $i-- ) { + if ( T_SEMICOLON !== $this->tokens[ $i ]['code'] + && T_WHITESPACE !== $this->tokens[ $i ]['code'] + ) { + break; + } + $this->phpcsFile->fixer->replaceToken( $i, '' ); + } + + $this->phpcsFile->fixer->endChangeset(); + } + break; + + /* + * Detect ``. + */ + case 'T_CLOSE_TAG': + $prevNonEmpty = $this->phpcsFile->findPrevious( + T_WHITESPACE, + ( $stackPtr - 1 ), + null, + true + ); + + if ( false === $prevNonEmpty || T_OPEN_TAG !== $this->tokens[ $prevNonEmpty ]['code'] ) { + return; + } + + $fix = $this->phpcsFile->addFixableWarning( + 'Empty PHP open/close tag combination detected.', + $prevNonEmpty, + 'EmptyPHPOpenCloseTagsDetected' + ); + if ( true === $fix ) { + $this->phpcsFile->fixer->beginChangeset(); + for ( $i = $prevNonEmpty; $i <= $stackPtr; $i++ ) { + $this->phpcsFile->fixer->replaceToken( $i, '' ); + } + $this->phpcsFile->fixer->endChangeset(); + } + break; + + default: + /* Deliberately left empty. */ + break; + } + + } // End process_token(). + +} // End class. diff --git a/WordPress/Tests/CodeAnalysis/EmptyStatementUnitTest.inc b/WordPress/Tests/CodeAnalysis/EmptyStatementUnitTest.inc new file mode 100644 index 00000000..710099b4 --- /dev/null +++ b/WordPress/Tests/CodeAnalysis/EmptyStatementUnitTest.inc @@ -0,0 +1,45 @@ + + + + +/* + * Test empty statement: no code between PHP open and close tag. + */ + + + + + + + + + + + + diff --git a/WordPress/Tests/CodeAnalysis/EmptyStatementUnitTest.inc.fixed b/WordPress/Tests/CodeAnalysis/EmptyStatementUnitTest.inc.fixed new file mode 100644 index 00000000..d036c214 --- /dev/null +++ b/WordPress/Tests/CodeAnalysis/EmptyStatementUnitTest.inc.fixed @@ -0,0 +1,40 @@ + + + + +/* + * Test empty statement: no code between PHP open and close tag. + */ + + + + + + + + + + + diff --git a/WordPress/Tests/CodeAnalysis/EmptyStatementUnitTest.php b/WordPress/Tests/CodeAnalysis/EmptyStatementUnitTest.php new file mode 100644 index 00000000..6e62ad81 --- /dev/null +++ b/WordPress/Tests/CodeAnalysis/EmptyStatementUnitTest.php @@ -0,0 +1,47 @@ + => + */ + public function getErrorList() { + return array(); + } + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array( + 9 => 1, + 12 => 1, + 15 => 1, + 18 => 1, + 21 => 1, + 22 => 1, + 31 => 1, + 33 => 1, + 43 => 1, + 45 => 1, + ); + } + +} // End class. From e971d3210ee8dce5edf568dd60fcd9774e3a0805 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 18 Jun 2017 03:31:31 +0200 Subject: [PATCH 056/282] ControlStructureSpacing sniff: add unit test for disappearing comment --- .../WhiteSpace/ControlStructureSpacingUnitTest.inc | 11 +++++++++++ .../ControlStructureSpacingUnitTest.inc.fixed | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc b/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc index dbd0d4e4..4c97c594 100644 --- a/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc +++ b/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc @@ -211,3 +211,14 @@ if ( ) { // Ok. echo 'bye'; } + +// Bug #976 - the case of the disappearing comment. +if ( isset( $submenu_file ) ) { + if ( $submenu_file == $sub_item[2] ) { + $class[] = 'current'; + } +// If plugin_page is set the parent must either match the current page or not physically exist. +// This allows plugin pages with the same hook to exist under different parents. +} else { + $class[] = 'current'; +} diff --git a/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc.fixed b/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc.fixed index 62753b57..4f1e8171 100644 --- a/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc.fixed +++ b/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc.fixed @@ -206,3 +206,14 @@ if ( ) { // Ok. echo 'bye'; } + +// Bug #976 - the case of the disappearing comment. +if ( isset( $submenu_file ) ) { + if ( $submenu_file == $sub_item[2] ) { + $class[] = 'current'; + } +// If plugin_page is set the parent must either match the current page or not physically exist. +// This allows plugin pages with the same hook to exist under different parents. +} else { + $class[] = 'current'; +} From b747adc5afc9a97dd37c339a6f2231f5a141de9e Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 18 Jun 2017 03:40:13 +0200 Subject: [PATCH 057/282] Revert "ControlStructureSpacing: No need to check separately for comments." This effectively reverts commit 786c9bb5855b3bdeb6c33852dd92f089b160a5fa. --- .../WhiteSpace/ControlStructureSpacingSniff.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php b/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php index dde402c1..c027d997 100644 --- a/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php +++ b/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php @@ -496,7 +496,8 @@ public function process_token( $stackPtr ) { return; } - $trailingContent = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $scopeCloser + 1 ), null, true ); + // {@internal This is just for the blank line check. Only whitespace should be considered.}} + $trailingContent = $this->phpcsFile->findNext( T_WHITESPACE, ( $scopeCloser + 1 ), null, true ); if ( false === $trailingContent ) { return; } @@ -506,6 +507,16 @@ public function process_token( $stackPtr ) { return; } + if ( T_COMMENT === $this->tokens[ $trailingContent ]['code'] ) { + if ( $this->tokens[ $trailingContent ]['line'] === $this->tokens[ $scopeCloser ]['line'] ) { + if ( '//end' === substr( $this->tokens[ $trailingContent ]['content'], 0, 5 ) ) { + // There is an end comment, so we have to get the next piece + // of content. + $trailingContent = $this->phpcsFile->findNext( T_WHITESPACE, ( $trailingContent + 1), null, true ); + } + } + } + if ( T_BREAK === $this->tokens[ $trailingContent ]['code'] ) { // If this BREAK is closing a CASE, we don't need the // blank line after this control structure. From a5bb8e0a43661410792e997fbc645d81659ccd31 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 18 Jun 2017 19:05:06 +0200 Subject: [PATCH 058/282] Minor tweak: use original content for indentation determination The tokenizer sometimes replaces tabs with spaces in the token `content`. Instead of undoing this with a `str_replace()`, use the `orig_content` instead for higher accuracy. --- WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php | 7 +++++-- WordPress/Sniffs/Arrays/ArrayIndentationSniff.php | 9 ++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php index b982d182..7890969c 100644 --- a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php @@ -164,8 +164,11 @@ protected function fix_associative_array( PHP_CodeSniffer_File $phpcsFile, $arra } if ( T_WHITESPACE === $tokens[ ( $i + 1 ) ]['code'] ) { - // Something weird going on with tabs vs spaces, but this fixes it. - $indentation = str_replace( ' ', "\t", $tokens[ ( $i + 1 ) ]['content'] ); + // If the tokenizer replaced tabs with spaces, use the original content. + $indentation = $tokens[ ( $i + 1 ) ]['content']; + if ( isset( $tokens[ ( $i + 1 ) ]['orig_content'] ) ) { + $indentation = $tokens[ ( $i + 1 ) ]['orig_content']; + } } break; } diff --git a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php index a0ae020d..141336f0 100644 --- a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php @@ -95,9 +95,12 @@ public function process_token( $stackPtr ) { } if ( T_WHITESPACE === $this->tokens[ ( $i + 1 ) ]['code'] ) { - // Something weird going on with tabs vs spaces, but this fixes it. - $indentation = str_replace( ' ', "\t", $this->tokens[ ( $i + 1 ) ]['content'] ); - $column = $this->tokens[ ( $i + 2 ) ]['column']; + // If the tokenizer replaced tabs with spaces, use the original content. + $indentation = $this->tokens[ ( $i + 1 ) ]['content']; + if ( isset( $this->tokens[ ( $i + 1 ) ]['orig_content'] ) ) { + $indentation = $this->tokens[ ( $i + 1 ) ]['orig_content']; + } + $column = $this->tokens[ ( $i + 2 ) ]['column']; } break; } From 2536aacdd935574064c1696338a902d5ba33f3e8 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 20 Jun 2017 01:29:03 +0200 Subject: [PATCH 059/282] ControlStructureSpacing sniff: Sync in more changes from upstream for the "blank line after" check The upstream sniff is *not* properly unit tested with a fixed file and in part checks for something different and therefore uses different logic. This commit adds unit tests for our version of the sniff, syncs in a number of good changes from upstream and fixes a number of bugs related to this particular check & fixer. --- .../ControlStructureSpacingSniff.php | 65 ++++++++++--------- .../ControlStructureSpacingUnitTest.inc | 46 +++++++++++++ .../ControlStructureSpacingUnitTest.inc.fixed | 40 ++++++++++++ .../ControlStructureSpacingUnitTest.php | 3 + 4 files changed, 125 insertions(+), 29 deletions(-) diff --git a/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php b/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php index c027d997..01941afa 100644 --- a/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php +++ b/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php @@ -496,36 +496,39 @@ public function process_token( $stackPtr ) { return; } - // {@internal This is just for the blank line check. Only whitespace should be considered.}} + // {@internal This is just for the blank line check. Only whitespace should be considered, + // not "other" empty tokens.}} $trailingContent = $this->phpcsFile->findNext( T_WHITESPACE, ( $scopeCloser + 1 ), null, true ); if ( false === $trailingContent ) { return; } - if ( T_ELSE === $this->tokens[ $trailingContent ]['code'] && T_IF === $this->tokens[ $stackPtr ]['code'] ) { - // IF with ELSE. - return; - } - if ( T_COMMENT === $this->tokens[ $trailingContent ]['code'] ) { + // Special exception for code where the comment about + // an ELSE or ELSEIF is written between the control structures. + $nextCode = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $scopeCloser + 1 ), null, true ); + + if ( T_ELSE === $this->tokens[ $nextCode ]['code'] || T_ELSEIF === $this->tokens[ $nextCode ]['code'] ) { + $trailingContent = $nextCode; + } + + // Move past end comments. if ( $this->tokens[ $trailingContent ]['line'] === $this->tokens[ $scopeCloser ]['line'] ) { - if ( '//end' === substr( $this->tokens[ $trailingContent ]['content'], 0, 5 ) ) { - // There is an end comment, so we have to get the next piece - // of content. - $trailingContent = $this->phpcsFile->findNext( T_WHITESPACE, ( $trailingContent + 1), null, true ); + if ( preg_match( '`^//[ ]?end`i', $this->tokens[ $trailingContent ]['content'], $matches ) > 0 ) { + $scopeCloser = $trailingContent; + $trailingContent = $this->phpcsFile->findNext( T_WHITESPACE, ( $trailingContent + 1 ), null, true ); } } } - if ( T_BREAK === $this->tokens[ $trailingContent ]['code'] ) { - // If this BREAK is closing a CASE, we don't need the - // blank line after this control structure. - if ( isset( $this->tokens[ $trailingContent ]['scope_condition'] ) ) { - $condition = $this->tokens[ $trailingContent ]['scope_condition']; - if ( T_CASE === $this->tokens[ $condition ]['code'] || T_DEFAULT === $this->tokens[ $condition ]['code'] ) { - return; - } - } + if ( T_ELSE === $this->tokens[ $trailingContent ]['code'] && T_IF === $this->tokens[ $stackPtr ]['code'] ) { + // IF with ELSE. + return; + } + + if ( T_WHILE === $this->tokens[ $trailingContent ]['code'] && T_DO === $this->tokens[ $stackPtr ]['code'] ) { + // DO with WHILE. + return; } if ( T_CLOSE_TAG === $this->tokens[ $trailingContent ]['code'] ) { @@ -533,15 +536,15 @@ public function process_token( $stackPtr ) { return; } - if ( T_CLOSE_CURLY_BRACKET === $this->tokens[ $trailingContent ]['code'] ) { + if ( isset( $this->tokens[ $trailingContent ]['scope_condition'] ) + && T_CLOSE_CURLY_BRACKET === $this->tokens[ $trailingContent ]['code'] + ) { // Another control structure's closing brace. - if ( isset( $this->tokens[ $trailingContent ]['scope_condition'] ) ) { - $owner = $this->tokens[ $trailingContent ]['scope_condition']; - if ( in_array( $this->tokens[ $owner ]['code'], array( T_FUNCTION, T_CLOSURE, T_CLASS, T_ANON_CLASS, T_INTERFACE, T_TRAIT ), true ) ) { - // The next content is the closing brace of a function, class, interface or trait - // so normal function/class rules apply and we can ignore it. - return; - } + $owner = $this->tokens[ $trailingContent ]['scope_condition']; + if ( in_array( $this->tokens[ $owner ]['code'], array( T_FUNCTION, T_CLOSURE, T_CLASS, T_ANON_CLASS, T_INTERFACE, T_TRAIT ), true ) ) { + // The next content is the closing brace of a function, class, interface or trait + // so normal function/class rules apply and we can ignore it. + return; } if ( ( $this->tokens[ $scopeCloser ]['line'] + 1 ) !== $this->tokens[ $trailingContent ]['line'] ) { @@ -552,12 +555,16 @@ public function process_token( $stackPtr ) { if ( true === $fix ) { $this->phpcsFile->fixer->beginChangeset(); - for ( $i = ( $scopeCloser + 1 ); $i < $trailingContent; $i++ ) { + $i = ( $scopeCloser + 1 ); + while ( $this->tokens[ $i ]['line'] !== $this->tokens[ $trailingContent ]['line'] ) { $this->phpcsFile->fixer->replaceToken( $i, '' ); + $i++; } // TODO: Instead a separate error should be triggered when content comes right after closing brace. - $this->phpcsFile->fixer->addNewlineBefore( $trailingContent ); + if ( T_COMMENT !== $this->tokens[ $scopeCloser ]['code'] ) { + $this->phpcsFile->fixer->addNewlineBefore( $trailingContent ); + } $this->phpcsFile->fixer->endChangeset(); } } diff --git a/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc b/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc index 4c97c594..2da0347b 100644 --- a/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc +++ b/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc @@ -222,3 +222,49 @@ if ( isset( $submenu_file ) ) { } else { $class[] = 'current'; } + +// Test finding & fixing blank line after control structure. +if ( $one ) { +} +elseif ( $two ) { +} +// else if something +else if ( $three ) { +} // else do something +else { +} + +do { +} +// Comment +while ( $a === $b ); + +if ( $foo ) { + try { + // Something + } catch ( Exception $e ) { + // Something + } + + +} + +if ( $foo ) { + try { + // Something + } catch ( Exception $e ) { + // Something + }//end try/catch <- Bad: "blank line after". + + +} + +if ( $foo ) { + try { // Bad. + // Something + } catch ( Exception $e ) { + // Something + } // End try/catch <- Bad: "blank line after". + + +} diff --git a/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc.fixed b/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc.fixed index 4f1e8171..d138c2f4 100644 --- a/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc.fixed +++ b/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc.fixed @@ -217,3 +217,43 @@ if ( isset( $submenu_file ) ) { } else { $class[] = 'current'; } + +// Test finding & fixing blank line after control structure. +if ( $one ) { +} +elseif ( $two ) { +} +// else if something +else if ( $three ) { +} // else do something +else { +} + +do { +} +// Comment +while ( $a === $b ); + +if ( $foo ) { + try { + // Something + } catch ( Exception $e ) { + // Something + } +} + +if ( $foo ) { + try { + // Something + } catch ( Exception $e ) { + // Something + }//end try/catch <- Bad: "blank line after". +} + +if ( $foo ) { + try { // Bad. + // Something + } catch ( Exception $e ) { + // Something + } // End try/catch <- Bad: "blank line after". +} diff --git a/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.php b/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.php index d4a5230b..7609189d 100644 --- a/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.php +++ b/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.php @@ -67,6 +67,9 @@ public function getErrorList() { 192 => 1, 196 => 2, 200 => 2, + 247 => 1, + 257 => 1, + 267 => 1, ); /* From e3cb73631ff5b0b020cbb865602d3727b82b673d Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 20 Jun 2017 02:04:54 +0200 Subject: [PATCH 060/282] Core: Enable the `ControlStructures.ControlSignature.NewlineAfterOpenBrace` check This was originally disabled in 366 as being too finicky, but fixes issues we are now running into with the WP coding standards update. Fixes 971 Fixes 974 --- WordPress-Core/ruleset.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index 3e821d28..0f4f0d7a 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -65,9 +65,6 @@ --> - - 0 - From d929d7e6446d8058cd4b05adab3787f68a505288 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 20 Jun 2017 05:05:50 +0200 Subject: [PATCH 061/282] OperatorSpacing sniff: Defer to upstream sniff for improved results. Up to now, this sniff was based on a copy of a very old and outdated version of the upstream sniff. The upstream and downstream sniffs had diverged quite widely code-wise, but not intention-wise. I've run both the `WordPress.WhiteSpace.OperatorSpacing` sniff as well as its upstream version `Squiz.WhiteSpace.OperatorSpacing` over both the WPCS unit tests for this sniff as well as the Squiz unit tests for this sniff. While there were differences in the results, they were for the better in favour of the upstream version of the sniff. --- .../WhiteSpace/OperatorSpacingSniff.php | 191 ++---------------- .../WhiteSpace/OperatorSpacingUnitTest.inc | 61 ++---- .../OperatorSpacingUnitTest.inc.fixed | 59 ++---- .../WhiteSpace/OperatorSpacingUnitTest.php | 10 +- 4 files changed, 51 insertions(+), 270 deletions(-) diff --git a/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php b/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php index cf2dc24b..ac57a2c9 100644 --- a/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php +++ b/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php @@ -7,8 +7,12 @@ * @license https://opensource.org/licenses/MIT MIT */ +if ( ! class_exists( 'Squiz_Sniffs_WhiteSpace_OperatorSpacingSniff', true ) ) { + throw new PHP_CodeSniffer_Exception( 'Class Squiz_Sniffs_WhiteSpace_OperatorSpacingSniff not found' ); +} + /** - * Verify operator spacing, based upon Squiz code. + * Verify operator spacing, uses the Squiz sniff, but additionally also sniffs for the `!` (boolean not) operator. * * "Always put spaces after commas, and on both sides of logical, comparison, string and assignment operators." * @@ -17,23 +21,27 @@ * @package WPCS\WordPressCodingStandards * * @since 0.1.0 - * @since 0.3.0 This sniff now has the ability to fix the issues it flags. - * @since 0.12.0 This class now extends WordPress_Sniff. + * @since 0.3.0 This sniff now has the ability to fix the issues it flags. + * @since 0.12.0 This sniff used to be a copy of a very old and outdated version of the + * upstream sniff. + * Now, the sniff defers completely to the upstream sniff, adding just one + * additional token - T_BOOLEAN_NOT - via the registration method + * and changing the value of the customizable $ignoreNewlines property. * - * Last synced with base class December 2008 at commit f01746fd1c89e98174b16c76efd325825eb58bf1. + * Last synced with base class June 2017 at commit 41127aa4764536f38f504fb3f7b8831f05919c89. * @link https://github.com/squizlabs/PHP_CodeSniffer/blob/master/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/OperatorSpacingSniff.php */ -class WordPress_Sniffs_WhiteSpace_OperatorSpacingSniff extends WordPress_Sniff { +class WordPress_Sniffs_WhiteSpace_OperatorSpacingSniff extends Squiz_Sniffs_WhiteSpace_OperatorSpacingSniff { /** - * A list of tokenizers this sniff supports. + * Allow newlines instead of spaces. + * + * N.B.: The upstream sniff defaults to `false`. * - * @var array + * @var boolean */ - public $supportedTokenizers = array( - 'PHP', - 'JS', - ); + public $ignoreNewlines = true; + /** * Returns an array of tokens this test wants to listen for. @@ -41,170 +49,11 @@ class WordPress_Sniffs_WhiteSpace_OperatorSpacingSniff extends WordPress_Sniff { * @return array */ public function register() { - $comparison = PHP_CodeSniffer_Tokens::$comparisonTokens; - $operators = PHP_CodeSniffer_Tokens::$operators; - $assignment = PHP_CodeSniffer_Tokens::$assignmentTokens; - - // Union the arrays - keeps the array keys and - in this case - automatically de-dups. - $tokens = ( $comparison + $operators + $assignment ); + $tokens = parent::register(); $tokens[] = T_BOOLEAN_NOT; return $tokens; } - /** - * Processes this test, when one of its tokens is encountered. - * - * @param int $stackPtr The position of the current token in the stack. - * - * @return void - */ - public function process_token( $stackPtr ) { - - if ( T_EQUAL === $this->tokens[ $stackPtr ]['code'] ) { - // Skip for '=&' case. - if ( isset( $this->tokens[ ( $stackPtr + 1 ) ] ) - && T_BITWISE_AND === $this->tokens[ ( $stackPtr + 1 ) ]['code'] - ) { - return; - } - - // Skip default values in function declarations. - // Skip declare statements. - if ( isset( $this->tokens[ $stackPtr ]['nested_parenthesis'] ) ) { - $bracket = end( $this->tokens[ $stackPtr ]['nested_parenthesis'] ); - if ( isset( $this->tokens[ $bracket ]['parenthesis_owner'] ) ) { - $function = $this->tokens[ $bracket ]['parenthesis_owner']; - if ( T_FUNCTION === $this->tokens[ $function ]['code'] - || T_CLOSURE === $this->tokens[ $function ]['code'] - || T_DECLARE === $this->tokens[ $function ]['code'] - ) { - return; - } - } - } - } - - if ( T_BITWISE_AND === $this->tokens[ $stackPtr ]['code'] ) { - /* - // If it's not a reference, then we expect one space either side of the - // bitwise operator. - if ( false === $this->phpcsFile->isReference( $stackPtr ) ) { - // @todo Implement or remove ? - } - */ - return; - - } else { - if ( T_MINUS === $this->tokens[ $stackPtr ]['code'] ) { - // Check minus spacing, but make sure we aren't just assigning - // a minus value or returning one. - $prev = $this->phpcsFile->findPrevious( T_WHITESPACE, ( $stackPtr - 1 ), null, true ); - if ( T_RETURN === $this->tokens[ $prev ]['code'] ) { - // Just returning a negative value; eg. return -1. - return; - } - - if ( isset( PHP_CodeSniffer_Tokens::$operators[ $this->tokens[ $prev ]['code'] ] ) ) { - // Just trying to operate on a negative value; eg. ($var * -1). - return; - } - - if ( isset( PHP_CodeSniffer_Tokens::$comparisonTokens[ $this->tokens[ $prev ]['code'] ] ) ) { - // Just trying to compare a negative value; eg. ($var === -1). - return; - } - - // A list of tokens that indicate that the token is not - // part of an arithmetic operation. - $invalidTokens = array( - T_COMMA, - T_OPEN_PARENTHESIS, - T_OPEN_SQUARE_BRACKET, - ); - - if ( in_array( $this->tokens[ $prev ]['code'], $invalidTokens, true ) ) { - // Just trying to use a negative value; eg. myFunction($var, -2). - return; - } - - $number = $this->phpcsFile->findNext( T_WHITESPACE, ( $stackPtr + 1 ), null, true ); - if ( T_LNUMBER === $this->tokens[ $number ]['code'] ) { - $semi = $this->phpcsFile->findNext( T_WHITESPACE, ( $number + 1 ), null, true ); - if ( T_SEMICOLON === $this->tokens[ $semi ]['code'] ) { - if ( false !== $prev && - isset( PHP_CodeSniffer_Tokens::$assignmentTokens[ $this->tokens[ $prev ]['code'] ] ) - ) { - // This is a negative assignment. - return; - } - } - } - } - - $operator = $this->tokens[ $stackPtr ]['content']; - - if ( T_WHITESPACE !== $this->tokens[ ( $stackPtr - 1 ) ]['code'] ) { - $error = 'Expected 1 space before "%s"; 0 found'; - $data = array( $operator ); - $fix = $this->phpcsFile->addFixableError( $error, $stackPtr, 'NoSpaceBefore', $data ); - if ( true === $fix ) { - $this->phpcsFile->fixer->beginChangeset(); - $this->phpcsFile->fixer->addContentBefore( $stackPtr, ' ' ); - $this->phpcsFile->fixer->endChangeset(); - } - } elseif ( 1 !== strlen( $this->tokens[ ( $stackPtr - 1 ) ]['content'] ) - && 1 !== $this->tokens[ ( $stackPtr - 1 ) ]['column'] - ) { - // Don't throw an error for assignments, because other standards allow - // multiple spaces there to align multiple assignments. - if ( false === isset( PHP_CodeSniffer_Tokens::$assignmentTokens[ $this->tokens[ $stackPtr ]['code'] ] ) ) { - $found = strlen( $this->tokens[ ( $stackPtr - 1 ) ]['content'] ); - $error = 'Expected 1 space before "%s"; %s found'; - $data = array( - $operator, - $found, - ); - - $fix = $this->phpcsFile->addFixableError( $error, $stackPtr, 'SpacingBefore', $data ); - if ( true === $fix ) { - $this->phpcsFile->fixer->beginChangeset(); - $this->phpcsFile->fixer->replaceToken( ( $stackPtr - 1 ), ' ' ); - $this->phpcsFile->fixer->endChangeset(); - } - } - } - - if ( '-' !== $operator ) { - if ( T_WHITESPACE !== $this->tokens[ ( $stackPtr + 1 ) ]['code'] ) { - $error = 'Expected 1 space after "%s"; 0 found'; - $data = array( $operator ); - - $fix = $this->phpcsFile->addFixableError( $error, $stackPtr, 'NoSpaceAfter', $data ); - if ( true === $fix ) { - $this->phpcsFile->fixer->beginChangeset(); - $this->phpcsFile->fixer->addContent( $stackPtr, ' ' ); - $this->phpcsFile->fixer->endChangeset(); - } - } elseif ( 1 !== strlen( $this->tokens[ ( $stackPtr + 1 ) ]['content'] ) ) { - $found = strlen( $this->tokens[ ( $stackPtr + 1 ) ]['content'] ); - $error = 'Expected 1 space after "%s"; %s found'; - $data = array( - $operator, - $found, - ); - - $fix = $this->phpcsFile->addFixableError( $error, $stackPtr, 'SpacingAfter', $data ); - if ( true === $fix ) { - $this->phpcsFile->fixer->beginChangeset(); - $this->phpcsFile->fixer->replaceToken( ( $stackPtr + 1 ), ' ' ); - $this->phpcsFile->fixer->endChangeset(); - } - } - } - } - - } // End process(). - } // End class. diff --git a/WordPress/Tests/WhiteSpace/OperatorSpacingUnitTest.inc b/WordPress/Tests/WhiteSpace/OperatorSpacingUnitTest.inc index f6a405ca..ab44d569 100644 --- a/WordPress/Tests/WhiteSpace/OperatorSpacingUnitTest.inc +++ b/WordPress/Tests/WhiteSpace/OperatorSpacingUnitTest.inc @@ -1,63 +1,30 @@ $c; - -$a ??= $b; // Multiple spaces before assignment is OK. +// Bad. +if ( ! $var ) { + // ... +} diff --git a/WordPress/Tests/WhiteSpace/OperatorSpacingUnitTest.inc.fixed b/WordPress/Tests/WhiteSpace/OperatorSpacingUnitTest.inc.fixed index 06aa5ed8..14974e73 100644 --- a/WordPress/Tests/WhiteSpace/OperatorSpacingUnitTest.inc.fixed +++ b/WordPress/Tests/WhiteSpace/OperatorSpacingUnitTest.inc.fixed @@ -1,63 +1,30 @@ $c; - -$a ??= $b; // Multiple spaces before assignment is OK. +// Bad. +if ( ! $var ) { + // ... +} diff --git a/WordPress/Tests/WhiteSpace/OperatorSpacingUnitTest.php b/WordPress/Tests/WhiteSpace/OperatorSpacingUnitTest.php index a9ad3c29..2b094f5b 100644 --- a/WordPress/Tests/WhiteSpace/OperatorSpacingUnitTest.php +++ b/WordPress/Tests/WhiteSpace/OperatorSpacingUnitTest.php @@ -12,6 +12,8 @@ * * @package WPCS\WordPressCodingStandards * @since 2013-06-11 + * @since 0.12.0 Now only tests the WPCS specific addition of T_BOOLEAN_NOT. + * The rest of the sniff is unit tested upstream. */ class WordPress_Tests_WhiteSpace_OperatorSpacingUnitTest extends AbstractSniffUnitTest { @@ -22,12 +24,8 @@ class WordPress_Tests_WhiteSpace_OperatorSpacingUnitTest extends AbstractSniffUn */ public function getErrorList() { return array( - 5 => 4, - 18 => 1, - 45 => 1, - 49 => 1, - 60 => 2, - 61 => 2, + 23 => 2, + 28 => 2, ); } From dd3f5f79ebb39ccb3c6e2bbb224b828fc0a7fdff Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 17 Jun 2017 22:26:41 +0200 Subject: [PATCH 062/282] Add `Squiz.PHP.EmbeddedPhp` sniff to `Extra` Added to the `Extra` ruleset as the requirement to have a closing semi-colon for embedded PHP is not explicitly mentioned in the WP Core Handbook. It's also perfectly valid PHP and won't cause parse errors, so more of a best practice than anything else. Fixes 465 --- WordPress-Extra/ruleset.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/WordPress-Extra/ruleset.xml b/WordPress-Extra/ruleset.xml index 8d6e2ce2..39617ec0 100644 --- a/WordPress-Extra/ruleset.xml +++ b/WordPress-Extra/ruleset.xml @@ -33,6 +33,15 @@ https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/pull/809 --> + + + + + + + + From c51a10cb8f8ceda65ca0cbaf9fe9e4d556f8b8b7 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 20 Jun 2017 14:10:26 +0200 Subject: [PATCH 063/282] Core: Set the default encoding in the ruleset Also moved the `tab-width` up as this is not a sniff specific, but a generic setting. --- WordPress-Core/ruleset.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index 0f4f0d7a..04fe39dd 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -2,6 +2,12 @@ Non-controversial generally-agreed upon WordPress Coding Standards + + + + + + - From ecf19fe62bf2cb2de958603f4a0c857a98d0a38b Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 22 Jun 2017 19:02:37 +0200 Subject: [PATCH 064/282] :sparkles: New `WP.DeprecatedClasses` sniff New sniff to detect & notify about usage of deprecated WP classes. Moved one deprecated class which was listed in the `DeprecatedFunctions` to this new class. Added the new sniff to the `Extra` ruleset in line with the `DeprecatedFunctions` sniff also being there. Related to 576 and 979#issuecomment-310235086 --- WordPress-Extra/ruleset.xml | 1 + .../Sniffs/WP/DeprecatedClassesSniff.php | 113 ++++++++++++++++++ .../Sniffs/WP/DeprecatedFunctionsSniff.php | 4 - .../Tests/WP/DeprecatedClassesUnitTest.inc | 19 +++ .../Tests/WP/DeprecatedClassesUnitTest.php | 38 ++++++ .../Tests/WP/DeprecatedFunctionsUnitTest.inc | 1 - .../Tests/WP/DeprecatedFunctionsUnitTest.php | 4 +- 7 files changed, 173 insertions(+), 7 deletions(-) create mode 100644 WordPress/Sniffs/WP/DeprecatedClassesSniff.php create mode 100644 WordPress/Tests/WP/DeprecatedClassesUnitTest.inc create mode 100644 WordPress/Tests/WP/DeprecatedClassesUnitTest.php diff --git a/WordPress-Extra/ruleset.xml b/WordPress-Extra/ruleset.xml index 39617ec0..07555a36 100644 --- a/WordPress-Extra/ruleset.xml +++ b/WordPress-Extra/ruleset.xml @@ -72,6 +72,7 @@ + diff --git a/WordPress/Sniffs/WP/DeprecatedClassesSniff.php b/WordPress/Sniffs/WP/DeprecatedClassesSniff.php new file mode 100644 index 00000000..3145c821 --- /dev/null +++ b/WordPress/Sniffs/WP/DeprecatedClassesSniff.php @@ -0,0 +1,113 @@ + + * + * + * + * + * + * @var string WordPress versions. + */ + public $minimum_supported_version = '4.5'; + + /** + * List of deprecated classes with alternative when available. + * + * To be updated after every major release. + * + * Version numbers should be fully qualified. + * + * @var array + */ + private $deprecated_classes = array( + + // WP 3.1.0. + 'WP_User_Search' => array( + 'alt' => 'WP_User_Query', + 'version' => '3.1.0', + ), + ); + + + /** + * Groups of classes to restrict. + * + * @return array + */ + public function getGroups() { + // Make sure all array keys are lowercase. + $keys = array_keys( $this->deprecated_classes ); + $keys = array_map( 'strtolower', $keys ); + $this->deprecated_classes = array_combine( $keys, $this->deprecated_classes ); + + return array( + 'deprecated_classes' => array( + 'classes' => $keys, + ), + ); + + } // End getGroups(). + + /** + * Process a matched token. + * + * @param int $stackPtr The position of the current token in the stack. + * @param array $group_name The name of the group which was matched. Will + * always be 'deprecated_functions'. + * @param string $matched_content The token content (class name) which was matched. + * + * @return void + */ + public function process_matched_token( $stackPtr, $group_name, $matched_content ) { + $class_name = ltrim( strtolower( $matched_content ), '\\' ); + + $message = 'The %s class has been deprecated since WordPress version %s.'; + $data = array( + ltrim( $matched_content, '\\' ), + $this->deprecated_classes[ $class_name ]['version'], + ); + + if ( ! empty( $this->deprecated_classes[ $class_name ]['alt'] ) ) { + $message .= ' Use %s instead.'; + $data[] = $this->deprecated_classes[ $class_name ]['alt']; + } + + $this->addMessage( + $message, + $stackPtr, + ( version_compare( $this->deprecated_classes[ $class_name ]['version'], $this->minimum_supported_version, '<' ) ), + $this->string_to_errorcode( $matched_content . 'Found' ), + $data + ); + + } // End process_matched_token(). + +} // End class. diff --git a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php index cacf08e0..123a9b21 100644 --- a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php +++ b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php @@ -570,10 +570,6 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => '', 'version' => '3.1', ), - 'WP_User_Search' => array( - 'alt' => 'WP_User_Query', - 'version' => '3.1', - ), 'get_others_unpublished_posts' => array( 'alt' => '', 'version' => '3.1', diff --git a/WordPress/Tests/WP/DeprecatedClassesUnitTest.inc b/WordPress/Tests/WP/DeprecatedClassesUnitTest.inc new file mode 100644 index 00000000..add7761f --- /dev/null +++ b/WordPress/Tests/WP/DeprecatedClassesUnitTest.inc @@ -0,0 +1,19 @@ +query(); + +/* + * Warning. + */ diff --git a/WordPress/Tests/WP/DeprecatedClassesUnitTest.php b/WordPress/Tests/WP/DeprecatedClassesUnitTest.php new file mode 100644 index 00000000..14bd9883 --- /dev/null +++ b/WordPress/Tests/WP/DeprecatedClassesUnitTest.php @@ -0,0 +1,38 @@ + => + */ + public function getErrorList() { + return array_fill( 9, 7, 1 ); + + } // End getErrorList(). + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array(); + + } + +} // End class. diff --git a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc index 03dd465a..ef95f7bb 100644 --- a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc +++ b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc @@ -132,7 +132,6 @@ get_author_user_ids(); get_editable_authors(); get_editable_user_ids(); get_nonauthor_user_ids(); -WP_User_Search(); get_others_unpublished_posts(); get_others_drafts(); get_others_pending(); diff --git a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php index 951804c3..6a6ce54d 100644 --- a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php +++ b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php @@ -22,7 +22,7 @@ class WordPress_Tests_WP_DeprecatedFunctionsUnitTest extends AbstractSniffUnitTe * @return array => */ public function getErrorList() { - return array_fill( 8, 236, 1 ); + return array_fill( 8, 235, 1 ); } @@ -32,7 +32,7 @@ public function getErrorList() { * @return array => */ public function getWarningList() { - return array_fill( 246, 15, 1 ); + return array_fill( 245, 15, 1 ); } From 577c9cfe4f7cb9d306065767b44dfe5d2677910b Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 22 Jun 2017 22:37:02 +0200 Subject: [PATCH 065/282] DeprecatedFunctions sniff: update minimum WP version & add WP 4.7 & 4.7 deprecated functions This version is supposed to be 3 versions before the current WP release and what with WP 4.8 having been released, should now be updated. Functions which have been deprecated in WP 4.7 and 4.8 have been added to the list. Unit tests have been updated accordingly. --- .../Sniffs/WP/DeprecatedFunctionsSniff.php | 36 ++++++++++++++++--- .../Tests/WP/DeprecatedFunctionsUnitTest.inc | 11 ++++-- .../Tests/WP/DeprecatedFunctionsUnitTest.php | 4 +-- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php index 123a9b21..570b999b 100644 --- a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php +++ b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php @@ -28,7 +28,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun * this sniff by setting a property in a custom phpcs.xml ruleset. * * Example usage: - * + * * * * @@ -36,13 +36,13 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun * * @var string WordPress versions. */ - public $minimum_supported_version = '4.4'; + public $minimum_supported_version = '4.5'; /** * List of deprecated functions with alternative when available. * * To be updated after every major release. - * Last updated for WordPress 4.7. + * Last updated for WordPress 4.8. * * @var array */ @@ -1083,7 +1083,35 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '4.6', ), - // No deprecated functions in WordPress 4.7. + '_sort_nav_menu_items' => array( + 'alt' => 'wp_list_sort', + 'version' => '4.7', + ), + '_usort_terms_by_ID' => array( + 'alt' => 'wp_list_sort', + 'version' => '4.7', + ), + '_usort_terms_by_name' => array( + 'alt' => 'wp_list_sort', + 'version' => '4.7', + ), + 'get_paged_template' => array( + 'alt' => '', + 'version' => '4.7', + ), + 'wp_get_network' => array( + 'alt' => 'get_network', + 'version' => '4.7', + ), + 'wp_kses_js_entities' => array( + 'alt' => '', + 'version' => '4.7', + ), + + 'wp_dashboard_plugins_output' => array( + 'alt' => '', + 'version' => '4.8', + ), ); /** diff --git a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc index ef95f7bb..bdacb72a 100644 --- a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc +++ b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc @@ -240,14 +240,14 @@ preview_theme_ob_filter(); preview_theme_ob_filter_callback(); wp_richedit_pre(); wp_ajax_wp_fullscreen_save_post(); - -// Warning. flush_widget_cache(); // WP_Widget_Recent_Comments::flush_widget_cache() post_permalink(); force_ssl_login(); create_empty_blog(); get_admin_users_for_domain(); wp_get_http(); + +// Warning. is_comments_popup(); add_object_page(); add_utility_page(); @@ -257,3 +257,10 @@ popuplinks(); get_currentuserinfo(); wp_embed_handler_googlevideo(); wp_get_sites(); +_sort_nav_menu_items(); +_usort_terms_by_ID(); +_usort_terms_by_name(); +get_paged_template(); +wp_get_network(); +wp_kses_js_entities(); +wp_dashboard_plugins_output(); diff --git a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php index 6a6ce54d..6901c26a 100644 --- a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php +++ b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php @@ -22,7 +22,7 @@ class WordPress_Tests_WP_DeprecatedFunctionsUnitTest extends AbstractSniffUnitTe * @return array => */ public function getErrorList() { - return array_fill( 8, 235, 1 ); + return array_fill( 8, 241, 1 ); } @@ -32,7 +32,7 @@ public function getErrorList() { * @return array => */ public function getWarningList() { - return array_fill( 245, 15, 1 ); + return array_fill( 251, 16, 1 ); } From 6ea1090d4d830d1e1940f2be43a55371777abe27 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 22 Jun 2017 22:34:56 +0200 Subject: [PATCH 066/282] DeprecatedFunctions sniff: re-order the array and add version number delimiters New sort order: Ordered by WP version in which deprecation occurred & order alphabetically (case-insensitive sort) on function name within each subset. Additionally I've added version number comments as delimiters in both the array as well as the test case file to make maintenance easier and I've accounted for those in the test file. --- .../Sniffs/WP/DeprecatedFunctionsSniff.php | 704 +++++++++--------- .../Tests/WP/DeprecatedFunctionsUnitTest.inc | 303 ++++---- .../Tests/WP/DeprecatedFunctionsUnitTest.php | 23 +- 3 files changed, 559 insertions(+), 471 deletions(-) diff --git a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php index 570b999b..56de473b 100644 --- a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php +++ b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php @@ -47,46 +47,53 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun * @var array */ private $deprecated_functions = array( - 'the_category_id' => array( - 'alt' => 'get_the_category()', - 'version' => '0.71', - ), + + // WP 0.71. 'the_category_head' => array( 'alt' => 'get_the_category_by_ID()', 'version' => '0.71', ), + 'the_category_id' => array( + 'alt' => 'get_the_category()', + 'version' => '0.71', + ), + // WP 1.2.0. 'permalink_link' => array( 'alt' => 'the_permalink()', 'version' => '1.2', ), + // WP 1.5.0. 'start_wp' => array( 'alt' => 'the Loop', 'version' => '1.5', ), + + // WP 1.5.1. 'get_postdata' => array( 'alt' => 'get_post()', 'version' => '1.5.1', ), - 'previous_post' => array( - 'alt' => 'previous_post_link()', + // WP 2.0.0. + 'create_user' => array( + 'alt' => 'wp_create_user()', 'version' => '2.0', ), 'next_post' => array( 'alt' => 'next_post_link()', 'version' => '2.0', ), - 'user_can_create_post' => array( - 'alt' => 'current_user_can()', + 'previous_post' => array( + 'alt' => 'previous_post_link()', 'version' => '2.0', ), 'user_can_create_draft' => array( 'alt' => 'current_user_can()', 'version' => '2.0', ), - 'user_can_edit_post' => array( + 'user_can_create_post' => array( 'alt' => 'current_user_can()', 'version' => '2.0', ), @@ -94,15 +101,15 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'current_user_can()', 'version' => '2.0', ), - 'user_can_set_post_date' => array( + 'user_can_delete_post_comments' => array( 'alt' => 'current_user_can()', 'version' => '2.0', ), - 'user_can_edit_post_comments' => array( + 'user_can_edit_post' => array( 'alt' => 'current_user_can()', 'version' => '2.0', ), - 'user_can_delete_post_comments' => array( + 'user_can_edit_post_comments' => array( 'alt' => 'current_user_can()', 'version' => '2.0', ), @@ -110,160 +117,160 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'current_user_can()', 'version' => '2.0', ), - 'create_user' => array( - 'alt' => 'wp_create_user()', + 'user_can_set_post_date' => array( + 'alt' => 'current_user_can()', 'version' => '2.0', ), - 'get_linksbyname' => array( - 'alt' => 'get_bookmarks()', + // WP 2.1.0. + 'dropdown_cats' => array( + 'alt' => 'wp_dropdown_categories()', 'version' => '2.1', ), - 'wp_get_linksbyname' => array( - 'alt' => 'wp_list_bookmarks()', + 'get_archives' => array( + 'alt' => 'wp_get_archives', 'version' => '2.1', ), - 'get_linkobjectsbyname' => array( - 'alt' => 'get_bookmarks()', + 'get_author_link' => array( + 'alt' => 'get_author_posts_url()', 'version' => '2.1', ), - 'get_linkobjects' => array( - 'alt' => 'get_bookmarks()', + 'get_autotoggle' => array( + 'alt' => '', 'version' => '2.1', ), - 'get_linksbyname_withrating' => array( - 'alt' => 'get_bookmarks()', + 'get_link' => array( + 'alt' => 'get_bookmark()', 'version' => '2.1', ), - 'get_links_withrating' => array( - 'alt' => 'get_bookmarks()', + 'get_linkcatname' => array( + 'alt' => 'get_category()', 'version' => '2.1', ), - 'get_autotoggle' => array( - 'alt' => '', + 'get_linkobjects' => array( + 'alt' => 'get_bookmarks()', 'version' => '2.1', ), - 'list_cats' => array( - 'alt' => 'wp_list_categories', + 'get_linkobjectsbyname' => array( + 'alt' => 'get_bookmarks()', 'version' => '2.1', ), - 'wp_list_cats' => array( - 'alt' => 'wp_list_categories', + 'get_linkrating' => array( + 'alt' => 'sanitize_bookmark_field()', 'version' => '2.1', ), - 'dropdown_cats' => array( - 'alt' => 'wp_dropdown_categories()', + 'get_links' => array( + 'alt' => 'get_bookmarks()', 'version' => '2.1', ), - 'list_authors' => array( - 'alt' => 'wp_list_authors()', + 'get_links_list' => array( + 'alt' => 'wp_list_bookmarks()', 'version' => '2.1', ), - 'wp_get_post_cats' => array( - 'alt' => 'wp_get_post_categories()', + 'get_links_withrating' => array( + 'alt' => 'get_bookmarks()', 'version' => '2.1', ), - 'wp_set_post_cats' => array( - 'alt' => 'wp_set_post_categories()', + 'get_linksbyname' => array( + 'alt' => 'get_bookmarks()', 'version' => '2.1', ), - 'get_archives' => array( - 'alt' => 'wp_get_archives', + 'get_linksbyname_withrating' => array( + 'alt' => 'get_bookmarks()', 'version' => '2.1', ), - 'get_author_link' => array( - 'alt' => 'get_author_posts_url()', + 'get_settings' => array( + 'alt' => 'get_option()', 'version' => '2.1', ), 'link_pages' => array( 'alt' => 'wp_link_pages()', 'version' => '2.1', ), - 'get_settings' => array( - 'alt' => 'get_option()', + 'links_popup_script' => array( + 'alt' => '', 'version' => '2.1', ), - 'wp_get_links' => array( - 'alt' => 'wp_list_bookmarks()', + 'list_authors' => array( + 'alt' => 'wp_list_authors()', 'version' => '2.1', ), - 'get_links' => array( - 'alt' => 'get_bookmarks()', + 'list_cats' => array( + 'alt' => 'wp_list_categories', 'version' => '2.1', ), - 'get_links_list' => array( - 'alt' => 'wp_list_bookmarks()', + 'tinymce_include' => array( + 'alt' => 'wp_tiny_mce()', 'version' => '2.1', ), - 'links_popup_script' => array( - 'alt' => '', + 'wp_get_links' => array( + 'alt' => 'wp_list_bookmarks()', 'version' => '2.1', ), - 'get_linkrating' => array( - 'alt' => 'sanitize_bookmark_field()', + 'wp_get_linksbyname' => array( + 'alt' => 'wp_list_bookmarks()', 'version' => '2.1', ), - 'get_linkcatname' => array( - 'alt' => 'get_category()', + 'wp_get_post_cats' => array( + 'alt' => 'wp_get_post_categories()', 'version' => '2.1', ), - 'get_link' => array( - 'alt' => 'get_bookmark()', + 'wp_list_cats' => array( + 'alt' => 'wp_list_categories', 'version' => '2.1', ), - 'tinymce_include' => array( - 'alt' => 'wp_tiny_mce()', + 'wp_set_post_cats' => array( + 'alt' => 'wp_set_post_categories()', 'version' => '2.1', ), + // WP 2.2.0. 'comments_rss' => array( 'alt' => 'get_post_comments_feed_link()', 'version' => '2.2', ), + // WP 2.3.0. 'permalink_single_rss' => array( 'alt' => 'permalink_rss()', 'version' => '2.3', ), + // WP 2.5.0. 'comments_rss_link' => array( 'alt' => 'post_comments_feed_link()', 'version' => '2.5', ), - 'get_category_rss_link' => array( - 'alt' => 'get_category_feed_link()', - 'version' => '2.5', - ), - 'get_author_rss_link' => array( - 'alt' => 'get_author_feed_link()', + 'documentation_link' => array( + 'alt' => '', 'version' => '2.5', ), - 'get_the_attachment_link' => array( - 'alt' => 'wp_get_attachment_link()', + 'get_attachment_icon' => array( + 'alt' => 'wp_get_attachment_image()', 'version' => '2.5', ), 'get_attachment_icon_src' => array( 'alt' => 'wp_get_attachment_image_src()', 'version' => '2.5', ), - 'get_attachment_icon' => array( + 'get_attachment_innerHTML' => array( 'alt' => 'wp_get_attachment_image()', 'version' => '2.5', ), - 'get_attachment_innerHTML' => array( - 'alt' => 'wp_get_attachment_image()', + 'get_author_rss_link' => array( + 'alt' => 'get_author_feed_link()', 'version' => '2.5', ), - 'documentation_link' => array( - 'alt' => '', + 'get_category_rss_link' => array( + 'alt' => 'get_category_feed_link()', 'version' => '2.5', ), - 'gzip_compression' => array( - 'alt' => '', + 'get_the_attachment_link' => array( + 'alt' => 'wp_get_attachment_link()', 'version' => '2.5', ), - 'wp_setcookie' => array( - 'alt' => 'wp_set_auth_cookie()', + 'gzip_compression' => array( + 'alt' => '', 'version' => '2.5', ), 'wp_get_cookie_login' => array( @@ -274,7 +281,12 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'wp_signon()', 'version' => '2.5', ), + 'wp_setcookie' => array( + 'alt' => 'wp_set_auth_cookie()', + 'version' => '2.5', + ), + // WP 2.6.0. 'dropdown_categories' => array( 'alt' => 'wp_category_checklist()', 'version' => '2.6', @@ -284,6 +296,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '2.6', ), + // WP 2.7.0. 'get_commentdata' => array( 'alt' => 'get_comment()', 'version' => '2.7', @@ -299,210 +312,213 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '2.7', ), - 'get_catname' => array( - 'alt' => 'get_cat_name()', + // WP 2.8.0. + '__ngettext' => array( + 'alt' => '_n_noop()', 'version' => '2.8', ), - 'get_category_children' => array( - 'alt' => 'get_term_children', + '__ngettext_noop' => array( + 'alt' => '_n_noop()', 'version' => '2.8', ), - 'get_the_author_description' => array( - 'alt' => "get_the_author_meta( 'description' )", + 'attribute_escape' => array( + 'alt' => 'esc_attr()', 'version' => '2.8', ), - 'the_author_description' => array( - 'alt' => 'the_author_meta(\'description\')', + 'get_author_name' => array( + 'alt' => 'get_the_author_meta(\'display_name\')', 'version' => '2.8', ), - 'get_the_author_login' => array( - 'alt' => 'the_author_meta(\'login\')', + 'get_category_children' => array( + 'alt' => 'get_term_children', 'version' => '2.8', ), - 'get_the_author_firstname' => array( - 'alt' => 'get_the_author_meta(\'first_name\')', + 'get_catname' => array( + 'alt' => 'get_cat_name()', 'version' => '2.8', ), - 'the_author_firstname' => array( - 'alt' => 'the_author_meta(\'first_name\')', + 'get_the_author_aim' => array( + 'alt' => 'get_the_author_meta(\'aim\')', 'version' => '2.8', ), - 'get_the_author_lastname' => array( - 'alt' => 'get_the_author_meta(\'last_name\')', + 'get_the_author_description' => array( + 'alt' => "get_the_author_meta( 'description' )", 'version' => '2.8', ), - 'the_author_lastname' => array( - 'alt' => 'the_author_meta(\'last_name\')', + 'get_the_author_email' => array( + 'alt' => 'get_the_author_meta(\'email\')', 'version' => '2.8', ), - 'get_the_author_nickname' => array( - 'alt' => 'get_the_author_meta(\'nickname\')', + 'get_the_author_firstname' => array( + 'alt' => 'get_the_author_meta(\'first_name\')', 'version' => '2.8', ), - 'the_author_nickname' => array( - 'alt' => 'the_author_meta(\'nickname\')', + 'get_the_author_icq' => array( + 'alt' => 'get_the_author_meta(\'icq\')', 'version' => '2.8', ), - 'get_the_author_email' => array( - 'alt' => 'get_the_author_meta(\'email\')', + 'get_the_author_ID' => array( + 'alt' => 'get_the_author_meta(\'ID\')', 'version' => '2.8', ), - 'the_author_email' => array( - 'alt' => 'the_author_meta(\'email\')', + 'get_the_author_lastname' => array( + 'alt' => 'get_the_author_meta(\'last_name\')', 'version' => '2.8', ), - 'get_the_author_icq' => array( - 'alt' => 'get_the_author_meta(\'icq\')', + 'get_the_author_login' => array( + 'alt' => 'the_author_meta(\'login\')', 'version' => '2.8', ), - 'the_author_icq' => array( - 'alt' => 'the_author_meta(\'icq\')', + 'get_the_author_msn' => array( + 'alt' => 'get_the_author_meta(\'msn\')', + 'version' => '2.8', + ), + 'get_the_author_nickname' => array( + 'alt' => 'get_the_author_meta(\'nickname\')', + 'version' => '2.8', + ), + 'get_the_author_url' => array( + 'alt' => 'get_the_author_meta(\'url\')', 'version' => '2.8', ), 'get_the_author_yim' => array( 'alt' => 'get_the_author_meta(\'yim\')', 'version' => '2.8', ), - 'the_author_yim' => array( - 'alt' => 'the_author_meta(\'yim\')', + 'js_escape' => array( + 'alt' => 'esc_js()', 'version' => '2.8', ), - 'get_the_author_msn' => array( - 'alt' => 'get_the_author_meta(\'msn\')', + 'register_sidebar_widget' => array( + 'alt' => 'wp_register_sidebar_widget()', 'version' => '2.8', ), - 'the_author_msn' => array( - 'alt' => 'the_author_meta(\'msn\')', + 'register_widget_control' => array( + 'alt' => 'wp_register_widget_control()', 'version' => '2.8', ), - 'get_the_author_aim' => array( - 'alt' => 'get_the_author_meta(\'aim\')', + 'sanitize_url' => array( + 'alt' => 'esc_url()', 'version' => '2.8', ), 'the_author_aim' => array( 'alt' => 'the_author_meta(\'aim\')', 'version' => '2.8', ), - 'get_author_name' => array( - 'alt' => 'get_the_author_meta(\'display_name\')', + 'the_author_description' => array( + 'alt' => 'the_author_meta(\'description\')', 'version' => '2.8', ), - 'get_the_author_url' => array( - 'alt' => 'get_the_author_meta(\'url\')', + 'the_author_email' => array( + 'alt' => 'the_author_meta(\'email\')', 'version' => '2.8', ), - 'the_author_url' => array( - 'alt' => 'the_author_meta(\'url\')', + 'the_author_firstname' => array( + 'alt' => 'the_author_meta(\'first_name\')', 'version' => '2.8', ), - 'get_the_author_ID' => array( - 'alt' => 'get_the_author_meta(\'ID\')', + 'the_author_icq' => array( + 'alt' => 'the_author_meta(\'icq\')', 'version' => '2.8', ), 'the_author_ID' => array( 'alt' => 'the_author_meta(\'ID\')', 'version' => '2.8', ), - '__ngettext' => array( - 'alt' => '_n_noop()', - 'version' => '2.8', - ), - '__ngettext_noop' => array( - 'alt' => '_n_noop()', - 'version' => '2.8', - ), - 'sanitize_url' => array( - 'alt' => 'esc_url()', + 'the_author_lastname' => array( + 'alt' => 'the_author_meta(\'last_name\')', 'version' => '2.8', ), - 'js_escape' => array( - 'alt' => 'esc_js()', + 'the_author_msn' => array( + 'alt' => 'the_author_meta(\'msn\')', 'version' => '2.8', ), - 'wp_specialchars' => array( - 'alt' => 'esc_html()', + 'the_author_nickname' => array( + 'alt' => 'the_author_meta(\'nickname\')', 'version' => '2.8', ), - 'attribute_escape' => array( - 'alt' => 'esc_attr()', + 'the_author_url' => array( + 'alt' => 'the_author_meta(\'url\')', 'version' => '2.8', ), - 'register_sidebar_widget' => array( - 'alt' => 'wp_register_sidebar_widget()', + 'the_author_yim' => array( + 'alt' => 'the_author_meta(\'yim\')', 'version' => '2.8', ), 'unregister_sidebar_widget' => array( 'alt' => 'wp_unregister_sidebar_widget()', 'version' => '2.8', ), - 'register_widget_control' => array( - 'alt' => 'wp_register_widget_control()', - 'version' => '2.8', - ), 'unregister_widget_control' => array( 'alt' => 'wp_unregister_widget_control()', 'version' => '2.8', ), + 'wp_specialchars' => array( + 'alt' => 'esc_html()', + 'version' => '2.8', + ), - 'the_content_rss' => array( - 'alt' => 'the_content_feed()', + // WP 2.9.0. + '_c' => array( + 'alt' => '_x()', 'version' => '2.9', ), 'make_url_footnote' => array( 'alt' => '', 'version' => '2.9', ), - '_c' => array( - 'alt' => '_x()', + 'the_content_rss' => array( + 'alt' => 'the_content_feed()', 'version' => '2.9', ), - 'translate_with_context' => array( - 'alt' => '_x()', - 'version' => '3.0', - ), - 'nc' => array( - 'alt' => 'nx()', + // WP 3.0.0. + 'add_option_update_handler' => array( + 'alt' => 'register_setting()', 'version' => '3.0', ), - 'get_alloptions' => array( - 'alt' => 'wp_load_alloptions()', + 'automatic_feed_links' => array( + 'alt' => 'add_theme_support( \'automatic-feed-links\' )', 'version' => '3.0', ), 'clean_url' => array( 'alt' => 'esc_url()', 'version' => '3.0', ), + 'codepress_footer_js' => array( + 'alt' => '', + 'version' => '3.0', + ), + 'codepress_get_lang' => array( + 'alt' => '', + 'version' => '3.0', + ), 'delete_usermeta' => array( 'alt' => 'delete_user_meta()', 'version' => '3.0', ), - 'get_usermeta' => array( - 'alt' => 'get_user_meta()', + 'funky_javascript_callback' => array( + 'alt' => '', 'version' => '3.0', ), - 'update_usermeta' => array( - 'alt' => 'update_user_meta()', + 'funky_javascript_fix' => array( + 'alt' => '', 'version' => '3.0', ), - 'automatic_feed_links' => array( - 'alt' => 'add_theme_support( \'automatic-feed-links\' )', + 'get_alloptions' => array( + 'alt' => 'wp_load_alloptions()', 'version' => '3.0', ), 'get_profile' => array( 'alt' => 'get_the_author_meta()', 'version' => '3.0', ), - 'get_usernumposts' => array( - 'alt' => 'count_user_posts()', - 'version' => '3.0', - ), - 'funky_javascript_callback' => array( - 'alt' => '', + 'get_usermeta' => array( + 'alt' => 'get_user_meta()', 'version' => '3.0', ), - 'funky_javascript_fix' => array( - 'alt' => '', + 'get_usernumposts' => array( + 'alt' => 'count_user_posts()', 'version' => '3.0', ), 'is_taxonomy' => array( @@ -513,60 +529,57 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'term_exists()', 'version' => '3.0', ), - 'wp_dropdown_cats' => array( - 'alt' => 'wp_dropdown_categories()', - 'version' => '3.0', - ), - 'add_option_update_handler' => array( - 'alt' => 'register_setting()', + 'nc' => array( + 'alt' => 'nx()', 'version' => '3.0', ), 'remove_option_update_handler' => array( 'alt' => 'unregister_setting()', 'version' => '3.0', ), - 'codepress_get_lang' => array( - 'alt' => '', + 'translate_with_context' => array( + 'alt' => '_x()', 'version' => '3.0', ), - 'codepress_footer_js' => array( - 'alt' => '', + 'update_usermeta' => array( + 'alt' => 'update_user_meta()', 'version' => '3.0', ), 'use_codepress' => array( 'alt' => '', 'version' => '3.0', ), + 'wp_dropdown_cats' => array( + 'alt' => 'wp_dropdown_categories()', + 'version' => '3.0', + ), 'wp_shrink_dimensions' => array( 'alt' => 'wp_constrain_dimensions()', 'version' => '3.0', ), - 'is_plugin_page' => array( - 'alt' => '$plugin_page and/or get_plugin_page_hookname() hooks', - 'version' => '3.1', - ), - 'update_category_cache' => array( + // WP 3.1.0. + 'get_author_user_ids' => array( 'alt' => '', 'version' => '3.1', ), - 'get_users_of_blog' => array( - 'alt' => 'get_users()', + 'get_editable_authors' => array( + 'alt' => '', 'version' => '3.1', ), - 'get_author_user_ids' => array( + 'get_editable_user_ids' => array( 'alt' => '', 'version' => '3.1', ), - 'get_editable_authors' => array( + 'get_nonauthor_user_ids' => array( 'alt' => '', 'version' => '3.1', ), - 'get_editable_user_ids' => array( + 'get_others_drafts' => array( 'alt' => '', 'version' => '3.1', ), - 'get_nonauthor_user_ids' => array( + 'get_others_pending' => array( 'alt' => '', 'version' => '3.1', ), @@ -574,27 +587,28 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => '', 'version' => '3.1', ), - 'get_others_drafts' => array( - 'alt' => '', + 'get_users_of_blog' => array( + 'alt' => 'get_users()', 'version' => '3.1', ), - 'get_others_pending' => array( + 'is_plugin_page' => array( + 'alt' => '$plugin_page and/or get_plugin_page_hookname() hooks', + 'version' => '3.1', + ), + 'update_category_cache' => array( 'alt' => '', 'version' => '3.1', ), - 'wp_timezone_supported' => array( - 'alt' => '', + // WP 3.2.0. + 'favorite_actions' => array( + 'alt' => 'WP_Admin_Bar', 'version' => '3.2', ), 'wp_dashboard_quick_press' => array( 'alt' => '', 'version' => '3.2', ), - 'wp_tiny_mce' => array( - 'alt' => 'wp_editor', - 'version' => '3.2', - ), 'wp_preload_dialogs' => array( 'alt' => 'wp_editor()', 'version' => '3.2', @@ -607,28 +621,33 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'wp_editor()', 'version' => '3.2', ), - 'favorite_actions' => array( - 'alt' => 'WP_Admin_Bar', + 'wp_timezone_supported' => array( + 'alt' => '', 'version' => '3.2', ), - - 'the_editor' => array( + 'wp_tiny_mce' => array( 'alt' => 'wp_editor', + 'version' => '3.2', + ), + + // WP 3.3.0. + 'add_contextual_help' => array( + 'alt' => 'get_current_screen()->add_help_tab()', 'version' => '3.3', ), - 'get_user_metavalues' => array( - 'alt' => '', + 'debug_fclose' => array( + 'alt' => 'error_log()', 'version' => '3.3', ), - 'sanitize_user_object' => array( - 'alt' => '', + 'debug_fopen' => array( + 'alt' => 'error_log()', 'version' => '3.3', ), - 'get_boundary_post_rel_link' => array( - 'alt' => '', + 'debug_fwrite' => array( + 'alt' => 'error_log()', 'version' => '3.3', ), - 'start_post_rel_link' => array( + 'get_boundary_post_rel_link' => array( 'alt' => '', 'version' => '3.3', ), @@ -636,19 +655,15 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => '', 'version' => '3.3', ), - 'index_rel_link' => array( - 'alt' => '', - 'version' => '3.3', - ), 'get_parent_post_rel_link' => array( 'alt' => '', 'version' => '3.3', ), - 'parent_post_rel_link' => array( + 'get_user_metavalues' => array( 'alt' => '', 'version' => '3.3', ), - 'wp_admin_bar_dashboard_view_site_menu' => array( + 'index_rel_link' => array( 'alt' => '', 'version' => '3.3', ), @@ -656,150 +671,146 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'is_member_of_blog()', 'version' => '3.3', ), - 'debug_fopen' => array( - 'alt' => 'error_log()', + 'media_upload_audio' => array( + 'alt' => 'wp_media_upload_handler()', 'version' => '3.3', ), - 'debug_fwrite' => array( - 'alt' => 'error_log()', + 'media_upload_file' => array( + 'alt' => 'wp_media_upload_handler()', 'version' => '3.3', ), - 'debug_fclose' => array( - 'alt' => 'error_log()', + 'media_upload_image' => array( + 'alt' => 'wp_media_upload_handler()', 'version' => '3.3', ), - 'screen_layout' => array( - 'alt' => '$current_screen->render_screen_layout()', + 'media_upload_video' => array( + 'alt' => 'wp_media_upload_handler()', 'version' => '3.3', ), - 'screen_options' => array( - 'alt' => '$current_screen->render_per_page_options()', + 'parent_post_rel_link' => array( + 'alt' => '', 'version' => '3.3', ), - 'screen_meta' => array( - 'alt' => '$current_screen->render_screen_meta()', + 'sanitize_user_object' => array( + 'alt' => '', 'version' => '3.3', ), - 'media_upload_image' => array( - 'alt' => 'wp_media_upload_handler()', + 'screen_layout' => array( + 'alt' => '$current_screen->render_screen_layout()', 'version' => '3.3', ), - 'media_upload_audio' => array( - 'alt' => 'wp_media_upload_handler()', + 'screen_meta' => array( + 'alt' => '$current_screen->render_screen_meta()', 'version' => '3.3', ), - 'media_upload_video' => array( - 'alt' => 'wp_media_upload_handler()', + 'screen_options' => array( + 'alt' => '$current_screen->render_per_page_options()', 'version' => '3.3', ), - 'media_upload_file' => array( - 'alt' => 'wp_media_upload_handler()', + 'start_post_rel_link' => array( + 'alt' => '', 'version' => '3.3', ), - 'type_url_form_image' => array( - 'alt' => 'wp_media_insert_url_form( \'image\' )', + 'the_editor' => array( + 'alt' => 'wp_editor', 'version' => '3.3', ), 'type_url_form_audio' => array( 'alt' => 'wp_media_insert_url_form( \'audio\' )', 'version' => '3.3', ), - 'type_url_form_video' => array( - 'alt' => 'wp_media_insert_url_form( \'video\' )', - 'version' => '3.3', - ), 'type_url_form_file' => array( 'alt' => 'wp_media_insert_url_form( \'file\' )', 'version' => '3.3', ), - 'add_contextual_help' => array( - 'alt' => 'get_current_screen()->add_help_tab()', + 'type_url_form_image' => array( + 'alt' => 'wp_media_insert_url_form( \'image\' )', + 'version' => '3.3', + ), + 'type_url_form_video' => array( + 'alt' => 'wp_media_insert_url_form( \'video\' )', + 'version' => '3.3', + ), + 'wp_admin_bar_dashboard_view_site_menu' => array( + 'alt' => '', 'version' => '3.3', ), - 'get_themes' => array( - 'alt' => 'wp_get_themes()', + // WP 3.4.0. + 'add_custom_background' => array( + 'alt' => 'add_theme_support( \'custom-background\', $args )', 'version' => '3.4', ), - 'get_theme' => array( - 'alt' => 'wp_get_theme()', + 'add_custom_image_header' => array( + 'alt' => 'add_theme_support( \'custom-header\', $args )', 'version' => '3.4', ), - 'get_current_theme' => array( - 'alt' => 'wp_get_theme()', + 'clean_page_cache' => array( + 'alt' => 'clean_post_cache()', 'version' => '3.4', ), 'clean_pre' => array( 'alt' => '', 'version' => '3.4', ), - 'add_custom_image_header' => array( - 'alt' => 'add_theme_support( \'custom-header\', $args )', + 'current_theme_info' => array( + 'alt' => 'wp_get_theme()', 'version' => '3.4', ), - 'remove_custom_image_header' => array( - 'alt' => 'remove_theme_support( \'custom-header\' )', + 'get_allowed_themes' => array( + 'alt' => 'wp_get_themes( array( \'allowed\' => true ) )', 'version' => '3.4', ), - 'add_custom_background' => array( - 'alt' => 'add_theme_support( \'custom-background\', $args )', + 'get_broken_themes' => array( + 'alt' => 'wp_get_themes( array( \'errors\' => true )', 'version' => '3.4', ), - 'remove_custom_background' => array( - 'alt' => 'remove_theme_support( \'custom-background\' )', + 'get_current_theme' => array( + 'alt' => 'wp_get_theme()', 'version' => '3.4', ), - 'get_theme_data' => array( + 'get_theme' => array( 'alt' => 'wp_get_theme()', 'version' => '3.4', ), - 'update_page_cache' => array( - 'alt' => 'update_post_cache()', + 'get_theme_data' => array( + 'alt' => 'wp_get_theme()', 'version' => '3.4', ), - 'clean_page_cache' => array( - 'alt' => 'clean_post_cache()', + 'get_themes' => array( + 'alt' => 'wp_get_themes()', 'version' => '3.4', ), - 'get_allowed_themes' => array( - 'alt' => 'wp_get_themes( array( \'allowed\' => true ) )', + 'remove_custom_background' => array( + 'alt' => 'remove_theme_support( \'custom-background\' )', 'version' => '3.4', ), - 'get_broken_themes' => array( - 'alt' => 'wp_get_themes( array( \'errors\' => true )', + 'remove_custom_image_header' => array( + 'alt' => 'remove_theme_support( \'custom-header\' )', 'version' => '3.4', ), - 'current_theme_info' => array( - 'alt' => 'wp_get_theme()', + 'update_page_cache' => array( + 'alt' => 'update_post_cache()', 'version' => '3.4', ), + + // WP 3.4.1. 'wp_explain_nonce' => array( 'alt' => 'wp_nonce_ays', 'version' => '3.4.1', ), - 'sticky_class' => array( - 'alt' => 'post_class()', - 'version' => '3.5', - ), + // WP 3.5.0. '_get_post_ancestors' => array( 'alt' => '', 'version' => '3.5', ), - 'wp_load_image' => array( - 'alt' => 'wp_get_image_editor()', - 'version' => '3.5', - ), - 'image_resize' => array( - 'alt' => 'wp_get_image_editor()', - 'version' => '3.5', - ), - 'wp_get_single_post' => array( - 'alt' => 'get_post()', + '_insert_into_post_button' => array( + 'alt' => '', 'version' => '3.5', ), - 'user_pass_ok' => array( - 'alt' => 'wp_authenticate()', + '_media_button' => array( + 'alt' => '', 'version' => '3.5', ), '_save_post_hook' => array( @@ -810,27 +821,40 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'wp_image_editor_supports', 'version' => '3.5', ), - '_insert_into_post_button' => array( - 'alt' => '', - 'version' => '3.5', - ), - '_media_button' => array( - 'alt' => '', + 'get_default_page_to_edit' => array( + 'alt' => 'get_default_post_to_edit()', 'version' => '3.5', ), 'get_post_to_edit' => array( 'alt' => 'get_post()', 'version' => '3.5', ), - 'get_default_page_to_edit' => array( - 'alt' => 'get_default_post_to_edit()', + 'image_resize' => array( + 'alt' => 'wp_get_image_editor()', + 'version' => '3.5', + ), + 'sticky_class' => array( + 'alt' => 'post_class()', + 'version' => '3.5', + ), + 'user_pass_ok' => array( + 'alt' => 'wp_authenticate()', 'version' => '3.5', ), 'wp_create_thumbnail' => array( 'alt' => 'image_resize()', 'version' => '3.5', ), + 'wp_get_single_post' => array( + 'alt' => 'get_post()', + 'version' => '3.5', + ), + 'wp_load_image' => array( + 'alt' => 'wp_get_image_editor()', + 'version' => '3.5', + ), + // WP 3.6.0. 'get_user_id_from_string' => array( 'alt' => 'get_user_by()', 'version' => '3.6', @@ -844,6 +868,15 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '3.6', ), + // WP 3.7.0. + '_search_terms_tidy' => array( + 'alt' => '', + 'version' => '3.7', + ), + 'get_blogaddress_by_domain' => array( + 'alt' => '', + 'version' => '3.7', + ), 'the_attachment_links' => array( 'alt' => '', 'version' => '3.7', @@ -860,15 +893,8 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'new Theme_Upgrader()', 'version' => '3.7', ), - '_search_terms_tidy' => array( - 'alt' => '', - 'version' => '3.7', - ), - 'get_blogaddress_by_domain' => array( - 'alt' => '', - 'version' => '3.7', - ), + // WP 3.8.0. 'get_screen_icon' => array( 'alt' => '', 'version' => '3.8', @@ -914,7 +940,8 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '3.8', ), - 'rich_edit_exists' => array( + // WP 3.9.0. + '_relocate_children' => array( 'alt' => '', 'version' => '3.9', ), @@ -930,15 +957,16 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'get_current_site()', 'version' => '3.9', ), - 'wpmu_current_site' => array( + 'rich_edit_exists' => array( 'alt' => '', 'version' => '3.9', ), - '_relocate_children' => array( + 'wpmu_current_site' => array( 'alt' => '', 'version' => '3.9', ), + // WP 4.0.0. 'get_all_category_ids' => array( 'alt' => 'get_terms()', 'version' => '4.0', @@ -952,27 +980,25 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '4.0', ), - 'prepare_control' => array( + // WP 4.1.0. + 'add_tab' => array( 'alt' => '', 'version' => '4.1', ), - 'add_tab' => array( + 'prepare_control' => array( 'alt' => '', 'version' => '4.1', ), - 'remove_tab' => array( + 'print_tab_image' => array( 'alt' => '', 'version' => '4.1', ), - 'print_tab_image' => array( + 'remove_tab' => array( 'alt' => '', 'version' => '4.1', ), - 'setup_widget_addition_previews' => array( - 'alt' => 'customize_dynamic_setting_args', - 'version' => '4.2', - ), + // WP 4.2.0. 'prepreview_added_sidebars_widgets' => array( 'alt' => 'customize_dynamic_setting_args', 'version' => '4.2', @@ -985,8 +1011,13 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'customize_dynamic_setting_args()', 'version' => '4.2', ), + 'setup_widget_addition_previews' => array( + 'alt' => 'customize_dynamic_setting_args', + 'version' => '4.2', + ), - 'preview_theme' => array( + // WP 4.3.0. + '_preview_theme_stylesheet_filter' => array( 'alt' => '', 'version' => '4.3', ), @@ -994,7 +1025,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => '', 'version' => '4.3', ), - '_preview_theme_stylesheet_filter' => array( + 'preview_theme' => array( 'alt' => '', 'version' => '4.3', ), @@ -1006,7 +1037,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => '', 'version' => '4.3', ), - 'wp_richedit_pre' => array( + 'wp_ajax_wp_fullscreen_save_post' => array( 'alt' => '', 'version' => '4.3', ), @@ -1014,25 +1045,26 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => '', 'version' => '4.3', ), - 'wp_ajax_wp_fullscreen_save_post' => array( + 'wp_richedit_pre' => array( 'alt' => '', 'version' => '4.3', ), - 'post_permalink' => array( - 'alt' => 'get_permalink', + // WP 4.4.0. + 'create_empty_blog' => array( + 'alt' => '', 'version' => '4.4', ), 'force_ssl_login' => array( 'alt' => 'force_ssl_admin', 'version' => '4.4', ), - 'create_empty_blog' => array( + 'get_admin_users_for_domain' => array( 'alt' => '', 'version' => '4.4', ), - 'get_admin_users_for_domain' => array( - 'alt' => '', + 'post_permalink' => array( + 'alt' => 'get_permalink', 'version' => '4.4', ), 'wp_get_http' => array( @@ -1045,10 +1077,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '4.4', ), - 'is_comments_popup' => array( - 'alt' => '', - 'version' => '4.5', - ), + // WP 4.5.0. 'add_object_page' => array( 'alt' => 'add_menu_page()', 'version' => '4.5', @@ -1057,15 +1086,11 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'add_menu_page()', 'version' => '4.5', ), - 'get_comments_popup_template' => array( - 'alt' => '', - 'version' => '4.5', - ), 'comments_popup_script' => array( 'alt' => '', 'version' => '4.5', ), - 'popuplinks' => array( + 'get_comments_popup_template' => array( 'alt' => '', 'version' => '4.5', ), @@ -1073,7 +1098,16 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'wp_get_current_user()', 'version' => '4.5', ), + 'is_comments_popup' => array( + 'alt' => '', + 'version' => '4.5', + ), + 'popuplinks' => array( + 'alt' => '', + 'version' => '4.5', + ), + // WP 4.6.0. 'wp_embed_handler_googlevideo' => array( 'alt' => '', 'version' => '4.6', @@ -1083,6 +1117,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '4.6', ), + // WP 4.7.0. '_sort_nav_menu_items' => array( 'alt' => 'wp_list_sort', 'version' => '4.7', @@ -1108,6 +1143,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '4.7', ), + // WP 4.8.0. 'wp_dashboard_plugins_output' => array( 'alt' => '', 'version' => '4.8', diff --git a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc index bdacb72a..e7ddb027 100644 --- a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc +++ b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc @@ -1,210 +1,231 @@ => */ public function getErrorList() { - return array_fill( 8, 241, 1 ); + $errors = array_fill( 8, 268, 1 ); + + // Unset the lines related to version comments. + unset( + $errors[10], $errors[12], $errors[14], $errors[16], $errors[28], + $errors[54], $errors[56], $errors[58], $errors[71], $errors[74], + $errors[78], $errors[115], $errors[119], $errors[141], $errors[152], + $errors[160], $errors[187], $errors[203], $errors[217], $errors[221], + $errors[228], $errors[240], $errors[247], $errors[251], $errors[256], + $errors[261], $errors[269] + ); + + return $errors; } /** @@ -32,8 +44,15 @@ public function getErrorList() { * @return array => */ public function getWarningList() { - return array_fill( 251, 16, 1 ); + $warnings = array_fill( 281, 19, 1 ); + + // Unset the lines related to version comments. + unset( + $warnings[288], $warnings[291], $warnings[298] + ); + + return $warnings; } } // End class. From 11463c02da37d7484300d628cea63694b61e0b3a Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 21 Jun 2017 02:17:10 +0200 Subject: [PATCH 067/282] DeprecatedFunctions sniff: change version numbers used to fully qualified ones. --- .../Sniffs/WP/DeprecatedFunctionsSniff.php | 510 +++++++++--------- 1 file changed, 256 insertions(+), 254 deletions(-) diff --git a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php index 56de473b..8bc94bb0 100644 --- a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php +++ b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php @@ -44,6 +44,8 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun * To be updated after every major release. * Last updated for WordPress 4.8. * + * Version numbers should be fully qualified. + * * @var array */ private $deprecated_functions = array( @@ -61,13 +63,13 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun // WP 1.2.0. 'permalink_link' => array( 'alt' => 'the_permalink()', - 'version' => '1.2', + 'version' => '1.2.0', ), // WP 1.5.0. 'start_wp' => array( 'alt' => 'the Loop', - 'version' => '1.5', + 'version' => '1.5.0', ), // WP 1.5.1. @@ -79,719 +81,719 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun // WP 2.0.0. 'create_user' => array( 'alt' => 'wp_create_user()', - 'version' => '2.0', + 'version' => '2.0.0', ), 'next_post' => array( 'alt' => 'next_post_link()', - 'version' => '2.0', + 'version' => '2.0.0', ), 'previous_post' => array( 'alt' => 'previous_post_link()', - 'version' => '2.0', + 'version' => '2.0.0', ), 'user_can_create_draft' => array( 'alt' => 'current_user_can()', - 'version' => '2.0', + 'version' => '2.0.0', ), 'user_can_create_post' => array( 'alt' => 'current_user_can()', - 'version' => '2.0', + 'version' => '2.0.0', ), 'user_can_delete_post' => array( 'alt' => 'current_user_can()', - 'version' => '2.0', + 'version' => '2.0.0', ), 'user_can_delete_post_comments' => array( 'alt' => 'current_user_can()', - 'version' => '2.0', + 'version' => '2.0.0', ), 'user_can_edit_post' => array( 'alt' => 'current_user_can()', - 'version' => '2.0', + 'version' => '2.0.0', ), 'user_can_edit_post_comments' => array( 'alt' => 'current_user_can()', - 'version' => '2.0', + 'version' => '2.0.0', ), 'user_can_edit_user' => array( 'alt' => 'current_user_can()', - 'version' => '2.0', + 'version' => '2.0.0', ), 'user_can_set_post_date' => array( 'alt' => 'current_user_can()', - 'version' => '2.0', + 'version' => '2.0.0', ), // WP 2.1.0. 'dropdown_cats' => array( 'alt' => 'wp_dropdown_categories()', - 'version' => '2.1', + 'version' => '2.1.0', ), 'get_archives' => array( 'alt' => 'wp_get_archives', - 'version' => '2.1', + 'version' => '2.1.0', ), 'get_author_link' => array( 'alt' => 'get_author_posts_url()', - 'version' => '2.1', + 'version' => '2.1.0', ), 'get_autotoggle' => array( 'alt' => '', - 'version' => '2.1', + 'version' => '2.1.0', ), 'get_link' => array( 'alt' => 'get_bookmark()', - 'version' => '2.1', + 'version' => '2.1.0', ), 'get_linkcatname' => array( 'alt' => 'get_category()', - 'version' => '2.1', + 'version' => '2.1.0', ), 'get_linkobjects' => array( 'alt' => 'get_bookmarks()', - 'version' => '2.1', + 'version' => '2.1.0', ), 'get_linkobjectsbyname' => array( 'alt' => 'get_bookmarks()', - 'version' => '2.1', + 'version' => '2.1.0', ), 'get_linkrating' => array( 'alt' => 'sanitize_bookmark_field()', - 'version' => '2.1', + 'version' => '2.1.0', ), 'get_links' => array( 'alt' => 'get_bookmarks()', - 'version' => '2.1', + 'version' => '2.1.0', ), 'get_links_list' => array( 'alt' => 'wp_list_bookmarks()', - 'version' => '2.1', + 'version' => '2.1.0', ), 'get_links_withrating' => array( 'alt' => 'get_bookmarks()', - 'version' => '2.1', + 'version' => '2.1.0', ), 'get_linksbyname' => array( 'alt' => 'get_bookmarks()', - 'version' => '2.1', + 'version' => '2.1.0', ), 'get_linksbyname_withrating' => array( 'alt' => 'get_bookmarks()', - 'version' => '2.1', + 'version' => '2.1.0', ), 'get_settings' => array( 'alt' => 'get_option()', - 'version' => '2.1', + 'version' => '2.1.0', ), 'link_pages' => array( 'alt' => 'wp_link_pages()', - 'version' => '2.1', + 'version' => '2.1.0', ), 'links_popup_script' => array( 'alt' => '', - 'version' => '2.1', + 'version' => '2.1.0', ), 'list_authors' => array( 'alt' => 'wp_list_authors()', - 'version' => '2.1', + 'version' => '2.1.0', ), 'list_cats' => array( 'alt' => 'wp_list_categories', - 'version' => '2.1', + 'version' => '2.1.0', ), 'tinymce_include' => array( 'alt' => 'wp_tiny_mce()', - 'version' => '2.1', + 'version' => '2.1.0', ), 'wp_get_links' => array( 'alt' => 'wp_list_bookmarks()', - 'version' => '2.1', + 'version' => '2.1.0', ), 'wp_get_linksbyname' => array( 'alt' => 'wp_list_bookmarks()', - 'version' => '2.1', + 'version' => '2.1.0', ), 'wp_get_post_cats' => array( 'alt' => 'wp_get_post_categories()', - 'version' => '2.1', + 'version' => '2.1.0', ), 'wp_list_cats' => array( 'alt' => 'wp_list_categories', - 'version' => '2.1', + 'version' => '2.1.0', ), 'wp_set_post_cats' => array( 'alt' => 'wp_set_post_categories()', - 'version' => '2.1', + 'version' => '2.1.0', ), // WP 2.2.0. 'comments_rss' => array( 'alt' => 'get_post_comments_feed_link()', - 'version' => '2.2', + 'version' => '2.2.0', ), // WP 2.3.0. 'permalink_single_rss' => array( 'alt' => 'permalink_rss()', - 'version' => '2.3', + 'version' => '2.3.0', ), // WP 2.5.0. 'comments_rss_link' => array( 'alt' => 'post_comments_feed_link()', - 'version' => '2.5', + 'version' => '2.5.0', ), 'documentation_link' => array( 'alt' => '', - 'version' => '2.5', + 'version' => '2.5.0', ), 'get_attachment_icon' => array( 'alt' => 'wp_get_attachment_image()', - 'version' => '2.5', + 'version' => '2.5.0', ), 'get_attachment_icon_src' => array( 'alt' => 'wp_get_attachment_image_src()', - 'version' => '2.5', + 'version' => '2.5.0', ), 'get_attachment_innerHTML' => array( 'alt' => 'wp_get_attachment_image()', - 'version' => '2.5', + 'version' => '2.5.0', ), 'get_author_rss_link' => array( 'alt' => 'get_author_feed_link()', - 'version' => '2.5', + 'version' => '2.5.0', ), 'get_category_rss_link' => array( 'alt' => 'get_category_feed_link()', - 'version' => '2.5', + 'version' => '2.5.0', ), 'get_the_attachment_link' => array( 'alt' => 'wp_get_attachment_link()', - 'version' => '2.5', + 'version' => '2.5.0', ), 'gzip_compression' => array( 'alt' => '', - 'version' => '2.5', + 'version' => '2.5.0', ), 'wp_get_cookie_login' => array( 'alt' => '', - 'version' => '2.5', + 'version' => '2.5.0', ), 'wp_login' => array( 'alt' => 'wp_signon()', - 'version' => '2.5', + 'version' => '2.5.0', ), 'wp_setcookie' => array( 'alt' => 'wp_set_auth_cookie()', - 'version' => '2.5', + 'version' => '2.5.0', ), // WP 2.6.0. 'dropdown_categories' => array( 'alt' => 'wp_category_checklist()', - 'version' => '2.6', + 'version' => '2.6.0', ), 'dropdown_link_categories' => array( 'alt' => 'wp_link_category_checklist()', - 'version' => '2.6', + 'version' => '2.6.0', ), // WP 2.7.0. 'get_commentdata' => array( 'alt' => 'get_comment()', - 'version' => '2.7', + 'version' => '2.7.0', ), // This is a method i.e. WP_Filesystem_Base::find_base_dir() See #731. 'find_base_dir' => array( 'alt' => 'WP_Filesystem::abspath()', - 'version' => '2.7', + 'version' => '2.7.0', ), // This is a method i.e. WP_Filesystem_Base::get_base_dir() See #731. 'get_base_dir' => array( 'alt' => 'WP_Filesystem::abspath()', - 'version' => '2.7', + 'version' => '2.7.0', ), // WP 2.8.0. '__ngettext' => array( 'alt' => '_n_noop()', - 'version' => '2.8', + 'version' => '2.8.0', ), '__ngettext_noop' => array( 'alt' => '_n_noop()', - 'version' => '2.8', + 'version' => '2.8.0', ), 'attribute_escape' => array( 'alt' => 'esc_attr()', - 'version' => '2.8', + 'version' => '2.8.0', ), 'get_author_name' => array( 'alt' => 'get_the_author_meta(\'display_name\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'get_category_children' => array( 'alt' => 'get_term_children', - 'version' => '2.8', + 'version' => '2.8.0', ), 'get_catname' => array( 'alt' => 'get_cat_name()', - 'version' => '2.8', + 'version' => '2.8.0', ), 'get_the_author_aim' => array( 'alt' => 'get_the_author_meta(\'aim\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'get_the_author_description' => array( 'alt' => "get_the_author_meta( 'description' )", - 'version' => '2.8', + 'version' => '2.8.0', ), 'get_the_author_email' => array( 'alt' => 'get_the_author_meta(\'email\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'get_the_author_firstname' => array( 'alt' => 'get_the_author_meta(\'first_name\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'get_the_author_icq' => array( 'alt' => 'get_the_author_meta(\'icq\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'get_the_author_ID' => array( 'alt' => 'get_the_author_meta(\'ID\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'get_the_author_lastname' => array( 'alt' => 'get_the_author_meta(\'last_name\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'get_the_author_login' => array( 'alt' => 'the_author_meta(\'login\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'get_the_author_msn' => array( 'alt' => 'get_the_author_meta(\'msn\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'get_the_author_nickname' => array( 'alt' => 'get_the_author_meta(\'nickname\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'get_the_author_url' => array( 'alt' => 'get_the_author_meta(\'url\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'get_the_author_yim' => array( 'alt' => 'get_the_author_meta(\'yim\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'js_escape' => array( 'alt' => 'esc_js()', - 'version' => '2.8', + 'version' => '2.8.0', ), 'register_sidebar_widget' => array( 'alt' => 'wp_register_sidebar_widget()', - 'version' => '2.8', + 'version' => '2.8.0', ), 'register_widget_control' => array( 'alt' => 'wp_register_widget_control()', - 'version' => '2.8', + 'version' => '2.8.0', ), 'sanitize_url' => array( 'alt' => 'esc_url()', - 'version' => '2.8', + 'version' => '2.8.0', ), 'the_author_aim' => array( 'alt' => 'the_author_meta(\'aim\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'the_author_description' => array( 'alt' => 'the_author_meta(\'description\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'the_author_email' => array( 'alt' => 'the_author_meta(\'email\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'the_author_firstname' => array( 'alt' => 'the_author_meta(\'first_name\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'the_author_icq' => array( 'alt' => 'the_author_meta(\'icq\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'the_author_ID' => array( 'alt' => 'the_author_meta(\'ID\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'the_author_lastname' => array( 'alt' => 'the_author_meta(\'last_name\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'the_author_msn' => array( 'alt' => 'the_author_meta(\'msn\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'the_author_nickname' => array( 'alt' => 'the_author_meta(\'nickname\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'the_author_url' => array( 'alt' => 'the_author_meta(\'url\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'the_author_yim' => array( 'alt' => 'the_author_meta(\'yim\')', - 'version' => '2.8', + 'version' => '2.8.0', ), 'unregister_sidebar_widget' => array( 'alt' => 'wp_unregister_sidebar_widget()', - 'version' => '2.8', + 'version' => '2.8.0', ), 'unregister_widget_control' => array( 'alt' => 'wp_unregister_widget_control()', - 'version' => '2.8', + 'version' => '2.8.0', ), 'wp_specialchars' => array( 'alt' => 'esc_html()', - 'version' => '2.8', + 'version' => '2.8.0', ), // WP 2.9.0. '_c' => array( 'alt' => '_x()', - 'version' => '2.9', + 'version' => '2.9.0', ), 'make_url_footnote' => array( 'alt' => '', - 'version' => '2.9', + 'version' => '2.9.0', ), 'the_content_rss' => array( 'alt' => 'the_content_feed()', - 'version' => '2.9', + 'version' => '2.9.0', ), // WP 3.0.0. 'add_option_update_handler' => array( 'alt' => 'register_setting()', - 'version' => '3.0', + 'version' => '3.0.0', ), 'automatic_feed_links' => array( 'alt' => 'add_theme_support( \'automatic-feed-links\' )', - 'version' => '3.0', + 'version' => '3.0.0', ), 'clean_url' => array( 'alt' => 'esc_url()', - 'version' => '3.0', + 'version' => '3.0.0', ), 'codepress_footer_js' => array( 'alt' => '', - 'version' => '3.0', + 'version' => '3.0.0', ), 'codepress_get_lang' => array( 'alt' => '', - 'version' => '3.0', + 'version' => '3.0.0', ), 'delete_usermeta' => array( 'alt' => 'delete_user_meta()', - 'version' => '3.0', + 'version' => '3.0.0', ), 'funky_javascript_callback' => array( 'alt' => '', - 'version' => '3.0', + 'version' => '3.0.0', ), 'funky_javascript_fix' => array( 'alt' => '', - 'version' => '3.0', + 'version' => '3.0.0', ), 'get_alloptions' => array( 'alt' => 'wp_load_alloptions()', - 'version' => '3.0', + 'version' => '3.0.0', ), 'get_profile' => array( 'alt' => 'get_the_author_meta()', - 'version' => '3.0', + 'version' => '3.0.0', ), 'get_usermeta' => array( 'alt' => 'get_user_meta()', - 'version' => '3.0', + 'version' => '3.0.0', ), 'get_usernumposts' => array( 'alt' => 'count_user_posts()', - 'version' => '3.0', + 'version' => '3.0.0', ), 'is_taxonomy' => array( 'alt' => 'taxonomy_exists()', - 'version' => '3.0', + 'version' => '3.0.0', ), 'is_term' => array( 'alt' => 'term_exists()', - 'version' => '3.0', + 'version' => '3.0.0', ), 'nc' => array( 'alt' => 'nx()', - 'version' => '3.0', + 'version' => '3.0.0', ), 'remove_option_update_handler' => array( 'alt' => 'unregister_setting()', - 'version' => '3.0', + 'version' => '3.0.0', ), 'translate_with_context' => array( 'alt' => '_x()', - 'version' => '3.0', + 'version' => '3.0.0', ), 'update_usermeta' => array( 'alt' => 'update_user_meta()', - 'version' => '3.0', + 'version' => '3.0.0', ), 'use_codepress' => array( 'alt' => '', - 'version' => '3.0', + 'version' => '3.0.0', ), 'wp_dropdown_cats' => array( 'alt' => 'wp_dropdown_categories()', - 'version' => '3.0', + 'version' => '3.0.0', ), 'wp_shrink_dimensions' => array( 'alt' => 'wp_constrain_dimensions()', - 'version' => '3.0', + 'version' => '3.0.0', ), // WP 3.1.0. 'get_author_user_ids' => array( 'alt' => '', - 'version' => '3.1', + 'version' => '3.1.0', ), 'get_editable_authors' => array( 'alt' => '', - 'version' => '3.1', + 'version' => '3.1.0', ), 'get_editable_user_ids' => array( 'alt' => '', - 'version' => '3.1', + 'version' => '3.1.0', ), 'get_nonauthor_user_ids' => array( 'alt' => '', - 'version' => '3.1', + 'version' => '3.1.0', ), 'get_others_drafts' => array( 'alt' => '', - 'version' => '3.1', + 'version' => '3.1.0', ), 'get_others_pending' => array( 'alt' => '', - 'version' => '3.1', + 'version' => '3.1.0', ), 'get_others_unpublished_posts' => array( 'alt' => '', - 'version' => '3.1', + 'version' => '3.1.0', ), 'get_users_of_blog' => array( 'alt' => 'get_users()', - 'version' => '3.1', + 'version' => '3.1.0', ), 'is_plugin_page' => array( 'alt' => '$plugin_page and/or get_plugin_page_hookname() hooks', - 'version' => '3.1', + 'version' => '3.1.0', ), 'update_category_cache' => array( 'alt' => '', - 'version' => '3.1', + 'version' => '3.1.0', ), // WP 3.2.0. 'favorite_actions' => array( 'alt' => 'WP_Admin_Bar', - 'version' => '3.2', + 'version' => '3.2.0', ), 'wp_dashboard_quick_press' => array( 'alt' => '', - 'version' => '3.2', + 'version' => '3.2.0', ), 'wp_preload_dialogs' => array( 'alt' => 'wp_editor()', - 'version' => '3.2', + 'version' => '3.2.0', ), 'wp_print_editor_js' => array( 'alt' => 'wp_editor()', - 'version' => '3.2', + 'version' => '3.2.0', ), 'wp_quicktags' => array( 'alt' => 'wp_editor()', - 'version' => '3.2', + 'version' => '3.2.0', ), 'wp_timezone_supported' => array( 'alt' => '', - 'version' => '3.2', + 'version' => '3.2.0', ), 'wp_tiny_mce' => array( 'alt' => 'wp_editor', - 'version' => '3.2', + 'version' => '3.2.0', ), // WP 3.3.0. 'add_contextual_help' => array( 'alt' => 'get_current_screen()->add_help_tab()', - 'version' => '3.3', + 'version' => '3.3.0', ), 'debug_fclose' => array( 'alt' => 'error_log()', - 'version' => '3.3', + 'version' => '3.3.0', ), 'debug_fopen' => array( 'alt' => 'error_log()', - 'version' => '3.3', + 'version' => '3.3.0', ), 'debug_fwrite' => array( 'alt' => 'error_log()', - 'version' => '3.3', + 'version' => '3.3.0', ), 'get_boundary_post_rel_link' => array( 'alt' => '', - 'version' => '3.3', + 'version' => '3.3.0', ), 'get_index_rel_link' => array( 'alt' => '', - 'version' => '3.3', + 'version' => '3.3.0', ), 'get_parent_post_rel_link' => array( 'alt' => '', - 'version' => '3.3', + 'version' => '3.3.0', ), 'get_user_metavalues' => array( 'alt' => '', - 'version' => '3.3', + 'version' => '3.3.0', ), 'index_rel_link' => array( 'alt' => '', - 'version' => '3.3', + 'version' => '3.3.0', ), 'is_blog_user' => array( 'alt' => 'is_member_of_blog()', - 'version' => '3.3', + 'version' => '3.3.0', ), 'media_upload_audio' => array( 'alt' => 'wp_media_upload_handler()', - 'version' => '3.3', + 'version' => '3.3.0', ), 'media_upload_file' => array( 'alt' => 'wp_media_upload_handler()', - 'version' => '3.3', + 'version' => '3.3.0', ), 'media_upload_image' => array( 'alt' => 'wp_media_upload_handler()', - 'version' => '3.3', + 'version' => '3.3.0', ), 'media_upload_video' => array( 'alt' => 'wp_media_upload_handler()', - 'version' => '3.3', + 'version' => '3.3.0', ), 'parent_post_rel_link' => array( 'alt' => '', - 'version' => '3.3', + 'version' => '3.3.0', ), 'sanitize_user_object' => array( 'alt' => '', - 'version' => '3.3', + 'version' => '3.3.0', ), 'screen_layout' => array( 'alt' => '$current_screen->render_screen_layout()', - 'version' => '3.3', + 'version' => '3.3.0', ), 'screen_meta' => array( 'alt' => '$current_screen->render_screen_meta()', - 'version' => '3.3', + 'version' => '3.3.0', ), 'screen_options' => array( 'alt' => '$current_screen->render_per_page_options()', - 'version' => '3.3', + 'version' => '3.3.0', ), 'start_post_rel_link' => array( 'alt' => '', - 'version' => '3.3', + 'version' => '3.3.0', ), 'the_editor' => array( 'alt' => 'wp_editor', - 'version' => '3.3', + 'version' => '3.3.0', ), 'type_url_form_audio' => array( 'alt' => 'wp_media_insert_url_form( \'audio\' )', - 'version' => '3.3', + 'version' => '3.3.0', ), 'type_url_form_file' => array( 'alt' => 'wp_media_insert_url_form( \'file\' )', - 'version' => '3.3', + 'version' => '3.3.0', ), 'type_url_form_image' => array( 'alt' => 'wp_media_insert_url_form( \'image\' )', - 'version' => '3.3', + 'version' => '3.3.0', ), 'type_url_form_video' => array( 'alt' => 'wp_media_insert_url_form( \'video\' )', - 'version' => '3.3', + 'version' => '3.3.0', ), 'wp_admin_bar_dashboard_view_site_menu' => array( 'alt' => '', - 'version' => '3.3', + 'version' => '3.3.0', ), // WP 3.4.0. 'add_custom_background' => array( 'alt' => 'add_theme_support( \'custom-background\', $args )', - 'version' => '3.4', + 'version' => '3.4.0', ), 'add_custom_image_header' => array( 'alt' => 'add_theme_support( \'custom-header\', $args )', - 'version' => '3.4', + 'version' => '3.4.0', ), 'clean_page_cache' => array( 'alt' => 'clean_post_cache()', - 'version' => '3.4', + 'version' => '3.4.0', ), 'clean_pre' => array( 'alt' => '', - 'version' => '3.4', + 'version' => '3.4.0', ), 'current_theme_info' => array( 'alt' => 'wp_get_theme()', - 'version' => '3.4', + 'version' => '3.4.0', ), 'get_allowed_themes' => array( 'alt' => 'wp_get_themes( array( \'allowed\' => true ) )', - 'version' => '3.4', + 'version' => '3.4.0', ), 'get_broken_themes' => array( 'alt' => 'wp_get_themes( array( \'errors\' => true )', - 'version' => '3.4', + 'version' => '3.4.0', ), 'get_current_theme' => array( 'alt' => 'wp_get_theme()', - 'version' => '3.4', + 'version' => '3.4.0', ), 'get_theme' => array( 'alt' => 'wp_get_theme()', - 'version' => '3.4', + 'version' => '3.4.0', ), 'get_theme_data' => array( 'alt' => 'wp_get_theme()', - 'version' => '3.4', + 'version' => '3.4.0', ), 'get_themes' => array( 'alt' => 'wp_get_themes()', - 'version' => '3.4', + 'version' => '3.4.0', ), 'remove_custom_background' => array( 'alt' => 'remove_theme_support( \'custom-background\' )', - 'version' => '3.4', + 'version' => '3.4.0', ), 'remove_custom_image_header' => array( 'alt' => 'remove_theme_support( \'custom-header\' )', - 'version' => '3.4', + 'version' => '3.4.0', ), 'update_page_cache' => array( 'alt' => 'update_post_cache()', - 'version' => '3.4', + 'version' => '3.4.0', ), // WP 3.4.1. @@ -803,350 +805,350 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun // WP 3.5.0. '_get_post_ancestors' => array( 'alt' => '', - 'version' => '3.5', + 'version' => '3.5.0', ), '_insert_into_post_button' => array( 'alt' => '', - 'version' => '3.5', + 'version' => '3.5.0', ), '_media_button' => array( 'alt' => '', - 'version' => '3.5', + 'version' => '3.5.0', ), '_save_post_hook' => array( 'alt' => '', - 'version' => '3.5', + 'version' => '3.5.0', ), 'gd_edit_image_support' => array( 'alt' => 'wp_image_editor_supports', - 'version' => '3.5', + 'version' => '3.5.0', ), 'get_default_page_to_edit' => array( 'alt' => 'get_default_post_to_edit()', - 'version' => '3.5', + 'version' => '3.5.0', ), 'get_post_to_edit' => array( 'alt' => 'get_post()', - 'version' => '3.5', + 'version' => '3.5.0', ), 'image_resize' => array( 'alt' => 'wp_get_image_editor()', - 'version' => '3.5', + 'version' => '3.5.0', ), 'sticky_class' => array( 'alt' => 'post_class()', - 'version' => '3.5', + 'version' => '3.5.0', ), 'user_pass_ok' => array( 'alt' => 'wp_authenticate()', - 'version' => '3.5', + 'version' => '3.5.0', ), 'wp_create_thumbnail' => array( 'alt' => 'image_resize()', - 'version' => '3.5', + 'version' => '3.5.0', ), 'wp_get_single_post' => array( 'alt' => 'get_post()', - 'version' => '3.5', + 'version' => '3.5.0', ), 'wp_load_image' => array( 'alt' => 'wp_get_image_editor()', - 'version' => '3.5', + 'version' => '3.5.0', ), // WP 3.6.0. 'get_user_id_from_string' => array( 'alt' => 'get_user_by()', - 'version' => '3.6', + 'version' => '3.6.0', ), 'wp_convert_bytes_to_hr' => array( 'alt' => 'size_format()', - 'version' => '3.6', + 'version' => '3.6.0', ), 'wp_nav_menu_locations_meta_box' => array( 'alt' => '', - 'version' => '3.6', + 'version' => '3.6.0', ), // WP 3.7.0. '_search_terms_tidy' => array( 'alt' => '', - 'version' => '3.7', + 'version' => '3.7.0', ), 'get_blogaddress_by_domain' => array( 'alt' => '', - 'version' => '3.7', + 'version' => '3.7.0', ), 'the_attachment_links' => array( 'alt' => '', - 'version' => '3.7', + 'version' => '3.7.0', ), 'wp_update_core' => array( 'alt' => 'new Core_Upgrader()', - 'version' => '3.7', + 'version' => '3.7.0', ), 'wp_update_plugin' => array( 'alt' => 'new Plugin_Upgrader()', - 'version' => '3.7', + 'version' => '3.7.0', ), 'wp_update_theme' => array( 'alt' => 'new Theme_Upgrader()', - 'version' => '3.7', + 'version' => '3.7.0', ), // WP 3.8.0. 'get_screen_icon' => array( 'alt' => '', - 'version' => '3.8', + 'version' => '3.8.0', ), 'screen_icon' => array( 'alt' => '', - 'version' => '3.8', + 'version' => '3.8.0', ), 'wp_dashboard_incoming_links' => array( 'alt' => '', - 'version' => '3.8', + 'version' => '3.8.0', ), 'wp_dashboard_incoming_links_control' => array( 'alt' => '', - 'version' => '3.8', + 'version' => '3.8.0', ), 'wp_dashboard_incoming_links_output' => array( 'alt' => '', - 'version' => '3.8', + 'version' => '3.8.0', ), 'wp_dashboard_plugins' => array( 'alt' => '', - 'version' => '3.8', + 'version' => '3.8.0', ), 'wp_dashboard_primary_control' => array( 'alt' => '', - 'version' => '3.8', + 'version' => '3.8.0', ), 'wp_dashboard_recent_comments_control' => array( 'alt' => '', - 'version' => '3.8', + 'version' => '3.8.0', ), 'wp_dashboard_secondary' => array( 'alt' => '', - 'version' => '3.8', + 'version' => '3.8.0', ), 'wp_dashboard_secondary_control' => array( 'alt' => '', - 'version' => '3.8', + 'version' => '3.8.0', ), 'wp_dashboard_secondary_output' => array( 'alt' => '', - 'version' => '3.8', + 'version' => '3.8.0', ), // WP 3.9.0. '_relocate_children' => array( 'alt' => '', - 'version' => '3.9', + 'version' => '3.9.0', ), 'default_topic_count_text' => array( 'alt' => '', - 'version' => '3.9', + 'version' => '3.9.0', ), 'format_to_post' => array( 'alt' => '', - 'version' => '3.9', + 'version' => '3.9.0', ), 'get_current_site_name' => array( 'alt' => 'get_current_site()', - 'version' => '3.9', + 'version' => '3.9.0', ), 'rich_edit_exists' => array( 'alt' => '', - 'version' => '3.9', + 'version' => '3.9.0', ), 'wpmu_current_site' => array( 'alt' => '', - 'version' => '3.9', + 'version' => '3.9.0', ), // WP 4.0.0. 'get_all_category_ids' => array( 'alt' => 'get_terms()', - 'version' => '4.0', + 'version' => '4.0.0', ), 'like_escape' => array( 'alt' => 'wpdb::esc_like()', - 'version' => '4.0', + 'version' => '4.0.0', ), 'url_is_accessable_via_ssl' => array( 'alt' => '', - 'version' => '4.0', + 'version' => '4.0.0', ), // WP 4.1.0. 'add_tab' => array( 'alt' => '', - 'version' => '4.1', + 'version' => '4.1.0', ), 'prepare_control' => array( 'alt' => '', - 'version' => '4.1', + 'version' => '4.1.0', ), 'print_tab_image' => array( 'alt' => '', - 'version' => '4.1', + 'version' => '4.1.0', ), 'remove_tab' => array( 'alt' => '', - 'version' => '4.1', + 'version' => '4.1.0', ), // WP 4.2.0. 'prepreview_added_sidebars_widgets' => array( 'alt' => 'customize_dynamic_setting_args', - 'version' => '4.2', + 'version' => '4.2.0', ), 'prepreview_added_widget_instance' => array( 'alt' => 'customize_dynamic_setting_args', - 'version' => '4.2', + 'version' => '4.2.0', ), 'remove_prepreview_filters' => array( 'alt' => 'customize_dynamic_setting_args()', - 'version' => '4.2', + 'version' => '4.2.0', ), 'setup_widget_addition_previews' => array( 'alt' => 'customize_dynamic_setting_args', - 'version' => '4.2', + 'version' => '4.2.0', ), // WP 4.3.0. '_preview_theme_stylesheet_filter' => array( 'alt' => '', - 'version' => '4.3', + 'version' => '4.3.0', ), '_preview_theme_template_filter' => array( 'alt' => '', - 'version' => '4.3', + 'version' => '4.3.0', ), 'preview_theme' => array( 'alt' => '', - 'version' => '4.3', + 'version' => '4.3.0', ), 'preview_theme_ob_filter' => array( 'alt' => '', - 'version' => '4.3', + 'version' => '4.3.0', ), 'preview_theme_ob_filter_callback' => array( 'alt' => '', - 'version' => '4.3', + 'version' => '4.3.0', ), 'wp_ajax_wp_fullscreen_save_post' => array( 'alt' => '', - 'version' => '4.3', + 'version' => '4.3.0', ), 'wp_htmledit_pre' => array( 'alt' => '', - 'version' => '4.3', + 'version' => '4.3.0', ), 'wp_richedit_pre' => array( 'alt' => '', - 'version' => '4.3', + 'version' => '4.3.0', ), // WP 4.4.0. 'create_empty_blog' => array( 'alt' => '', - 'version' => '4.4', + 'version' => '4.4.0', ), 'force_ssl_login' => array( 'alt' => 'force_ssl_admin', - 'version' => '4.4', + 'version' => '4.4.0', ), 'get_admin_users_for_domain' => array( 'alt' => '', - 'version' => '4.4', + 'version' => '4.4.0', ), 'post_permalink' => array( 'alt' => 'get_permalink', - 'version' => '4.4', + 'version' => '4.4.0', ), 'wp_get_http' => array( 'alt' => 'WP_Http', - 'version' => '4.4', + 'version' => '4.4.0', ), // This is a method i.e. WP_Widget_Recent_Comments::flush_widget_cache() See #731. 'flush_widget_cache' => array( 'alt' => '', - 'version' => '4.4', + 'version' => '4.4.0', ), // WP 4.5.0. 'add_object_page' => array( 'alt' => 'add_menu_page()', - 'version' => '4.5', + 'version' => '4.5.0', ), 'add_utility_page' => array( 'alt' => 'add_menu_page()', - 'version' => '4.5', + 'version' => '4.5.0', ), 'comments_popup_script' => array( 'alt' => '', - 'version' => '4.5', + 'version' => '4.5.0', ), 'get_comments_popup_template' => array( 'alt' => '', - 'version' => '4.5', + 'version' => '4.5.0', ), 'get_currentuserinfo' => array( 'alt' => 'wp_get_current_user()', - 'version' => '4.5', + 'version' => '4.5.0', ), 'is_comments_popup' => array( 'alt' => '', - 'version' => '4.5', + 'version' => '4.5.0', ), 'popuplinks' => array( 'alt' => '', - 'version' => '4.5', + 'version' => '4.5.0', ), // WP 4.6.0. 'wp_embed_handler_googlevideo' => array( 'alt' => '', - 'version' => '4.6', + 'version' => '4.6.0', ), 'wp_get_sites' => array( 'alt' => 'get_sites()', - 'version' => '4.6', + 'version' => '4.6.0', ), // WP 4.7.0. '_sort_nav_menu_items' => array( 'alt' => 'wp_list_sort', - 'version' => '4.7', + 'version' => '4.7.0', ), '_usort_terms_by_ID' => array( 'alt' => 'wp_list_sort', - 'version' => '4.7', + 'version' => '4.7.0', ), '_usort_terms_by_name' => array( 'alt' => 'wp_list_sort', - 'version' => '4.7', + 'version' => '4.7.0', ), 'get_paged_template' => array( 'alt' => '', - 'version' => '4.7', + 'version' => '4.7.0', ), 'wp_get_network' => array( 'alt' => 'get_network', - 'version' => '4.7', + 'version' => '4.7.0', ), 'wp_kses_js_entities' => array( 'alt' => '', - 'version' => '4.7', + 'version' => '4.7.0', ), // WP 4.8.0. 'wp_dashboard_plugins_output' => array( 'alt' => '', - 'version' => '4.8', + 'version' => '4.8.0', ), ); From 52ac2cd955138c0ce32be40ecfda8300763bfff9 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 21 Jun 2017 02:34:58 +0200 Subject: [PATCH 068/282] DeprecatedFunctions sniff: Add parentheses to replacement functions --- .../Sniffs/WP/DeprecatedFunctionsSniff.php | 42 ++++++++++--------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php index 8bc94bb0..1ad543f3 100644 --- a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php +++ b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php @@ -45,6 +45,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun * Last updated for WordPress 4.8. * * Version numbers should be fully qualified. + * Replacement functions should have parentheses. + * + * To retrieve a function list for comparison, the following tool is available: + * https://github.com/JDGrimes/wp-deprecated-code-scanner * * @var array */ @@ -130,7 +134,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '2.1.0', ), 'get_archives' => array( - 'alt' => 'wp_get_archives', + 'alt' => 'wp_get_archives()', 'version' => '2.1.0', ), 'get_author_link' => array( @@ -198,7 +202,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '2.1.0', ), 'list_cats' => array( - 'alt' => 'wp_list_categories', + 'alt' => 'wp_list_categories()', 'version' => '2.1.0', ), 'tinymce_include' => array( @@ -218,7 +222,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '2.1.0', ), 'wp_list_cats' => array( - 'alt' => 'wp_list_categories', + 'alt' => 'wp_list_categories()', 'version' => '2.1.0', ), 'wp_set_post_cats' => array( @@ -332,7 +336,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '2.8.0', ), 'get_category_children' => array( - 'alt' => 'get_term_children', + 'alt' => 'get_term_children()', 'version' => '2.8.0', ), 'get_catname' => array( @@ -344,7 +348,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '2.8.0', ), 'get_the_author_description' => array( - 'alt' => "get_the_author_meta( 'description' )", + 'alt' => 'get_the_author_meta( \'description\' )', 'version' => '2.8.0', ), 'get_the_author_email' => array( @@ -628,7 +632,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '3.2.0', ), 'wp_tiny_mce' => array( - 'alt' => 'wp_editor', + 'alt' => 'wp_editor()', 'version' => '3.2.0', ), @@ -714,7 +718,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '3.3.0', ), 'the_editor' => array( - 'alt' => 'wp_editor', + 'alt' => 'wp_editor()', 'version' => '3.3.0', ), 'type_url_form_audio' => array( @@ -798,7 +802,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun // WP 3.4.1. 'wp_explain_nonce' => array( - 'alt' => 'wp_nonce_ays', + 'alt' => 'wp_nonce_ays()', 'version' => '3.4.1', ), @@ -820,7 +824,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '3.5.0', ), 'gd_edit_image_support' => array( - 'alt' => 'wp_image_editor_supports', + 'alt' => 'wp_image_editor_supports()', 'version' => '3.5.0', ), 'get_default_page_to_edit' => array( @@ -1002,11 +1006,11 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun // WP 4.2.0. 'prepreview_added_sidebars_widgets' => array( - 'alt' => 'customize_dynamic_setting_args', + 'alt' => 'customize_dynamic_setting_args()', 'version' => '4.2.0', ), 'prepreview_added_widget_instance' => array( - 'alt' => 'customize_dynamic_setting_args', + 'alt' => 'customize_dynamic_setting_args()', 'version' => '4.2.0', ), 'remove_prepreview_filters' => array( @@ -1014,7 +1018,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '4.2.0', ), 'setup_widget_addition_previews' => array( - 'alt' => 'customize_dynamic_setting_args', + 'alt' => 'customize_dynamic_setting_args()', 'version' => '4.2.0', ), @@ -1058,7 +1062,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '4.4.0', ), 'force_ssl_login' => array( - 'alt' => 'force_ssl_admin', + 'alt' => 'force_ssl_admin()', 'version' => '4.4.0', ), 'get_admin_users_for_domain' => array( @@ -1066,11 +1070,11 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '4.4.0', ), 'post_permalink' => array( - 'alt' => 'get_permalink', + 'alt' => 'get_permalink()', 'version' => '4.4.0', ), 'wp_get_http' => array( - 'alt' => 'WP_Http', + 'alt' => 'the WP_Http class', 'version' => '4.4.0', ), // This is a method i.e. WP_Widget_Recent_Comments::flush_widget_cache() See #731. @@ -1121,15 +1125,15 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun // WP 4.7.0. '_sort_nav_menu_items' => array( - 'alt' => 'wp_list_sort', + 'alt' => 'wp_list_sort()', 'version' => '4.7.0', ), '_usort_terms_by_ID' => array( - 'alt' => 'wp_list_sort', + 'alt' => 'wp_list_sort()', 'version' => '4.7.0', ), '_usort_terms_by_name' => array( - 'alt' => 'wp_list_sort', + 'alt' => 'wp_list_sort()', 'version' => '4.7.0', ), 'get_paged_template' => array( @@ -1137,7 +1141,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '4.7.0', ), 'wp_get_network' => array( - 'alt' => 'get_network', + 'alt' => 'get_network()', 'version' => '4.7.0', ), 'wp_kses_js_entities' => array( From 1a4c078384d139dd98f7c81e4145f669da9d2db2 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 22 Jun 2017 18:50:17 +0200 Subject: [PATCH 069/282] DeprecatedFunctions sniff: correct some incorrect deprecated function names * Fix two incorrect functions * Use correct case for the function name in the array, the function name comparison is done in a case-insensitive manner anyway. --- WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php | 6 +++--- WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php index 1ad543f3..351db4f5 100644 --- a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php +++ b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php @@ -59,7 +59,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'get_the_category_by_ID()', 'version' => '0.71', ), - 'the_category_id' => array( + 'the_category_ID' => array( 'alt' => 'get_the_category()', 'version' => '0.71', ), @@ -535,7 +535,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'term_exists()', 'version' => '3.0.0', ), - 'nc' => array( + '_nc' => array( 'alt' => 'nx()', 'version' => '3.0.0', ), @@ -611,7 +611,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'WP_Admin_Bar', 'version' => '3.2.0', ), - 'wp_dashboard_quick_press' => array( + 'wp_dashboard_quick_press_output' => array( 'alt' => '', 'version' => '3.2.0', ), diff --git a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc index e7ddb027..e7037a24 100644 --- a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc +++ b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc @@ -6,7 +6,7 @@ */ /* ============ WP 0.71 ============ */ the_category_head(); -the_category_id(); +the_category_ID(); /* ============ WP 1.2 ============ */ permalink_link(); /* ============ WP 1.5 ============ */ @@ -131,7 +131,7 @@ get_usermeta(); get_usernumposts(); is_taxonomy(); is_term(); -nc(); +_nc(); remove_option_update_handler(); translate_with_context(); update_usermeta(); @@ -151,7 +151,7 @@ is_plugin_page(); update_category_cache(); /* ============ WP 3.2 ============ */ favorite_actions(); -wp_dashboard_quick_press(); +wp_dashboard_quick_press_output(); wp_preload_dialogs(); wp_print_editor_js(); wp_quicktags(); From 233a2f3618771d3abc4468dc0a5e77fa9b2bc3ee Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 22 Jun 2017 22:11:14 +0200 Subject: [PATCH 070/282] DeprecatedFunctions sniff: fix alternative functions * Correct incorrect alternative functions * Adjust incomplete alternatives * Add missing alternative functions * Fix punctuation/spacing of alternative functions text strings to be in line with the punctuation used in Core. * Annotate verified differences with the WP code scanner in alternatives --- .../Sniffs/WP/DeprecatedFunctionsSniff.php | 60 ++++++++++--------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php index 351db4f5..e5420af6 100644 --- a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php +++ b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php @@ -72,6 +72,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun // WP 1.5.0. 'start_wp' => array( + // Verified correct alternative. 'alt' => 'the Loop', 'version' => '1.5.0', ), @@ -206,7 +207,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '2.1.0', ), 'tinymce_include' => array( - 'alt' => 'wp_tiny_mce()', + 'alt' => 'wp_editor()', 'version' => '2.1.0', ), 'wp_get_links' => array( @@ -238,7 +239,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun // WP 2.3.0. 'permalink_single_rss' => array( - 'alt' => 'permalink_rss()', + 'alt' => 'the_permalink_rss()', 'version' => '2.3.0', ), @@ -320,7 +321,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun // WP 2.8.0. '__ngettext' => array( - 'alt' => '_n_noop()', + 'alt' => '_n()', 'version' => '2.8.0', ), '__ngettext_noop' => array( @@ -348,7 +349,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '2.8.0', ), 'get_the_author_description' => array( - 'alt' => 'get_the_author_meta( \'description\' )', + 'alt' => 'get_the_author_meta(\'description\')', 'version' => '2.8.0', ), 'get_the_author_email' => array( @@ -372,7 +373,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '2.8.0', ), 'get_the_author_login' => array( - 'alt' => 'the_author_meta(\'login\')', + 'alt' => 'get_the_author_meta(\'login\')', 'version' => '2.8.0', ), 'get_the_author_msn' => array( @@ -404,7 +405,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '2.8.0', ), 'sanitize_url' => array( - 'alt' => 'esc_url()', + 'alt' => 'esc_url_raw()', 'version' => '2.8.0', ), 'the_author_aim' => array( @@ -536,7 +537,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '3.0.0', ), '_nc' => array( - 'alt' => 'nx()', + 'alt' => '_nx()', 'version' => '3.0.0', ), 'remove_option_update_handler' => array( @@ -566,19 +567,19 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun // WP 3.1.0. 'get_author_user_ids' => array( - 'alt' => '', + 'alt' => 'get_users()', 'version' => '3.1.0', ), 'get_editable_authors' => array( - 'alt' => '', + 'alt' => 'get_users()', 'version' => '3.1.0', ), 'get_editable_user_ids' => array( - 'alt' => '', + 'alt' => 'get_users()', 'version' => '3.1.0', ), 'get_nonauthor_user_ids' => array( - 'alt' => '', + 'alt' => 'get_users()', 'version' => '3.1.0', ), 'get_others_drafts' => array( @@ -598,7 +599,8 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '3.1.0', ), 'is_plugin_page' => array( - 'alt' => '$plugin_page and/or get_plugin_page_hookname() hooks', + // Verified correct alternative. + 'alt' => 'global $plugin_page and/or get_plugin_page_hookname() hooks', 'version' => '3.1.0', ), 'update_category_cache' => array( @@ -612,7 +614,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '3.2.0', ), 'wp_dashboard_quick_press_output' => array( - 'alt' => '', + 'alt' => 'wp_dashboard_quick_press()', 'version' => '3.2.0', ), 'wp_preload_dialogs' => array( @@ -674,7 +676,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '3.3.0', ), 'is_blog_user' => array( - 'alt' => 'is_member_of_blog()', + 'alt' => 'is_user_member_of_blog()', 'version' => '3.3.0', ), 'media_upload_audio' => array( @@ -722,19 +724,19 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '3.3.0', ), 'type_url_form_audio' => array( - 'alt' => 'wp_media_insert_url_form( \'audio\' )', + 'alt' => 'wp_media_insert_url_form(\'audio\')', 'version' => '3.3.0', ), 'type_url_form_file' => array( - 'alt' => 'wp_media_insert_url_form( \'file\' )', + 'alt' => 'wp_media_insert_url_form(\'file\')', 'version' => '3.3.0', ), 'type_url_form_image' => array( - 'alt' => 'wp_media_insert_url_form( \'image\' )', + 'alt' => 'wp_media_insert_url_form(\'image\')', 'version' => '3.3.0', ), 'type_url_form_video' => array( - 'alt' => 'wp_media_insert_url_form( \'video\' )', + 'alt' => 'wp_media_insert_url_form(\'video\')', 'version' => '3.3.0', ), 'wp_admin_bar_dashboard_view_site_menu' => array( @@ -776,7 +778,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '3.4.0', ), 'get_theme' => array( - 'alt' => 'wp_get_theme()', + 'alt' => 'wp_get_theme( $stylesheet )', 'version' => '3.4.0', ), 'get_theme_data' => array( @@ -828,7 +830,7 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '3.5.0', ), 'get_default_page_to_edit' => array( - 'alt' => 'get_default_post_to_edit()', + 'alt' => 'get_default_post_to_edit( \'page\' )', 'version' => '3.5.0', ), 'get_post_to_edit' => array( @@ -888,15 +890,15 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '3.7.0', ), 'wp_update_core' => array( - 'alt' => 'new Core_Upgrader()', + 'alt' => 'new Core_Upgrader();', 'version' => '3.7.0', ), 'wp_update_plugin' => array( - 'alt' => 'new Plugin_Upgrader()', + 'alt' => 'new Plugin_Upgrader();', 'version' => '3.7.0', ), 'wp_update_theme' => array( - 'alt' => 'new Theme_Upgrader()', + 'alt' => 'new Theme_Upgrader();', 'version' => '3.7.0', ), @@ -1006,19 +1008,19 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun // WP 4.2.0. 'prepreview_added_sidebars_widgets' => array( - 'alt' => 'customize_dynamic_setting_args()', + 'alt' => 'the \'customize_dynamic_setting_args\' filter', 'version' => '4.2.0', ), 'prepreview_added_widget_instance' => array( - 'alt' => 'customize_dynamic_setting_args()', + 'alt' => 'the \'customize_dynamic_setting_args\' filter', 'version' => '4.2.0', ), 'remove_prepreview_filters' => array( - 'alt' => 'customize_dynamic_setting_args()', + 'alt' => 'the \'customize_dynamic_setting_args\' filter', 'version' => '4.2.0', ), 'setup_widget_addition_previews' => array( - 'alt' => 'customize_dynamic_setting_args()', + 'alt' => 'the \'customize_dynamic_setting_args\' filter', 'version' => '4.2.0', ), @@ -1048,11 +1050,11 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'version' => '4.3.0', ), 'wp_htmledit_pre' => array( - 'alt' => '', + 'alt' => 'format_for_editor()', 'version' => '4.3.0', ), 'wp_richedit_pre' => array( - 'alt' => '', + 'alt' => 'format_for_editor()', 'version' => '4.3.0', ), From eb8fa50913c8c6df11a4c61101ae6674b5ab17f8 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 22 Jun 2017 18:57:17 +0200 Subject: [PATCH 071/282] DeprecatedFunctions sniff: correct the version number for nine deprecated functions --- .../Sniffs/WP/DeprecatedFunctionsSniff.php | 72 +++++++++---------- .../Tests/WP/DeprecatedFunctionsUnitTest.inc | 18 ++--- .../Tests/WP/DeprecatedFunctionsUnitTest.php | 4 +- 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php index e5420af6..d8d8ac6c 100644 --- a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php +++ b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php @@ -470,6 +470,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => '_x()', 'version' => '2.9.0', ), + '_nc' => array( + 'alt' => '_nx()', + 'version' => '2.9.0', + ), 'make_url_footnote' => array( 'alt' => '', 'version' => '2.9.0', @@ -478,6 +482,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'the_content_feed()', 'version' => '2.9.0', ), + 'translate_with_context' => array( + 'alt' => '_x()', + 'version' => '2.9.0', + ), // WP 3.0.0. 'add_option_update_handler' => array( @@ -536,18 +544,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'term_exists()', 'version' => '3.0.0', ), - '_nc' => array( - 'alt' => '_nx()', - 'version' => '3.0.0', - ), 'remove_option_update_handler' => array( 'alt' => 'unregister_setting()', 'version' => '3.0.0', ), - 'translate_with_context' => array( - 'alt' => '_x()', - 'version' => '3.0.0', - ), 'update_usermeta' => array( 'alt' => 'update_user_meta()', 'version' => '3.0.0', @@ -617,44 +617,16 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'wp_dashboard_quick_press()', 'version' => '3.2.0', ), - 'wp_preload_dialogs' => array( - 'alt' => 'wp_editor()', - 'version' => '3.2.0', - ), - 'wp_print_editor_js' => array( - 'alt' => 'wp_editor()', - 'version' => '3.2.0', - ), - 'wp_quicktags' => array( - 'alt' => 'wp_editor()', - 'version' => '3.2.0', - ), 'wp_timezone_supported' => array( 'alt' => '', 'version' => '3.2.0', ), - 'wp_tiny_mce' => array( - 'alt' => 'wp_editor()', - 'version' => '3.2.0', - ), // WP 3.3.0. 'add_contextual_help' => array( 'alt' => 'get_current_screen()->add_help_tab()', 'version' => '3.3.0', ), - 'debug_fclose' => array( - 'alt' => 'error_log()', - 'version' => '3.3.0', - ), - 'debug_fopen' => array( - 'alt' => 'error_log()', - 'version' => '3.3.0', - ), - 'debug_fwrite' => array( - 'alt' => 'error_log()', - 'version' => '3.3.0', - ), 'get_boundary_post_rel_link' => array( 'alt' => '', 'version' => '3.3.0', @@ -743,6 +715,22 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => '', 'version' => '3.3.0', ), + 'wp_preload_dialogs' => array( + 'alt' => 'wp_editor()', + 'version' => '3.3.0', + ), + 'wp_print_editor_js' => array( + 'alt' => 'wp_editor()', + 'version' => '3.3.0', + ), + 'wp_quicktags' => array( + 'alt' => 'wp_editor()', + 'version' => '3.3.0', + ), + 'wp_tiny_mce' => array( + 'alt' => 'wp_editor()', + 'version' => '3.3.0', + ), // WP 3.4.0. 'add_custom_background' => array( @@ -765,6 +753,18 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'wp_get_theme()', 'version' => '3.4.0', ), + 'debug_fclose' => array( + 'alt' => 'error_log()', + 'version' => '3.4.0', + ), + 'debug_fopen' => array( + 'alt' => 'error_log()', + 'version' => '3.4.0', + ), + 'debug_fwrite' => array( + 'alt' => 'error_log()', + 'version' => '3.4.0', + ), 'get_allowed_themes' => array( 'alt' => 'wp_get_themes( array( \'allowed\' => true ) )', 'version' => '3.4.0', diff --git a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc index e7037a24..ce63342c 100644 --- a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc +++ b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc @@ -114,8 +114,10 @@ unregister_widget_control(); wp_specialchars(); /* ============ WP 2.9 ============ */ _c(); +_nc(); make_url_footnote(); the_content_rss(); +translate_with_context(); /* ============ WP 3.0 ============ */ add_option_update_handler(); automatic_feed_links(); @@ -131,9 +133,7 @@ get_usermeta(); get_usernumposts(); is_taxonomy(); is_term(); -_nc(); remove_option_update_handler(); -translate_with_context(); update_usermeta(); use_codepress(); wp_dropdown_cats(); @@ -152,16 +152,9 @@ update_category_cache(); /* ============ WP 3.2 ============ */ favorite_actions(); wp_dashboard_quick_press_output(); -wp_preload_dialogs(); -wp_print_editor_js(); -wp_quicktags(); wp_timezone_supported(); -wp_tiny_mce(); /* ============ WP 3.3 ============ */ add_contextual_help(); -debug_fclose(); -debug_fopen(); -debug_fwrite(); get_boundary_post_rel_link(); get_index_rel_link(); get_parent_post_rel_link(); @@ -184,12 +177,19 @@ type_url_form_file(); type_url_form_image(); type_url_form_video(); wp_admin_bar_dashboard_view_site_menu(); +wp_preload_dialogs(); +wp_print_editor_js(); +wp_quicktags(); +wp_tiny_mce(); /* ============ WP 3.4 ============ */ add_custom_background(); add_custom_image_header(); clean_page_cache(); clean_pre(); current_theme_info(); +debug_fclose(); +debug_fopen(); +debug_fwrite(); get_allowed_themes(); get_broken_themes(); get_current_theme(); diff --git a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php index ff9245a5..6a821d8a 100644 --- a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php +++ b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php @@ -29,8 +29,8 @@ public function getErrorList() { unset( $errors[10], $errors[12], $errors[14], $errors[16], $errors[28], $errors[54], $errors[56], $errors[58], $errors[71], $errors[74], - $errors[78], $errors[115], $errors[119], $errors[141], $errors[152], - $errors[160], $errors[187], $errors[203], $errors[217], $errors[221], + $errors[78], $errors[115], $errors[121], $errors[141], $errors[152], + $errors[156], $errors[184], $errors[203], $errors[217], $errors[221], $errors[228], $errors[240], $errors[247], $errors[251], $errors[256], $errors[261], $errors[269] ); From 319541c48177b66d5a1e8900d1f1f018fb9d648d Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 22 Jun 2017 18:58:43 +0200 Subject: [PATCH 072/282] DeprecatedFunctions sniff: Annotate methods listed in this sniff ... to be moved to their own sniff if & when that sniff gets created. --- WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php | 8 ++++++++ .../Tests/WP/DeprecatedFunctionsUnitTest.inc | 16 ++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php index d8d8ac6c..a82c1b77 100644 --- a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php +++ b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php @@ -989,36 +989,44 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun ), // WP 4.1.0. + // This is a method from the WP_Customize_Image_Control class. See #731. 'add_tab' => array( 'alt' => '', 'version' => '4.1.0', ), + // This is a method from the WP_Customize_Image_Control class. See #731. 'prepare_control' => array( 'alt' => '', 'version' => '4.1.0', ), + // This is a method from the WP_Customize_Image_Control class. See #731. 'print_tab_image' => array( 'alt' => '', 'version' => '4.1.0', ), + // This is a method from the WP_Customize_Image_Control class. See #731. 'remove_tab' => array( 'alt' => '', 'version' => '4.1.0', ), // WP 4.2.0. + // This is a method from the WP_Customize_Widgets class. See #731. 'prepreview_added_sidebars_widgets' => array( 'alt' => 'the \'customize_dynamic_setting_args\' filter', 'version' => '4.2.0', ), + // This is a method from the WP_Customize_Widgets class. See #731. 'prepreview_added_widget_instance' => array( 'alt' => 'the \'customize_dynamic_setting_args\' filter', 'version' => '4.2.0', ), + // This is a method from the WP_Customize_Widgets class. See #731. 'remove_prepreview_filters' => array( 'alt' => 'the \'customize_dynamic_setting_args\' filter', 'version' => '4.2.0', ), + // This is a method from the WP_Customize_Widgets class. See #731. 'setup_widget_addition_previews' => array( 'alt' => 'the \'customize_dynamic_setting_args\' filter', 'version' => '4.2.0', diff --git a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc index ce63342c..80d2823c 100644 --- a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc +++ b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc @@ -249,15 +249,15 @@ get_all_category_ids(); like_escape(); url_is_accessable_via_ssl(); /* ============ WP 4.1 ============ */ -add_tab(); -prepare_control(); -print_tab_image(); -remove_tab(); +add_tab(); // Issue #731 - method, not function. +prepare_control(); // Issue #731 - method, not function. +print_tab_image(); // Issue #731 - method, not function. +remove_tab(); // Issue #731 - method, not function. /* ============ WP 4.2 ============ */ -prepreview_added_sidebars_widgets(); -prepreview_added_widget_instance(); -remove_prepreview_filters(); -setup_widget_addition_previews(); +prepreview_added_sidebars_widgets(); // Issue #731 - method, not function. +prepreview_added_widget_instance(); // Issue #731 - method, not function. +remove_prepreview_filters(); // Issue #731 - method, not function. +setup_widget_addition_previews(); // Issue #731 - method, not function. /* ============ WP 4.3 ============ */ _preview_theme_stylesheet_filter(); _preview_theme_template_filter(); From a4f31f93285deef61d3a923112496407688d8d59 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 22 Jun 2017 19:38:58 +0200 Subject: [PATCH 073/282] DeprecatedFunctions sniff: add missing functions --- .../Sniffs/WP/DeprecatedFunctionsSniff.php | 140 ++++++++++++++++++ .../Tests/WP/DeprecatedFunctionsUnitTest.inc | 35 +++++ .../Tests/WP/DeprecatedFunctionsUnitTest.php | 18 +-- 3 files changed, 184 insertions(+), 9 deletions(-) diff --git a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php index a82c1b77..1604e175 100644 --- a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php +++ b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php @@ -120,6 +120,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'current_user_can()', 'version' => '2.0.0', ), + 'user_can_edit_post_date' => array( + 'alt' => 'current_user_can()', + 'version' => '2.0.0', + ), 'user_can_edit_user' => array( 'alt' => 'current_user_can()', 'version' => '2.0.0', @@ -280,6 +284,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => '', 'version' => '2.5.0', ), + 'wp_clearcookie' => array( + 'alt' => 'wp_clear_auth_cookie()', + 'version' => '2.5.0', + ), 'wp_get_cookie_login' => array( 'alt' => '', 'version' => '2.5.0', @@ -436,6 +444,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'the_author_meta(\'last_name\')', 'version' => '2.8.0', ), + 'the_author_login' => array( + 'alt' => 'the_author_meta(\'login\')', + 'version' => '2.8.0', + ), 'the_author_msn' => array( 'alt' => 'the_author_meta(\'msn\')', 'version' => '2.8.0', @@ -474,6 +486,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => '_nx()', 'version' => '2.9.0', ), + 'get_real_file_to_edit' => array( + 'alt' => '', + 'version' => '2.9.0', + ), 'make_url_footnote' => array( 'alt' => '', 'version' => '2.9.0', @@ -488,6 +504,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun ), // WP 3.0.0. + 'activate_sitewide_plugin' => array( + 'alt' => 'activate_plugin()', + 'version' => '3.0.0', + ), 'add_option_update_handler' => array( 'alt' => 'register_setting()', 'version' => '3.0.0', @@ -500,6 +520,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'esc_url()', 'version' => '3.0.0', ), + 'clear_global_post_cache' => array( + 'alt' => 'clean_post_cache()', + 'version' => '3.0.0', + ), 'codepress_footer_js' => array( 'alt' => '', 'version' => '3.0.0', @@ -508,6 +532,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => '', 'version' => '3.0.0', ), + 'deactivate_sitewide_plugin' => array( + 'alt' => 'deactivate_plugin()', + 'version' => '3.0.0', + ), 'delete_usermeta' => array( 'alt' => 'delete_user_meta()', 'version' => '3.0.0', @@ -520,14 +548,30 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => '', 'version' => '3.0.0', ), + 'generate_random_password' => array( + 'alt' => 'wp_generate_password()', + 'version' => '3.0.0', + ), 'get_alloptions' => array( 'alt' => 'wp_load_alloptions()', 'version' => '3.0.0', ), + 'get_blog_list' => array( + 'alt' => 'wp_get_sites()', + 'version' => '3.0.0', + ), + 'get_most_active_blogs' => array( + 'alt' => '', + 'version' => '3.0.0', + ), 'get_profile' => array( 'alt' => 'get_the_author_meta()', 'version' => '3.0.0', ), + 'get_user_details' => array( + 'alt' => 'get_user_by()', + 'version' => '3.0.0', + ), 'get_usermeta' => array( 'alt' => 'get_user_meta()', 'version' => '3.0.0', @@ -536,6 +580,18 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'count_user_posts()', 'version' => '3.0.0', ), + 'graceful_fail' => array( + 'alt' => 'wp_die()', + 'version' => '3.0.0', + ), + 'is_main_blog' => array( + 'alt' => 'is_main_site()', + 'version' => '3.0.0', + ), + 'is_site_admin' => array( + 'alt' => 'is_super_admin()', + 'version' => '3.0.0', + ), 'is_taxonomy' => array( 'alt' => 'taxonomy_exists()', 'version' => '3.0.0', @@ -544,10 +600,22 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'term_exists()', 'version' => '3.0.0', ), + 'is_wpmu_sitewide_plugin' => array( + 'alt' => 'is_network_only_plugin()', + 'version' => '3.0.0', + ), + 'mu_options' => array( + 'alt' => '', + 'version' => '3.0.0', + ), 'remove_option_update_handler' => array( 'alt' => 'unregister_setting()', 'version' => '3.0.0', ), + 'set_current_user' => array( + 'alt' => 'wp_set_current_user()', + 'version' => '3.0.0', + ), 'update_usermeta' => array( 'alt' => 'update_user_meta()', 'version' => '3.0.0', @@ -556,6 +624,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => '', 'version' => '3.0.0', ), + 'validate_email' => array( + 'alt' => 'is_email()', + 'version' => '3.0.0', + ), 'wp_dropdown_cats' => array( 'alt' => 'wp_dropdown_categories()', 'version' => '3.0.0', @@ -564,12 +636,24 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'wp_constrain_dimensions()', 'version' => '3.0.0', ), + 'wpmu_checkAvailableSpace' => array( + 'alt' => 'is_upload_space_available()', + 'version' => '3.0.0', + ), + 'wpmu_menu' => array( + 'alt' => '', + 'version' => '3.0.0', + ), // WP 3.1.0. 'get_author_user_ids' => array( 'alt' => 'get_users()', 'version' => '3.1.0', ), + 'get_dashboard_blog' => array( + 'alt' => '', + 'version' => '3.1.0', + ), 'get_editable_authors' => array( 'alt' => 'get_users()', 'version' => '3.1.0', @@ -598,6 +682,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'get_users()', 'version' => '3.1.0', ), + 'install_themes_feature_list' => array( + 'alt' => 'get_theme_feature_list()', + 'version' => '3.1.0', + ), 'is_plugin_page' => array( // Verified correct alternative. 'alt' => 'global $plugin_page and/or get_plugin_page_hookname() hooks', @@ -639,10 +727,18 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => '', 'version' => '3.3.0', ), + 'get_user_by_email' => array( + 'alt' => 'get_user_by(\'email\')', + 'version' => '3.3.0', + ), 'get_user_metavalues' => array( 'alt' => '', 'version' => '3.3.0', ), + 'get_userdatabylogin' => array( + 'alt' => 'get_user_by(\'login\')', + 'version' => '3.3.0', + ), 'index_rel_link' => array( 'alt' => '', 'version' => '3.3.0', @@ -731,6 +827,14 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'wp_editor()', 'version' => '3.3.0', ), + 'wpmu_admin_do_redirect' => array( + 'alt' => '', + 'version' => '3.3.0', + ), + 'wpmu_admin_redirect_add_updated_param' => array( + 'alt' => '', + 'version' => '3.3.0', + ), // WP 3.4.0. 'add_custom_background' => array( @@ -765,6 +869,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'error_log()', 'version' => '3.4.0', ), + 'display_theme' => array( + 'alt' => '', + 'version' => '3.4.0', + ), 'get_allowed_themes' => array( 'alt' => 'wp_get_themes( array( \'allowed\' => true ) )', 'version' => '3.4.0', @@ -777,6 +885,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'wp_get_theme()', 'version' => '3.4.0', ), + 'get_site_allowed_themes' => array( + 'alt' => 'WP_Theme::get_allowed_on_network()', + 'version' => '3.4.0', + ), 'get_theme' => array( 'alt' => 'wp_get_theme( $stylesheet )', 'version' => '3.4.0', @@ -789,6 +901,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'wp_get_themes()', 'version' => '3.4.0', ), + 'logIO' => array( + 'alt' => 'error_log()', + 'version' => '3.4.0', + ), 'remove_custom_background' => array( 'alt' => 'remove_theme_support( \'custom-background\' )', 'version' => '3.4.0', @@ -801,6 +917,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'update_post_cache()', 'version' => '3.4.0', ), + 'wpmu_get_blog_allowedthemes' => array( + 'alt' => 'WP_Theme::get_allowed_on_site()', + 'version' => '3.4.0', + ), // WP 3.4.1. 'wp_explain_nonce' => array( @@ -809,6 +929,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun ), // WP 3.5.0. + '_flip_image_resource' => array( + 'alt' => 'WP_Image_Editor::flip()', + 'version' => '3.5.0', + ), '_get_post_ancestors' => array( 'alt' => '', 'version' => '3.5.0', @@ -821,6 +945,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => '', 'version' => '3.5.0', ), + '_rotate_image_resource' => array( + 'alt' => 'WP_Image_Editor::rotate()', + 'version' => '3.5.0', + ), '_save_post_hook' => array( 'alt' => '', 'version' => '3.5.0', @@ -837,6 +965,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'get_post()', 'version' => '3.5.0', ), + 'get_udims' => array( + 'alt' => 'wp_constrain_dimensions()', + 'version' => '3.5.0', + ), 'image_resize' => array( 'alt' => 'wp_get_image_editor()', 'version' => '3.5.0', @@ -849,6 +981,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun 'alt' => 'wp_authenticate()', 'version' => '3.5.0', ), + 'wp_cache_reset' => array( + 'alt' => '', + 'version' => '3.5.0', + ), 'wp_create_thumbnail' => array( 'alt' => 'image_resize()', 'version' => '3.5.0', @@ -1124,6 +1260,10 @@ class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFun ), // WP 4.6.0. + 'post_form_autocomplete_off' => array( + 'alt' => '', + 'version' => '4.6.0', + ), 'wp_embed_handler_googlevideo' => array( 'alt' => '', 'version' => '4.6.0', diff --git a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc index 80d2823c..8cdfda91 100644 --- a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc +++ b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.inc @@ -23,6 +23,7 @@ user_can_delete_post(); user_can_delete_post_comments(); user_can_edit_post(); user_can_edit_post_comments(); +user_can_edit_post_date(); user_can_edit_user(); user_can_set_post_date(); /* ============ WP 2.1 ============ */ @@ -65,6 +66,7 @@ get_author_rss_link(); get_category_rss_link(); get_the_attachment_link(); gzip_compression(); +wp_clearcookie(); wp_get_cookie_login(); wp_login(); wp_setcookie(); @@ -105,6 +107,7 @@ the_author_firstname(); the_author_icq(); the_author_ID(); the_author_lastname(); +the_author_login(); the_author_msn(); the_author_nickname(); the_author_url(); @@ -115,31 +118,49 @@ wp_specialchars(); /* ============ WP 2.9 ============ */ _c(); _nc(); +get_real_file_to_edit(); make_url_footnote(); the_content_rss(); translate_with_context(); /* ============ WP 3.0 ============ */ +activate_sitewide_plugin(); add_option_update_handler(); automatic_feed_links(); clean_url(); +clear_global_post_cache(); codepress_footer_js(); codepress_get_lang(); +deactivate_sitewide_plugin(); delete_usermeta(); funky_javascript_callback(); funky_javascript_fix(); +generate_random_password(); get_alloptions(); +get_blog_list(); +get_most_active_blogs(); get_profile(); +get_user_details(); get_usermeta(); get_usernumposts(); +graceful_fail(); +is_main_blog(); +is_site_admin(); is_taxonomy(); is_term(); +is_wpmu_sitewide_plugin(); +mu_options(); remove_option_update_handler(); +set_current_user(); update_usermeta(); use_codepress(); +validate_email(); wp_dropdown_cats(); wp_shrink_dimensions(); +wpmu_checkAvailableSpace(); +wpmu_menu(); /* ============ WP 3.1 ============ */ get_author_user_ids(); +get_dashboard_blog(); get_editable_authors(); get_editable_user_ids(); get_nonauthor_user_ids(); @@ -147,6 +168,7 @@ get_others_drafts(); get_others_pending(); get_others_unpublished_posts(); get_users_of_blog(); +install_themes_feature_list(); is_plugin_page(); update_category_cache(); /* ============ WP 3.2 ============ */ @@ -158,7 +180,9 @@ add_contextual_help(); get_boundary_post_rel_link(); get_index_rel_link(); get_parent_post_rel_link(); +get_user_by_email(); get_user_metavalues(); +get_userdatabylogin(); index_rel_link(); is_blog_user(); media_upload_audio(); @@ -181,6 +205,8 @@ wp_preload_dialogs(); wp_print_editor_js(); wp_quicktags(); wp_tiny_mce(); +wpmu_admin_do_redirect(); +wpmu_admin_redirect_add_updated_param(); /* ============ WP 3.4 ============ */ add_custom_background(); add_custom_image_header(); @@ -190,27 +216,35 @@ current_theme_info(); debug_fclose(); debug_fopen(); debug_fwrite(); +display_theme(); get_allowed_themes(); get_broken_themes(); get_current_theme(); +get_site_allowed_themes(); get_theme(); get_theme_data(); get_themes(); +logIO(); remove_custom_background(); remove_custom_image_header(); update_page_cache(); wp_explain_nonce(); +wpmu_get_blog_allowedthemes(); /* ============ WP 3.5 ============ */ +_flip_image_resource(); _get_post_ancestors(); _insert_into_post_button(); _media_button(); +_rotate_image_resource(); _save_post_hook(); image_resize(); gd_edit_image_support(); get_default_page_to_edit(); get_post_to_edit(); +get_udims(); sticky_class(); user_pass_ok(); +wp_cache_reset(); wp_create_thumbnail(); wp_get_single_post(); wp_load_image(); @@ -286,6 +320,7 @@ get_currentuserinfo(); is_comments_popup(); popuplinks(); /* ============ WP 4.6 ============ */ +post_form_autocomplete_off(); wp_embed_handler_googlevideo(); wp_get_sites(); /* ============ WP 4.7 ============ */ diff --git a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php index 6a821d8a..86f70093 100644 --- a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php +++ b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php @@ -23,16 +23,16 @@ class WordPress_Tests_WP_DeprecatedFunctionsUnitTest extends AbstractSniffUnitTe */ public function getErrorList() { - $errors = array_fill( 8, 268, 1 ); + $errors = array_fill( 8, 302, 1 ); // Unset the lines related to version comments. unset( - $errors[10], $errors[12], $errors[14], $errors[16], $errors[28], - $errors[54], $errors[56], $errors[58], $errors[71], $errors[74], - $errors[78], $errors[115], $errors[121], $errors[141], $errors[152], - $errors[156], $errors[184], $errors[203], $errors[217], $errors[221], - $errors[228], $errors[240], $errors[247], $errors[251], $errors[256], - $errors[261], $errors[269] + $errors[10], $errors[12], $errors[14], $errors[16], $errors[29], + $errors[55], $errors[57], $errors[59], $errors[73], $errors[76], + $errors[80], $errors[118], $errors[125], $errors[161], $errors[174], + $errors[178], $errors[210], $errors[233], $errors[251], $errors[255], + $errors[262], $errors[274], $errors[281], $errors[285], $errors[290], + $errors[295], $errors[303] ); return $errors; @@ -45,11 +45,11 @@ public function getErrorList() { */ public function getWarningList() { - $warnings = array_fill( 281, 19, 1 ); + $warnings = array_fill( 315, 20, 1 ); // Unset the lines related to version comments. unset( - $warnings[288], $warnings[291], $warnings[298] + $warnings[322], $warnings[326], $warnings[333] ); return $warnings; From ed5ed45da550b664d15846b9221035453dd37dc1 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 23 Jun 2017 22:09:18 +0200 Subject: [PATCH 074/282] DisallowInlineTabs sniff: make error text clearer Came across this error message in one of my own projects and realized that - unless you run PHPCS with the error codes showing -, the error message was not clear enough and could cause confusion about alignment (spaces) versus indentation (tabs). --- WordPress/Sniffs/WhiteSpace/DisallowInlineTabsSniff.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/Sniffs/WhiteSpace/DisallowInlineTabsSniff.php b/WordPress/Sniffs/WhiteSpace/DisallowInlineTabsSniff.php index b817d33e..7ca26d2c 100644 --- a/WordPress/Sniffs/WhiteSpace/DisallowInlineTabsSniff.php +++ b/WordPress/Sniffs/WhiteSpace/DisallowInlineTabsSniff.php @@ -79,7 +79,7 @@ public function process_token( $stackPtr ) { } $fix = $this->phpcsFile->addFixableError( - 'Spaces must be used for alignment; tabs are not allowed', + 'Spaces must be used for mid-line alignment; tabs are not allowed', $i, 'NonIndentTabsUsed' ); From 1fce8531e42b695e9de3aa3ca6a52d9eebd7d164 Mon Sep 17 00:00:00 2001 From: Gary Jones Date: Sat, 24 Jun 2017 09:04:43 +0100 Subject: [PATCH 075/282] Don't fix capitalisation for "wordpress.pot" Fixes #999 --- WordPress/Sniffs/WP/CapitalPDangitSniff.php | 2 +- WordPress/Tests/WP/CapitalPDangitUnitTest.inc | 3 +++ WordPress/Tests/WP/CapitalPDangitUnitTest.inc.fixed | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/WordPress/Sniffs/WP/CapitalPDangitSniff.php b/WordPress/Sniffs/WP/CapitalPDangitSniff.php index 9f03b567..b80964d9 100644 --- a/WordPress/Sniffs/WP/CapitalPDangitSniff.php +++ b/WordPress/Sniffs/WP/CapitalPDangitSniff.php @@ -36,7 +36,7 @@ class WordPress_Sniffs_WP_CapitalPDangitSniff extends WordPress_Sniff { * * @var string */ - const WP_REGEX = '#(?\'"()]*?\.(?:php|js|css|png|j[e]?pg|gif))#i'; + const WP_REGEX = '#(?\'"()]*?\.(?:php|js|css|png|j[e]?pg|gif|pot))#i'; /** * Regex to match a large number or spelling variations of WordPress in class names. diff --git a/WordPress/Tests/WP/CapitalPDangitUnitTest.inc b/WordPress/Tests/WP/CapitalPDangitUnitTest.inc index 91d64af8..821530a6 100644 --- a/WordPress/Tests/WP/CapitalPDangitUnitTest.inc +++ b/WordPress/Tests/WP/CapitalPDangitUnitTest.inc @@ -171,3 +171,6 @@ echo 'This is an explanation about wordpress.'; // WPCS: spelling ok. */ ?>

      The first two should be ignored for the purpose of replacing, this wordpress however should be fixed and this wordpress too.

      + + +wordpress.pot diff --git a/WordPress/Tests/WP/CapitalPDangitUnitTest.inc.fixed b/WordPress/Tests/WP/CapitalPDangitUnitTest.inc.fixed index 16b5bcca..a7d59e91 100644 --- a/WordPress/Tests/WP/CapitalPDangitUnitTest.inc.fixed +++ b/WordPress/Tests/WP/CapitalPDangitUnitTest.inc.fixed @@ -171,3 +171,6 @@ echo 'This is an explanation about wordpress.'; // WPCS: spelling ok. */ ?>

      The first two should be ignored for the purpose of replacing, this WordPress however should be fixed and this WordPress too.

      + + +wordpress.pot From 0a996cb43cadc25e56e486b8b48996ac50d276cd Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 24 Jun 2017 16:37:28 +0200 Subject: [PATCH 076/282] ArrayIndentation sniff: Fix disappearing close brace when close brace not on its own line For multi-line array declarations, the close brace of the array is supposed to be on its own line + aligned with the line containing the array keyword. The `ArrayDeclaration` sniff will move the close brace to its own line. The `ArrayIndentation` sniff is only intended to fix the close brace indentation. The `ArrayIndentation` sniff was until now - incorrectly - presuming the close brace would already be on its own line with only whitespace before it. While the array *item* indentation part of the sniff did not suffer from this issue, I've build in a little extra check in that part just to make sure. --- .../Sniffs/Arrays/ArrayIndentationSniff.php | 37 +++++++++++++++---- .../Tests/Arrays/ArrayIndentationUnitTest.inc | 7 ++++ .../Arrays/ArrayIndentationUnitTest.inc.fixed | 7 ++++ .../Tests/Arrays/ArrayIndentationUnitTest.php | 2 + 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php index 141336f0..d05d2604 100644 --- a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php @@ -119,13 +119,31 @@ public function process_token( $stackPtr ) { $found, ); - $fix = $this->phpcsFile->addFixableError( $error, $closer, 'CloseBraceNotAligned', $data ); - if ( true === $fix ) { - if ( 0 === $found ) { - $this->phpcsFile->fixer->addContent( ( $closer - 1 ), $indentation ); - } else { - $this->phpcsFile->fixer->replaceToken( ( $closer - 1 ), $indentation ); + /** + * Report & fix the issue if the close brace is on its own line with + * nothing or only indentation whitespace before it. + */ + if ( 0 === $found + || ( T_WHITESPACE === $this->tokens[ ( $closer - 1 ) ]['code'] + && 1 === $this->tokens[ ( $closer - 1 ) ]['column'] ) + ) { + + $fix = $this->phpcsFile->addFixableError( $error, $closer, 'CloseBraceNotAligned', $data ); + if ( true === $fix ) { + if ( 0 === $found ) { + $this->phpcsFile->fixer->addContentBefore( $closer, $indentation ); + } else { + $this->phpcsFile->fixer->replaceToken( ( $closer - 1 ), $indentation ); + } } + } else { + /* + * Otherwise, only report the error, don't try and fix it (yet). + * + * It will get corrected in a future loop of the fixer once the closer + * has been moved to its own line by the `ArrayDeclaration` sniff. + */ + $this->phpcsFile->addError( $error, $closer, 'CloseBraceNotAligned', $data ); } } @@ -149,7 +167,10 @@ public function process_token( $stackPtr ) { // Bow out from reporting and fixing mixed multi-line/single-line arrays. // That is handled by the ArrayDeclarationSniff. - if ( $this->tokens[ $first_content ]['line'] === $this->tokens[ $end_of_last_item ]['line'] ) { + if ( $this->tokens[ $first_content ]['line'] === $this->tokens[ $end_of_last_item ]['line'] + || ( 1 !== $this->tokens[ $first_content ]['column'] + && T_WHITESPACE !== $this->tokens[ ( $first_content - 1 ) ]['code'] ) + ) { return $closer; } @@ -176,7 +197,7 @@ public function process_token( $stackPtr ) { $fix = $this->phpcsFile->addFixableError( $error, $first_content, 'ItemNotAligned', $data ); if ( true === $fix ) { if ( 0 === $found ) { - $this->phpcsFile->fixer->addContent( ( $first_content - 1 ), $expected_indent ); + $this->phpcsFile->fixer->addContentBefore( $first_content, $expected_indent ); } else { $this->phpcsFile->fixer->replaceToken( ( $first_content - 1 ), $expected_indent ); } diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc index b0c4bf6e..fd0e7a4c 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc @@ -79,3 +79,10 @@ $mixed_2 = array( ), 'something', 'else', ); + +// Issue 998: don't fix the indentation for the closer if it's not on its own line. +$a = array( + 'foo' => bar(1, 29)); + +$a = array( + 'foo' => bar(1, 29) ); diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc.fixed b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc.fixed index a85ad615..fd80dce3 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc.fixed +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.inc.fixed @@ -79,3 +79,10 @@ $mixed_2 = array( ), 'something', 'else', ); + +// Issue 998: don't fix the indentation for the closer if it's not on its own line. +$a = array( + 'foo' => bar(1, 29)); + +$a = array( + 'foo' => bar(1, 29) ); diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php index 67f8abe9..952197a4 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php @@ -47,6 +47,8 @@ public function getErrorList() { 61 => 1, 66 => 1, 80 => 1, + 85 => 1, + 88 => 1, ); } From af0b816e7dae580356fcc7b56a35bda86039ce49 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 24 Jun 2017 17:37:06 +0200 Subject: [PATCH 077/282] WordPress_Sniff: Add new `find_array_open_closer()` utility method. --- WordPress/Sniff.php | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index 390f9c6e..e3746dc5 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -2020,6 +2020,45 @@ public function get_function_call_parameter( $stackPtr, $param_offset ) { return $parameters[ $param_offset ]; } + /** + * Find the array opener & closer based on a T_ARRAY or T_OPEN_SHORT_ARRAY token. + * + * @param int $stackPtr The stack pointer to the array token. + * + * @return array|bool Array with two keys `opener`, `closer` or false if + * either or these could not be determined. + */ + protected function find_array_open_close( $stackPtr ) { + /* + * Determine the array opener & closer. + */ + if ( T_ARRAY === $this->tokens[ $stackPtr ]['code'] ) { + if ( isset( $this->tokens[ $stackPtr ]['parenthesis_opener'] ) ) { + $opener = $this->tokens[ $stackPtr ]['parenthesis_opener']; + + if ( isset( $this->tokens[ $opener ]['parenthesis_closer'] ) ) { + $closer = $this->tokens[ $opener ]['parenthesis_closer']; + } + } + } else { + // Short array syntax. + $opener = $stackPtr; + + if ( isset( $this->tokens[ $stackPtr ]['bracket_closer'] ) ) { + $closer = $this->tokens[ $stackPtr ]['bracket_closer']; + } + } + + if ( isset( $opener, $closer ) ) { + return array( + 'opener' => $opener, + 'closer' => $closer, + ); + } + + return false; + } + /** * Determine the namespace name an arbitrary token lives in. * From 314283a22ae6b501ddca17277f33468a4c3c2ae1 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 24 Jun 2017 17:37:47 +0200 Subject: [PATCH 078/282] ArrayIndentation sniff: Implement use of the new `find_array_open_close`()` utility method --- .../Sniffs/Arrays/ArrayIndentationSniff.php | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php index 141336f0..e7f0377b 100644 --- a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php @@ -59,26 +59,15 @@ public function process_token( $stackPtr ) { /* * Determine the array opener & closer. */ - if ( T_ARRAY === $this->tokens[ $stackPtr ]['code'] ) { - if ( ! isset( $this->tokens[ $stackPtr ]['parenthesis_opener'] ) ) { - return; // Live coding. - } - $opener = $this->tokens[ $stackPtr ]['parenthesis_opener']; - - if ( ! isset( $this->tokens[ $opener ]['parenthesis_closer'] ) ) { - return; // Live coding. - } - $closer = $this->tokens[ $opener ]['parenthesis_closer']; - } else { - // Short array syntax. - $opener = $stackPtr; - - if ( ! isset( $this->tokens[ $stackPtr ]['bracket_closer'] ) ) { - return; // Live coding. - } - $closer = $this->tokens[ $stackPtr ]['bracket_closer']; + $array_open_close = $this->find_array_open_close( $stackPtr ); + if ( false === $array_open_close ) { + // Array open/close could not be determined. + return; } + $opener = $array_open_close['opener']; + $closer = $array_open_close['closer']; + if ( $this->tokens[ $opener ]['line'] === $this->tokens[ $closer ]['line'] ) { // Not interested in single line arrays. return; From ac40395bd77898fd6823b9c2e04409ab7e7af609 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 24 Jun 2017 18:02:40 +0200 Subject: [PATCH 079/282] ArrayDeclarationSpacing sniff: Decouple the sniff from the upstream sniff This sniff was coupled to the upstream `Squiz_Sniffs_Arrays_ArrayDeclarationSniff` sniff to benefit from the process logic which routed the processing to the single-line/multi-line methods. However, with the addition of the `get_function_call_parameters()` utility method which handles splitting an array into individual array items + the addition of the new `find_array_open_close()` utility method to the `WordPress_Sniff`, we don't need the upstream logic anymore and it makes more sense to decouple the sniff and let it extend the `WordPress_Sniff` instead. Includes leveraging the properties in the `WordPress_Sniff`. --- WordPress-Core/ruleset.xml | 8 +- .../Arrays/ArrayDeclarationSpacingSniff.php | 139 +++++++++--------- 2 files changed, 74 insertions(+), 73 deletions(-) diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index 04fe39dd..e8cd9b3c 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -51,13 +51,7 @@
      - - - - - - + diff --git a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php index 7890969c..a5b49e08 100644 --- a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php @@ -7,12 +7,14 @@ * @license https://opensource.org/licenses/MIT MIT */ -if ( ! class_exists( 'Squiz_Sniffs_Arrays_ArrayDeclarationSniff', true ) ) { - throw new PHP_CodeSniffer_Exception( 'Class Squiz_Sniffs_Arrays_ArrayDeclarationSniff not found' ); -} - /** - * Enforces WordPress array format, based upon Squiz code. + * Enforces WordPress array spacing format. + * + * WordPress specific checks which are not covered by the `WordPress.Arrays.ArrayDeclaration`/ + * `Squiz.Arrays.ArrayDeclaration` sniff. + * + * - Checks for one space after the array opener / before the array closer in single-line arrays. + * - Checks that associative arrays are multi-line. * * @link https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#indentation * @@ -22,88 +24,109 @@ * from the WordPress_Sniffs_Arrays_ArrayDeclaration sniff into * this sniff. * - Added sniffing & fixing for associative arrays. - * - * {@internal This sniff only extends the upstream sniff to get the benefit of the - * process logic which routes the processing to the single-line/multi-line methods. - * Other than that, the actual sniffing from the upstream sniff is disregarded. - * In other words: no real syncing with upstream necessary.}} - * - * Last synced with parent class October 5 2016 at commit ea32814346ecf29791de701b3fa464a9ca43f45b. - * @link https://github.com/squizlabs/PHP_CodeSniffer/blob/master/CodeSniffer/Standards/Squiz/Sniffs/Arrays/ArrayDeclarationSniff.php + * @since 0.12.0 Decoupled this sniff from the upstream sniff completely. + * This sniff now extends the `WordPress_Sniff` instead. */ -class WordPress_Sniffs_Arrays_ArrayDeclarationSpacingSniff extends Squiz_Sniffs_Arrays_ArrayDeclarationSniff { +class WordPress_Sniffs_Arrays_ArrayDeclarationSpacingSniff extends WordPress_Sniff { /** - * Process a single line array. + * Returns an array of tokens this test wants to listen for. * - * @since 0.5.0 - * @since 0.11.0 Moved from WordPress_Sniffs_Arrays_ArrayDeclaration to this sniff. + * @since 0.12.0 * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. - * @param int $arrayStart Position of the array opener in the token stack. - * @param int $arrayEnd Position of the array closer in the token stack. + * @return array + */ + public function register() { + return array( + T_ARRAY, + T_OPEN_SHORT_ARRAY, + ); + } + + /** + * Processes this test, when one of its tokens is encountered. + * + * @since 0.12.0 The actual checks contained in this method used to + * be in the `processSingleLineArray()` method. + * + * @param int $stackPtr The position of the current token in the stack. + * + * @return void */ - public function processSingleLineArray( PHP_CodeSniffer_File $phpcsFile, $stackPtr, $arrayStart, $arrayEnd ) { + public function process_token( $stackPtr ) { + + /* + * Determine the array opener & closer. + */ + $array_open_close = $this->find_array_open_close( $stackPtr ); + if ( false === $array_open_close ) { + // Array open/close could not be determined. + return; + } + + $opener = $array_open_close['opener']; + $closer = $array_open_close['closer']; // This array is empty, so the below checks aren't necessary. - if ( ( $arrayStart + 1 ) === $arrayEnd ) { + if ( ( $opener + 1 ) === $closer ) { return; } - $tokens = $phpcsFile->getTokens(); + // We're only interested in single-line arrays. + if ( $this->tokens[ $opener ]['line'] !== $this->tokens[ $closer ]['line'] ) { + return; + } // Check that there is a single space after the array opener. - if ( T_WHITESPACE !== $tokens[ ( $arrayStart + 1 ) ]['code'] ) { + if ( T_WHITESPACE !== $this->tokens[ ( $opener + 1 ) ]['code'] ) { $warning = 'Missing space after array opener.'; - $fix = $phpcsFile->addFixableError( $warning, $arrayStart, 'NoSpaceAfterArrayOpener' ); + $fix = $this->phpcsFile->addFixableError( $warning, $opener, 'NoSpaceAfterArrayOpener' ); if ( true === $fix ) { - $phpcsFile->fixer->addContent( $arrayStart, ' ' ); + $this->phpcsFile->fixer->addContent( $opener, ' ' ); } - } elseif ( ' ' !== $tokens[ ( $arrayStart + 1 ) ]['content'] ) { + } elseif ( ' ' !== $this->tokens[ ( $opener + 1 ) ]['content'] ) { - $fix = $phpcsFile->addFixableError( + $fix = $this->phpcsFile->addFixableError( 'Expected 1 space after array opener, found %s.', - $arrayStart, + $opener, 'SpaceAfterArrayOpener', - array( strlen( $tokens[ ( $arrayStart + 1 ) ]['content'] ) ) + array( strlen( $this->tokens[ ( $opener + 1 ) ]['content'] ) ) ); if ( true === $fix ) { - $phpcsFile->fixer->replaceToken( ( $arrayStart + 1 ), ' ' ); + $this->phpcsFile->fixer->replaceToken( ( $opener + 1 ), ' ' ); } } - if ( T_WHITESPACE !== $tokens[ ( $arrayEnd - 1 ) ]['code'] ) { + if ( T_WHITESPACE !== $this->tokens[ ( $closer - 1 ) ]['code'] ) { $warning = 'Missing space before array closer.'; - $fix = $phpcsFile->addFixableError( $warning, $arrayEnd, 'NoSpaceBeforeArrayCloser' ); + $fix = $this->phpcsFile->addFixableError( $warning, $closer, 'NoSpaceBeforeArrayCloser' ); if ( true === $fix ) { - $phpcsFile->fixer->addContentBefore( $arrayEnd, ' ' ); + $this->phpcsFile->fixer->addContentBefore( $closer, ' ' ); } - } elseif ( ' ' !== $tokens[ ( $arrayEnd - 1 ) ]['content'] ) { + } elseif ( ' ' !== $this->tokens[ ( $closer - 1 ) ]['content'] ) { - $fix = $phpcsFile->addFixableError( + $fix = $this->phpcsFile->addFixableError( 'Expected 1 space before array closer, found %s.', - $arrayEnd, + $closer, 'SpaceBeforeArrayCloser', - array( strlen( $tokens[ ( $arrayEnd - 1 ) ]['content'] ) ) + array( strlen( $this->tokens[ ( $closer - 1 ) ]['content'] ) ) ); if ( true === $fix ) { - $phpcsFile->fixer->replaceToken( ( $arrayEnd - 1 ), ' ' ); + $this->phpcsFile->fixer->replaceToken( ( $closer - 1 ), ' ' ); } } - $array_has_keys = $phpcsFile->findNext( T_DOUBLE_ARROW, $arrayStart, $arrayEnd ); + $array_has_keys = $this->phpcsFile->findNext( T_DOUBLE_ARROW, $opener, $closer ); if ( false !== $array_has_keys ) { - $fix = $phpcsFile->addFixableError( + $fix = $this->phpcsFile->addFixableError( 'When an array uses associative keys, each value should start on a new line.', - $arrayEnd, + $closer, 'AssociativeKeyFound' ); @@ -111,37 +134,21 @@ public function processSingleLineArray( PHP_CodeSniffer_File $phpcsFile, $stackP // Only deal with one nesting level per loop to have the best chance of getting the indentation right. static $current_loop = array(); - if ( ! isset( $current_loop[ $phpcsFile->fixer->loops ] ) ) { - $current_loop[ $phpcsFile->fixer->loops ] = array_fill( 0, $phpcsFile->numTokens, false ); + if ( ! isset( $current_loop[ $this->phpcsFile->fixer->loops ] ) ) { + $current_loop[ $this->phpcsFile->fixer->loops ] = array_fill( 0, $this->phpcsFile->numTokens, false ); } - if ( false === $current_loop[ $phpcsFile->fixer->loops ][ $arrayStart ] ) { - for ( $i = $arrayStart; $i <= $arrayEnd; $i++ ) { - $current_loop[ $phpcsFile->fixer->loops ][ $i ] = true; + if ( false === $current_loop[ $this->phpcsFile->fixer->loops ][ $opener ] ) { + for ( $i = $opener; $i <= $closer; $i++ ) { + $current_loop[ $this->phpcsFile->fixer->loops ][ $i ] = true; } - $this->fix_associative_array( $phpcsFile, $arrayStart, $arrayEnd ); + $this->fix_associative_array( $this->phpcsFile, $opener, $closer ); } } } } - /** - * (Don't) Process a multi-line array. - * - * {@internal Multi-line arrays are handled by the upstream sniff via the - * WordPress_Sniffs_Arrays_ArrayDeclaration sniff.}} - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. - * @param int $arrayStart Position of the array opener in the token stack. - * @param int $arrayEnd Position of the array closer in the token stack. - */ - public function processMultiLineArray( PHP_CodeSniffer_File $phpcsFile, $stackPtr, $arrayStart, $arrayEnd ) { - return; - } // End processMultiLineArray(). - /** * Create & apply a changeset for a single line array with associative keys. * From cc5f92d10d93648939154efe2f0c416b436f44d1 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 24 Jun 2017 19:58:58 +0200 Subject: [PATCH 080/282] ArrayDeclarationSpacing sniff: remove array indentation from the associative array fixer ... as that is handled by the `ArrayIndentation` sniff which was introduced in PR 941 --- .../Arrays/ArrayDeclarationSpacingSniff.php | 137 +++--------------- .../ArrayDeclarationSpacingUnitTest.inc.fixed | 51 +++---- 2 files changed, 44 insertions(+), 144 deletions(-) diff --git a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php index a5b49e08..3657f75f 100644 --- a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php @@ -131,128 +131,37 @@ public function process_token( $stackPtr ) { ); if ( true === $fix ) { - // Only deal with one nesting level per loop to have the best chance of getting the indentation right. - static $current_loop = array(); - if ( ! isset( $current_loop[ $this->phpcsFile->fixer->loops ] ) ) { - $current_loop[ $this->phpcsFile->fixer->loops ] = array_fill( 0, $this->phpcsFile->numTokens, false ); + $array_items = $this->get_function_call_parameters( $stackPtr ); + if ( empty( $array_items ) ) { + // Strange, no array items found. + return; } - if ( false === $current_loop[ $this->phpcsFile->fixer->loops ][ $opener ] ) { - for ( $i = $opener; $i <= $closer; $i++ ) { - $current_loop[ $this->phpcsFile->fixer->loops ][ $i ] = true; + $this->phpcsFile->fixer->beginChangeset(); + + foreach( $array_items as $item ) { + /* + * Add a line break before the first non-empty token in the array item. + * Prevents extraneous whitespace at the start of the line which could be + * interpreted as alignment whitespace. + */ + $first_non_empty = $this->phpcsFile->findNext( + PHP_CodeSniffer_Tokens::$emptyTokens, + $item['start'], + ( $item['end'] + 1 ), + true + ); + if ( false === $first_non_empty ) { + continue; } - $this->fix_associative_array( $this->phpcsFile, $opener, $closer ); + $this->phpcsFile->fixer->addNewlineBefore( $first_non_empty ); } - } - } - } - - /** - * Create & apply a changeset for a single line array with associative keys. - * - * @since 0.11.0 - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $arrayStart Position of the array opener in the token stack. - * @param int $arrayEnd Position of the array closer in the token stack. - * @return void - */ - protected function fix_associative_array( PHP_CodeSniffer_File $phpcsFile, $arrayStart, $arrayEnd ) { - - $tokens = $phpcsFile->getTokens(); - - // Determine the needed indentation. - $indentation = ''; - for ( $i = $arrayStart; $i >= 0; $i-- ) { - if ( $tokens[ $i ]['line'] === $tokens[ $arrayStart ]['line'] ) { - continue; - } - - if ( T_WHITESPACE === $tokens[ ( $i + 1 ) ]['code'] ) { - // If the tokenizer replaced tabs with spaces, use the original content. - $indentation = $tokens[ ( $i + 1 ) ]['content']; - if ( isset( $tokens[ ( $i + 1 ) ]['orig_content'] ) ) { - $indentation = $tokens[ ( $i + 1 ) ]['orig_content']; - } - } - break; - } - unset( $i ); - - $value_indentation = "\t" . $indentation; - - // Which nesting level is the one we are interested in ? - $nesting_count = 1; - if ( T_OPEN_SHORT_ARRAY === $tokens[ $arrayStart ]['code'] ) { - $nesting_count = 0; - } - if ( isset( $tokens[ $arrayStart ]['nested_parenthesis'] ) ) { - $nesting_count += count( $tokens[ $arrayStart ]['nested_parenthesis'] ); - } - - // Record the required changes. - $phpcsFile->fixer->beginChangeset(); - - $phpcsFile->fixer->addNewline( $arrayStart ); - if ( T_WHITESPACE === $tokens[ ( $arrayStart + 1 ) ]['code'] ) { - $phpcsFile->fixer->replaceToken( ( $arrayStart + 1 ), $value_indentation ); - } else { - $phpcsFile->fixer->addContentBefore( ( $arrayStart + 1 ), $value_indentation ); - } - - for ( $ptr = ( $arrayStart + 1 ); $ptr < $arrayEnd; $ptr++ ) { - $ptr = $phpcsFile->findNext( array( T_COMMA, T_OPEN_SHORT_ARRAY ), $ptr, $arrayEnd ); - - if ( false === $ptr ) { - break; - } - - // Ignore anything within short array definition brackets. - // Necessary as the nesting level in that case is still the same. - if ( 'T_OPEN_SHORT_ARRAY' === $tokens[ $ptr ]['type'] - && ( isset( $tokens[ $ptr ]['bracket_opener'] ) - && $tokens[ $ptr ]['bracket_opener'] === $ptr ) - && isset( $tokens[ $ptr ]['bracket_closer'] ) - ) { - $ptr = $tokens[ $ptr ]['bracket_closer']; - continue; - } - - // Ignore comma's at a lower nesting level. - if ( 'T_COMMA' === $tokens[ $ptr ]['type'] - && isset( $tokens[ $ptr ]['nested_parenthesis'] ) - && count( $tokens[ $ptr ]['nested_parenthesis'] ) !== $nesting_count - ) { - continue; - } - - $phpcsFile->fixer->addNewline( $ptr ); - if ( isset( $tokens[ ( $ptr + 1 ) ] ) ) { - if ( T_WHITESPACE === $tokens[ ( $ptr + 1 ) ]['code'] ) { - $phpcsFile->fixer->replaceToken( ( $ptr + 1 ), $value_indentation ); - } else { - $phpcsFile->fixer->addContentBefore( ( $ptr + 1 ), $value_indentation ); - } + $this->phpcsFile->fixer->endChangeset(); } } - - $token_before_end = $phpcsFile->findPrevious( PHP_CodeSniffer_Tokens::$emptyTokens, ( $arrayEnd - 1 ), $arrayStart, true, null, true ); - if ( 'T_COMMA' !== $tokens[ $token_before_end ]['type'] ) { - $phpcsFile->fixer->addContent( $token_before_end, ',' ); - - if ( T_WHITESPACE === $tokens[ ( $arrayEnd - 1 ) ]['code'] || "\n" === $phpcsFile->fixer->getTokenContent( ( $arrayEnd - 1 ) ) ) { - $phpcsFile->fixer->replaceToken( ( $arrayEnd - 1 ), "\n" . $indentation ); - } else { - $phpcsFile->fixer->addContentBefore( $arrayEnd, "\n" . $indentation ); - } - } elseif ( $value_indentation === $phpcsFile->fixer->getTokenContent( ( $arrayEnd - 1 ) ) ) { - $phpcsFile->fixer->replaceToken( ( $arrayEnd - 1 ), $indentation ); - } - - $phpcsFile->fixer->endChangeset(); - } // End fix_associative_array(). + } } // End class. diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed index 72d2c815..9c80c77f 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed @@ -8,47 +8,38 @@ $query_vars = array( 'food' ); // Bad, no spaces after opening and before closin $test = array( 1, 2 ); $bad = array( - 'key' => 'value', -); // Bad, each value of an associative array should start on a new line. +'key' => 'value' ); // Bad, each value of an associative array should start on a new line. // Test for fixing nested associative arrays. $bad = array( - array( - 'key1' => 'value1', - 'key2' => [ - 'sub1' => 1, - 'sub2' => 2, - ], - ), - $key3 => 'value3', - [ - 'value4', - 10 => 'value5', - ], -); // Bad. +array( +'key1' => 'value1', +'key2' => [ +'sub1' => 1, +'sub2' => 2] ), +$key3 => 'value3', +[ +'value4', +10 => 'value5', ] ); // Bad. // Test for fixing mixed single & multi-line nested associative arrays. $bad = array( array( - 'key1' => 'value1', - array( - 'sub1' => 1, - 'sub2' => 2, - ), - ), +'key1' => 'value1', +array( +'sub1' => 1, +'sub2' => 2,)), $key3 => 'value3', [ - 'value4', - 10 => 'value5', - ] +'value4', +10 => 'value5' ] ); // Bad. // Test for fixing associative arrays with multiple values & whitespace in front. // This needs to be the last test as the scope indent sniff will otherwise screw things up. $bad = array( - 'key1' => 'value1', - 'key2' => 'value2', - $key3 => 'value3', - 'value4', - 10 => 'value5', - ); // Bad. +'key1' => 'value1', +'key2' => 'value2', +$key3 => 'value3', +'value4', +10 => 'value5' ); // Bad. From 7781049e72def33050f6f00a1c5b1c0e349c35e8 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 24 Jun 2017 20:05:36 +0200 Subject: [PATCH 081/282] ArrayDeclarationSpacing sniff: associative to multi-line: sort out trailing whitespace Let's remove trailing whitespace before adding a new line to prevent issues with the `.fixed` file not matching because code editors and sometimes even git clients remove trailing whitespace from the lines in the `.fixed` file. --- WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php | 8 ++++++++ .../Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc | 6 ++++-- .../Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed | 8 ++++++-- .../Tests/Arrays/ArrayDeclarationSpacingUnitTest.php | 3 ++- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php index 3657f75f..bd56f088 100644 --- a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php @@ -156,6 +156,14 @@ public function process_token( $stackPtr ) { continue; } + if ( $item['start'] <= ( $first_non_empty - 1 ) + && T_WHITESPACE === $this->tokens[ ( $first_non_empty - 1 ) ]['code'] + ) { + // Remove whitespace which would otherwise becoming trailing + // (as it gives problems with the fixed file). + $this->phpcsFile->fixer->replaceToken( ( $first_non_empty - 1 ), '' ); + } + $this->phpcsFile->fixer->addNewlineBefore( $first_non_empty ); } diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc index 31689bfb..f10329d7 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc @@ -19,6 +19,8 @@ $bad = array( [ 'value4', 10 => 'value5' ] ); // Bad. -// Test for fixing associative arrays with multiple values & whitespace in front. -// This needs to be the last test as the scope indent sniff will otherwise screw things up. +// Test for fixing associative arrays with multiple values & line indented with whitespace. $bad = array( 'key1' => 'value1', 'key2' => 'value2', $key3 => 'value3', 'value4', 10 => 'value5' ); // Bad. + +// Test for fixing associative arrays with comments between values. +$bad = array( 'key1' => 'value1', /* comment */ 'key2' => 'value2' ); // Bad. diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed index 9c80c77f..ad9e8efb 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed @@ -35,11 +35,15 @@ array( 10 => 'value5' ] ); // Bad. -// Test for fixing associative arrays with multiple values & whitespace in front. -// This needs to be the last test as the scope indent sniff will otherwise screw things up. +// Test for fixing associative arrays with multiple values & line indented with whitespace. $bad = array( 'key1' => 'value1', 'key2' => 'value2', $key3 => 'value3', 'value4', 10 => 'value5' ); // Bad. + +// Test for fixing associative arrays with comments between values. +$bad = array( +'key1' => 'value1', /* comment */ +'key2' => 'value2' ); // Bad. diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php index 2cb700eb..d316eb2f 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php @@ -28,7 +28,8 @@ public function getErrorList() { 13 => 6, 17 => 5, 19 => 1, - 24 => 1, + 23 => 1, + 26 => 1, ); } From b682f335d3476443450bf970ba793b4e1009c3e2 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 24 Jun 2017 20:23:45 +0200 Subject: [PATCH 082/282] ArrayDeclarationSpacing sniff: improve associative array detection A single-line non-associative array may contain a nested associative array. In that case, the non-associative array should *not* trigger an error, nor be auto-fixed, while the nested associative array should. Previously the non-associative array would also be fixed in that case. This commit adds the logic to distinguish between the two. --- .../Arrays/ArrayDeclarationSpacingSniff.php | 123 ++++++++++++------ .../ArrayDeclarationSpacingUnitTest.inc | 3 + .../ArrayDeclarationSpacingUnitTest.inc.fixed | 5 + .../ArrayDeclarationSpacingUnitTest.php | 1 + 4 files changed, 91 insertions(+), 41 deletions(-) diff --git a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php index bd56f088..e01e0dcd 100644 --- a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php @@ -29,6 +29,21 @@ */ class WordPress_Sniffs_Arrays_ArrayDeclarationSpacingSniff extends WordPress_Sniff { + /** + * Token this sniff targets. + * + * Also used for distinguishing between the array and an array value + * which is also an array. + * + * @since 0.12.0 + * + * @var array + */ + private $targets = array( + T_ARRAY => T_ARRAY, + T_OPEN_SHORT_ARRAY => T_OPEN_SHORT_ARRAY, + ); + /** * Returns an array of tokens this test wants to listen for. * @@ -37,10 +52,7 @@ class WordPress_Sniffs_Arrays_ArrayDeclarationSpacingSniff extends WordPress_Sni * @return array */ public function register() { - return array( - T_ARRAY, - T_OPEN_SHORT_ARRAY, - ); + return $this->targets; } /** @@ -66,6 +78,7 @@ public function process_token( $stackPtr ) { $opener = $array_open_close['opener']; $closer = $array_open_close['closer']; + unset( $array_open_close ); // This array is empty, so the below checks aren't necessary. if ( ( $opener + 1 ) === $closer ) { @@ -124,50 +137,78 @@ public function process_token( $stackPtr ) { $array_has_keys = $this->phpcsFile->findNext( T_DOUBLE_ARROW, $opener, $closer ); if ( false !== $array_has_keys ) { - $fix = $this->phpcsFile->addFixableError( - 'When an array uses associative keys, each value should start on a new line.', - $closer, - 'AssociativeKeyFound' - ); - - if ( true === $fix ) { - $array_items = $this->get_function_call_parameters( $stackPtr ); - if ( empty( $array_items ) ) { - // Strange, no array items found. - return; - } + $array_items = $this->get_function_call_parameters( $stackPtr ); + if ( empty( $array_items ) ) { + // Strange, no array items found. + return; + } - $this->phpcsFile->fixer->beginChangeset(); - - foreach( $array_items as $item ) { - /* - * Add a line break before the first non-empty token in the array item. - * Prevents extraneous whitespace at the start of the line which could be - * interpreted as alignment whitespace. - */ - $first_non_empty = $this->phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens, - $item['start'], - ( $item['end'] + 1 ), - true - ); - if ( false === $first_non_empty ) { - continue; + /* + * Make sure the double arrow is for *this* array, not for a nested one. + */ + $array_has_keys = false; // Reset before doing more detailed check. + foreach ( $array_items as $item ) { + for ( $ptr = $item['start']; $ptr <= $item['end']; $ptr++ ) { + if ( T_DOUBLE_ARROW === $this->tokens[ $ptr ]['code'] ) { + $array_has_keys = true; + break 2; } - if ( $item['start'] <= ( $first_non_empty - 1 ) - && T_WHITESPACE === $this->tokens[ ( $first_non_empty - 1 ) ]['code'] - ) { - // Remove whitespace which would otherwise becoming trailing - // (as it gives problems with the fixed file). - $this->phpcsFile->fixer->replaceToken( ( $first_non_empty - 1 ), '' ); + // Skip passed any nested arrays. + if ( isset( $this->targets[ $this->tokens[ $ptr ]['code'] ] ) ) { + $nested_array_open_close = $this->find_array_open_close( $ptr ); + if ( false === $nested_array_open_close ) { + // Nested array open/close could not be determined. + continue; + } + + $ptr = $nested_array_open_close['closer']; } - - $this->phpcsFile->fixer->addNewlineBefore( $first_non_empty ); } + } - $this->phpcsFile->fixer->endChangeset(); + if ( true === $array_has_keys ) { + + $fix = $this->phpcsFile->addFixableError( + 'When an array uses associative keys, each value should start on a new line.', + $closer, + 'AssociativeKeyFound' + ); + + if ( true === $fix ) { + + $this->phpcsFile->fixer->beginChangeset(); + + foreach( $array_items as $item ) { + /* + * Add a line break before the first non-empty token in the array item. + * Prevents extraneous whitespace at the start of the line which could be + * interpreted as alignment whitespace. + */ + $first_non_empty = $this->phpcsFile->findNext( + PHP_CodeSniffer_Tokens::$emptyTokens, + $item['start'], + ( $item['end'] + 1 ), + true + ); + if ( false === $first_non_empty ) { + continue; + } + + if ( $item['start'] <= ( $first_non_empty - 1 ) + && T_WHITESPACE === $this->tokens[ ( $first_non_empty - 1 ) ]['code'] + ) { + // Remove whitespace which would otherwise becoming trailing + // (as it gives problems with the fixed file). + $this->phpcsFile->fixer->replaceToken( ( $first_non_empty - 1 ), '' ); + } + + $this->phpcsFile->fixer->addNewlineBefore( $first_non_empty ); + } + + $this->phpcsFile->fixer->endChangeset(); + } } } } diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc index f10329d7..fbdc7574 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc @@ -24,3 +24,6 @@ $bad = array( // Test for fixing associative arrays with comments between values. $bad = array( 'key1' => 'value1', /* comment */ 'key2' => 'value2' ); // Bad. + +// Test for (not) fixing non-associative array with a nested associative array which *will* be fixed. +$bad = array( 'value1', 'value2', [ 'sub1' => 1, 'sub2' => 2 ], 'value4' ); // Bad. diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed index ad9e8efb..a514cde1 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed @@ -47,3 +47,8 @@ $key3 => 'value3', $bad = array( 'key1' => 'value1', /* comment */ 'key2' => 'value2' ); // Bad. + +// Test for (not) fixing non-associative array with a nested associative array which *will* be fixed. +$bad = array( 'value1', 'value2', [ +'sub1' => 1, +'sub2' => 2 ], 'value4' ); // Bad. diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php index d316eb2f..b6894798 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php @@ -30,6 +30,7 @@ public function getErrorList() { 19 => 1, 23 => 1, 26 => 1, + 29 => 1, ); } From 66174787f7f79ae46ba95307ca53b6403f7bdf85 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 24 Jun 2017 20:59:04 +0200 Subject: [PATCH 083/282] ArrayDeclarationSpacing sniff: move the associative array check up ... as the spacing checks are not relevant when the array needs to be changed to multi-line. --- .../Arrays/ArrayDeclarationSpacingSniff.php | 177 ++++++++++-------- .../ArrayDeclarationSpacingUnitTest.php | 4 +- 2 files changed, 96 insertions(+), 85 deletions(-) diff --git a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php index e01e0dcd..06c18ea0 100644 --- a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php @@ -66,7 +66,6 @@ public function register() { * @return void */ public function process_token( $stackPtr ) { - /* * Determine the array opener & closer. */ @@ -90,11 +89,97 @@ public function process_token( $stackPtr ) { return; } - // Check that there is a single space after the array opener. + /* + * Check that associative arrays are always multi-line. + */ + $array_has_keys = $this->phpcsFile->findNext( T_DOUBLE_ARROW, $opener, $closer ); + if ( false !== $array_has_keys ) { + + $array_items = $this->get_function_call_parameters( $stackPtr ); + + if ( ! empty( $array_items ) ) { + /* + * Make sure the double arrow is for *this* array, not for a nested one. + */ + $array_has_keys = false; // Reset before doing more detailed check. + foreach ( $array_items as $item ) { + for ( $ptr = $item['start']; $ptr <= $item['end']; $ptr++ ) { + if ( T_DOUBLE_ARROW === $this->tokens[ $ptr ]['code'] ) { + $array_has_keys = true; + break 2; + } + + // Skip passed any nested arrays. + if ( isset( $this->targets[ $this->tokens[ $ptr ]['code'] ] ) ) { + $nested_array_open_close = $this->find_array_open_close( $ptr ); + if ( false === $nested_array_open_close ) { + // Nested array open/close could not be determined. + continue; + } + + $ptr = $nested_array_open_close['closer']; + } + } + } + + if ( true === $array_has_keys ) { + + $fix = $this->phpcsFile->addFixableError( + 'When an array uses associative keys, each value should start on a new line.', + $closer, + 'AssociativeKeyFound' + ); + + if ( true === $fix ) { + + $this->phpcsFile->fixer->beginChangeset(); + + foreach ( $array_items as $item ) { + /* + * Add a line break before the first non-empty token in the array item. + * Prevents extraneous whitespace at the start of the line which could be + * interpreted as alignment whitespace. + */ + $first_non_empty = $this->phpcsFile->findNext( + PHP_CodeSniffer_Tokens::$emptyTokens, + $item['start'], + ( $item['end'] + 1 ), + true + ); + if ( false === $first_non_empty ) { + continue; + } + + if ( $item['start'] <= ( $first_non_empty - 1 ) + && T_WHITESPACE === $this->tokens[ ( $first_non_empty - 1 ) ]['code'] + ) { + // Remove whitespace which would otherwise becoming trailing + // (as it gives problems with the fixed file). + $this->phpcsFile->fixer->replaceToken( ( $first_non_empty - 1 ), '' ); + } + + $this->phpcsFile->fixer->addNewlineBefore( $first_non_empty ); + } + + $this->phpcsFile->fixer->endChangeset(); + } + + // No need to check for spacing around parentheses as this array should be multi-line. + return; + } + } + } + + /* + * Check that there is a single space after the array opener and before the array closer. + */ if ( T_WHITESPACE !== $this->tokens[ ( $opener + 1 ) ]['code'] ) { - $warning = 'Missing space after array opener.'; - $fix = $this->phpcsFile->addFixableError( $warning, $opener, 'NoSpaceAfterArrayOpener' ); + $fix = $this->phpcsFile->addFixableError( + 'Missing space after array opener.', + $opener, + 'NoSpaceAfterArrayOpener' + ); if ( true === $fix ) { $this->phpcsFile->fixer->addContent( $opener, ' ' ); @@ -115,8 +200,11 @@ public function process_token( $stackPtr ) { if ( T_WHITESPACE !== $this->tokens[ ( $closer - 1 ) ]['code'] ) { - $warning = 'Missing space before array closer.'; - $fix = $this->phpcsFile->addFixableError( $warning, $closer, 'NoSpaceBeforeArrayCloser' ); + $fix = $this->phpcsFile->addFixableError( + 'Missing space before array closer.', + $closer, + 'NoSpaceBeforeArrayCloser' + ); if ( true === $fix ) { $this->phpcsFile->fixer->addContentBefore( $closer, ' ' ); @@ -134,83 +222,6 @@ public function process_token( $stackPtr ) { $this->phpcsFile->fixer->replaceToken( ( $closer - 1 ), ' ' ); } } - - $array_has_keys = $this->phpcsFile->findNext( T_DOUBLE_ARROW, $opener, $closer ); - if ( false !== $array_has_keys ) { - - $array_items = $this->get_function_call_parameters( $stackPtr ); - if ( empty( $array_items ) ) { - // Strange, no array items found. - return; - } - - /* - * Make sure the double arrow is for *this* array, not for a nested one. - */ - $array_has_keys = false; // Reset before doing more detailed check. - foreach ( $array_items as $item ) { - for ( $ptr = $item['start']; $ptr <= $item['end']; $ptr++ ) { - if ( T_DOUBLE_ARROW === $this->tokens[ $ptr ]['code'] ) { - $array_has_keys = true; - break 2; - } - - // Skip passed any nested arrays. - if ( isset( $this->targets[ $this->tokens[ $ptr ]['code'] ] ) ) { - $nested_array_open_close = $this->find_array_open_close( $ptr ); - if ( false === $nested_array_open_close ) { - // Nested array open/close could not be determined. - continue; - } - - $ptr = $nested_array_open_close['closer']; - } - } - } - - if ( true === $array_has_keys ) { - - $fix = $this->phpcsFile->addFixableError( - 'When an array uses associative keys, each value should start on a new line.', - $closer, - 'AssociativeKeyFound' - ); - - if ( true === $fix ) { - - $this->phpcsFile->fixer->beginChangeset(); - - foreach( $array_items as $item ) { - /* - * Add a line break before the first non-empty token in the array item. - * Prevents extraneous whitespace at the start of the line which could be - * interpreted as alignment whitespace. - */ - $first_non_empty = $this->phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens, - $item['start'], - ( $item['end'] + 1 ), - true - ); - if ( false === $first_non_empty ) { - continue; - } - - if ( $item['start'] <= ( $first_non_empty - 1 ) - && T_WHITESPACE === $this->tokens[ ( $first_non_empty - 1 ) ]['code'] - ) { - // Remove whitespace which would otherwise becoming trailing - // (as it gives problems with the fixed file). - $this->phpcsFile->fixer->replaceToken( ( $first_non_empty - 1 ), '' ); - } - - $this->phpcsFile->fixer->addNewlineBefore( $first_non_empty ); - } - - $this->phpcsFile->fixer->endChangeset(); - } - } - } } } // End class. diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php index b6894798..dd4e6ce2 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php @@ -25,8 +25,8 @@ public function getErrorList() { 5 => 2, 8 => 2, 10 => 1, - 13 => 6, - 17 => 5, + 13 => 4, + 17 => 2, 19 => 1, 23 => 1, 26 => 1, From 7fa30ba2122510a17939edeaf7563095c8e2d7c5 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 24 Jun 2017 22:12:53 +0200 Subject: [PATCH 084/282] OperatorSpacing sniff: check whitespace around logical operators While working on something else, I realized that the spacing around logical operators - `&&`, `||`, `and`, `or` and `xor` - was not checked at all by the WordPress coding standards so far. This PR fixes that. Includes unit tests for the WPCS customizations. --- .../WhiteSpace/OperatorSpacingSniff.php | 16 ++++---- .../WhiteSpace/OperatorSpacingUnitTest.inc | 38 ++++++++++++++++++- .../OperatorSpacingUnitTest.inc.fixed | 38 ++++++++++++++++++- .../WhiteSpace/OperatorSpacingUnitTest.php | 10 +++++ 4 files changed, 93 insertions(+), 9 deletions(-) diff --git a/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php b/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php index ac57a2c9..921dfcd4 100644 --- a/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php +++ b/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php @@ -24,9 +24,10 @@ * @since 0.3.0 This sniff now has the ability to fix the issues it flags. * @since 0.12.0 This sniff used to be a copy of a very old and outdated version of the * upstream sniff. - * Now, the sniff defers completely to the upstream sniff, adding just one - * additional token - T_BOOLEAN_NOT - via the registration method - * and changing the value of the customizable $ignoreNewlines property. + * Now, the sniff defers completely to the upstream sniff, adding just the + * T_BOOLEAN_NOT and the logical operators (`&&` and the like) - via the + * registration method and changing the value of the customizable + * $ignoreNewlines property. * * Last synced with base class June 2017 at commit 41127aa4764536f38f504fb3f7b8831f05919c89. * @link https://github.com/squizlabs/PHP_CodeSniffer/blob/master/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/OperatorSpacingSniff.php @@ -49,11 +50,12 @@ class WordPress_Sniffs_WhiteSpace_OperatorSpacingSniff extends Squiz_Sniffs_Whit * @return array */ public function register() { - $tokens = parent::register(); - $tokens[] = T_BOOLEAN_NOT; - - return $tokens; + $tokens = parent::register(); + $tokens[ T_BOOLEAN_NOT ] = T_BOOLEAN_NOT; + $logical_operators = PHP_CodeSniffer_Tokens::$booleanOperators; + // Using array union to auto-dedup. + return $tokens + $logical_operators; } } // End class. diff --git a/WordPress/Tests/WhiteSpace/OperatorSpacingUnitTest.inc b/WordPress/Tests/WhiteSpace/OperatorSpacingUnitTest.inc index ab44d569..bad89cc0 100644 --- a/WordPress/Tests/WhiteSpace/OperatorSpacingUnitTest.inc +++ b/WordPress/Tests/WhiteSpace/OperatorSpacingUnitTest.inc @@ -1,6 +1,6 @@ 2, 28 => 2, + 40 => 2, + 41 => 2, + 42 => 2, + 43 => 2, + 44 => 2, + 47 => 2, + 48 => 2, + 49 => 2, + 50 => 2, + 51 => 2, ); } From d789af53bfbf7a2c1ddc601b91e4af58fd5943e0 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 25 Jun 2017 08:02:40 +0200 Subject: [PATCH 085/282] :sparkles: New `CommaAfterArrayItem` sniff New sniff to enforce a comma after each array item and check the spacing around it. Rules: - For multi-line arrays, a comma is needed after each array item. - Same for single-line arrays, but no comma is allowed after the last array item. - There should be no space between the comma and the end of the array item. - There should be exactly one space between the comma and the start of the next array item for single-line items. This sniff replaces the comma related checks within the `ArrayDeclaration` sniff which were buggy in a number of cases. * The single-line array comma related checks in the `WordPress.Arrays.ArrayDeclaration` have been excluded via the ruleset. * The multi-line array comma related checks have been commented out in the `WordPress.Arrays.ArrayDeclaration` sniff as explained in more detail in 998#issuecomment-310869580 . Fixes 986 Fixes 998 --- WordPress-Core/ruleset.xml | 10 +- .../Sniffs/Arrays/ArrayDeclarationSniff.php | 10 +- .../Arrays/CommaAfterArrayItemSniff.php | 282 ++++++++++++++++++ .../Arrays/CommaAfterArrayItemUnitTest.inc | 155 ++++++++++ .../CommaAfterArrayItemUnitTest.inc.fixed | 148 +++++++++ .../Arrays/CommaAfterArrayItemUnitTest.php | 72 +++++ 6 files changed, 674 insertions(+), 3 deletions(-) create mode 100644 WordPress/Sniffs/Arrays/CommaAfterArrayItemSniff.php create mode 100644 WordPress/Tests/Arrays/CommaAfterArrayItemUnitTest.inc create mode 100644 WordPress/Tests/Arrays/CommaAfterArrayItemUnitTest.inc.fixed create mode 100644 WordPress/Tests/Arrays/CommaAfterArrayItemUnitTest.php diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index e8cd9b3c..231d397d 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -45,10 +45,18 @@ - + + + + + + + + + diff --git a/WordPress/Sniffs/Arrays/ArrayDeclarationSniff.php b/WordPress/Sniffs/Arrays/ArrayDeclarationSniff.php index 83f76385..9e1e4be8 100644 --- a/WordPress/Sniffs/Arrays/ArrayDeclarationSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayDeclarationSniff.php @@ -142,6 +142,7 @@ public function processMultiLineArray( PHP_CodeSniffer_File $phpcsFile, $stackPt $currentEntry = array(); if ($tokens[$nextToken]['code'] === T_COMMA) { + /* $stackPtrCount = 0; if (isset($tokens[$stackPtr]['nested_parenthesis']) === true) { $stackPtrCount = count( $tokens[ $stackPtr ]['nested_parenthesis'] ); @@ -163,7 +164,6 @@ public function processMultiLineArray( PHP_CodeSniffer_File $phpcsFile, $stackPt continue; } - /* if ($keyUsed === true && $tokens[$lastToken]['code'] === T_COMMA) { $error = 'No key specified for array entry; first entry specifies key'; $phpcsFile->addError( $error, $nextToken, 'NoKeySpecified' ); @@ -172,6 +172,7 @@ public function processMultiLineArray( PHP_CodeSniffer_File $phpcsFile, $stackPt */ if ($keyUsed === false) { + /* if ($tokens[($nextToken - 1)]['code'] === T_WHITESPACE) { $content = $tokens[ ( $nextToken - 2 ) ]['content']; if ( $tokens[ ( $nextToken - 1 ) ]['content'] === $phpcsFile->eolChar ) { @@ -191,6 +192,7 @@ public function processMultiLineArray( PHP_CodeSniffer_File $phpcsFile, $stackPt $phpcsFile->fixer->replaceToken( ( $nextToken - 1 ), '' ); } } + */ $valueContent = $phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, @@ -200,7 +202,7 @@ public function processMultiLineArray( PHP_CodeSniffer_File $phpcsFile, $stackPt ); $indices[] = array( 'value' => $valueContent ); - $singleUsed = true; + // $singleUsed = true; }//end if $lastToken = $nextToken; @@ -320,6 +322,7 @@ public function processMultiLineArray( PHP_CodeSniffer_File $phpcsFile, $stackPt true ); + /* if ($tokens[$trailingContent]['code'] !== T_COMMA) { $phpcsFile->recordMetric( $stackPtr, 'Array end comma', 'no' ); $error = 'Comma required after last value in array declaration'; @@ -330,6 +333,7 @@ public function processMultiLineArray( PHP_CodeSniffer_File $phpcsFile, $stackPt } else { $phpcsFile->recordMetric( $stackPtr, 'Array end comma', 'yes' ); } + */ $lastValueLine = false; foreach ( $indices as $value ) { @@ -531,6 +535,7 @@ public function processMultiLineArray( PHP_CodeSniffer_File $phpcsFile, $stackPt */ // Check each line ends in a comma. + /* $valueLine = $tokens[ $index['value'] ]['line']; $nextComma = false; for ( $i = $index['value']; $i < $arrayEnd; $i++ ) { @@ -604,6 +609,7 @@ public function processMultiLineArray( PHP_CodeSniffer_File $phpcsFile, $stackPt $phpcsFile->fixer->replaceToken( ( $nextComma - 1 ), '' ); } } + */ }//end foreach }//end processMultiLineArray() diff --git a/WordPress/Sniffs/Arrays/CommaAfterArrayItemSniff.php b/WordPress/Sniffs/Arrays/CommaAfterArrayItemSniff.php new file mode 100644 index 00000000..0ec7f103 --- /dev/null +++ b/WordPress/Sniffs/Arrays/CommaAfterArrayItemSniff.php @@ -0,0 +1,282 @@ +find_array_open_close( $stackPtr ); + if ( false === $array_open_close ) { + // Array open/close could not be determined. + return; + } + + $opener = $array_open_close['opener']; + $closer = $array_open_close['closer']; + unset( $array_open_close ); + + // This array is empty, so the below checks aren't necessary. + if ( ( $opener + 1 ) === $closer ) { + return; + } + + $single_line = true; + if ( $this->tokens[ $opener ]['line'] !== $this->tokens[ $closer ]['line'] ) { + $single_line = false; + } + + $array_items = $this->get_function_call_parameters( $stackPtr ); + if ( empty( $array_items ) ) { + // Strange, no array items found. + return; + } + + $array_item_count = count( $array_items ); + + // Note: $item_index is 1-based and the array items are split on the commas! + foreach ( $array_items as $item_index => $item ) { + $maybe_comma = ( $item['end'] + 1 ); + $is_comma = false; + if ( isset( $this->tokens[ $maybe_comma ] ) && T_COMMA === $this->tokens[ $maybe_comma ]['code'] ) { + $is_comma = true; + } + + /* + * Check if this is a comma at the end of the last item in a single line array. + */ + if ( true === $single_line && $item_index === $array_item_count ) { + + if ( true === $is_comma ) { + $fix = $this->phpcsFile->addFixableError( + 'Comma not allowed after last value in single-line array declaration', + $maybe_comma, + 'CommaAfterLast' + ); + + if ( true === $fix ) { + $this->phpcsFile->fixer->replaceToken( $maybe_comma, '' ); + } + } + + /* + * No need to do the spacing checks for the last item in a single line array. + * This is handled by another sniff checking the spacing before the array closer. + */ + continue; + } + + $last_content = $this->phpcsFile->findPrevious( + PHP_CodeSniffer_Tokens::$emptyTokens, + $item['end'], + $item['start'], + true + ); + + if ( false === $last_content ) { + // Shouldn't be able to happen, but just in case, ignore this array item. + continue; + } + + /** + * Make sure every item in a multi-line array has a comma at the end. + * + * Should in reality only be triggered by the last item in a multi-line array + * as otherwise we'd have a parse error already. + */ + if ( false === $is_comma && false === $single_line ) { + + $fix = $this->phpcsFile->addFixableError( + 'Each array item in a multi-line array declaration must end in a comma', + $last_content, + 'NoComma' + ); + + if ( true === $fix ) { + $this->phpcsFile->fixer->addContent( $last_content, ',' ); + } + } + + if ( false === $is_comma ) { + // Can't check spacing around the comma if there is no comma. + continue; + } + + /* + * Check for whitespace at the end of the array item. + */ + if ( $last_content !== $item['end'] + // Ignore whitespace at the end of a multi-line item if it is the end of a heredoc/nowdoc. + && ( true === $single_line + || ! isset( PHP_CodeSniffer_Tokens::$heredocTokens[ $this->tokens[ $last_content ]['code'] ] ) ) + ) { + $newlines = 0; + $spaces = 0; + for ( $i = $item['end']; $i > $last_content; $i-- ) { + + if ( T_WHITESPACE === $this->tokens[ $i ]['code'] ) { + $this->phpcsFile->fixer->replaceToken( $i, '' ); + + if ( $this->tokens[ $i ]['content'] === $this->phpcsFile->eolChar ) { + $newlines++; + } else { + $spaces += $this->tokens[ $i ]['length']; + } + } elseif ( T_COMMENT === $this->tokens[ $i ]['code'] ) { + break; + } + } + + $space_phrases = array(); + if ( $spaces > 0 ) { + $space_phrases[] = $spaces . ' spaces'; + } + if ( $newlines > 0 ) { + $space_phrases[] = $newlines . ' newlines'; + } + unset( $newlines, $spaces ); + + $fix = $this->phpcsFile->addFixableError( + 'Expected 0 spaces between "%s" and comma; %s found', + $maybe_comma, + 'SpaceBeforeComma', + array( + $this->tokens[ $last_content ]['content'], + implode( ' and ', $space_phrases ), + ) + ); + + if ( true === $fix ) { + $this->phpcsFile->fixer->beginChangeset(); + for ( $i = $item['end']; $i > $last_content; $i-- ) { + + if ( T_WHITESPACE === $this->tokens[ $i ]['code'] ) { + $this->phpcsFile->fixer->replaceToken( $i, '' ); + + } elseif ( T_COMMENT === $this->tokens[ $i ]['code'] ) { + // We need to move the comma to before the comment. + $this->phpcsFile->fixer->addContent( $last_content, ',' ); + $this->phpcsFile->fixer->replaceToken( $maybe_comma, '' ); + + /* + * No need to worry about removing too much whitespace in + * combination with a `//` comment as in that case, the newline + * is part of the comment, so we're good. + */ + + break; + } + } + $this->phpcsFile->fixer->endChangeset(); + } + } + + if ( ! isset( $this->tokens[ ( $maybe_comma + 1 ) ] ) ) { + // Shouldn't be able to happen, but just in case. + continue; + } + + /* + * Check whitespace after the comma. + */ + $next_token = $this->tokens[ ( $maybe_comma + 1 ) ]; + + if ( T_WHITESPACE === $next_token['code'] ) { + + if ( false === $single_line && $this->phpcsFile->eolChar === $next_token['content'] ) { + continue; + } + + $next_non_whitespace = $this->phpcsFile->findNext( + T_WHITESPACE, + ($maybe_comma + 1 ), + $closer, + true + ); + + if ( false === $next_non_whitespace + || ( false === $single_line + && $this->tokens[ $next_non_whitespace ]['line'] === $this->tokens[ $maybe_comma ]['line'] + && T_COMMENT === $this->tokens[ $next_non_whitespace ]['code'] ) + ) { + continue; + } + + $space_length = $next_token['length']; + if ( 1 === $space_length ) { + continue; + } + + $fix = $this->phpcsFile->addFixableError( + 'Expected 1 space between comma and "%s"; %s found', + $maybe_comma, + 'SpaceAfterComma', + array( + $this->tokens[ $next_non_whitespace ]['content'], + $space_length, + ) + ); + + if ( true === $fix ) { + $this->phpcsFile->fixer->replaceToken( ( $maybe_comma + 1 ), ' ' ); + } + } else { + // This is either a comment or a mixed single/multi-line array. + // Just add a space and let other sniffs sort out the array layout. + $fix = $this->phpcsFile->addFixableError( + 'Expected 1 space between comma and "%s"; 0 found', + $maybe_comma, + 'NoSpaceAfterComma', + array( $next_token['content'] ) + ); + + if ( true === $fix ) { + $this->phpcsFile->fixer->addContent( $maybe_comma, ' ' ); + } + } + } + } + +} // End class. diff --git a/WordPress/Tests/Arrays/CommaAfterArrayItemUnitTest.inc b/WordPress/Tests/Arrays/CommaAfterArrayItemUnitTest.inc new file mode 100644 index 00000000..6b6e2ed7 --- /dev/null +++ b/WordPress/Tests/Arrays/CommaAfterArrayItemUnitTest.inc @@ -0,0 +1,155 @@ + 'value', + 2 => array( 1 ), + 3 => apply_filters( 'filter', $input, $var ), /* Comment. */ +); +$good = [ + 'a' => 'value', // Comment - the extra spacing is fine, might be for alignment with other comments. + 'b' => array( 1 ), + 'c' => apply_filters( 'filter', $input, $var ), +]; + +// OK: that this should be a multi-line array is not the concern of this sniff. +$good = array( 1 => 'a', 2 => 'b', 3 => 'c' ); +$good = [ 'a' => 1, 'b' => 2, 'c' => 3 ]; + +$good = array( 1, 2, // OK: that each item should be on its own line or single line array is not the concern of this sniff. + 3, ); // OK: that the brace should be on another line is not the concern of this sniff. + +/* + * Bad. + */ +// Spacing before comma. +$bad = array( 1 , 2 , 3 ); // Bad x2. +$bad = [ 'a' , 'b' , 'c' ]; // Bad x2. + +// Spacing after comma. +$bad = array( 1,2, 3 ); // Bad x2. +$bad = [ 'a','b', 'c' ]; // Bad x2. + +// Comma after last. +$bad = array( 1, 2, 3, ); +$bad = [ 'a', 'b', 'c', ]; + +// Spacing before comma. +$bad = array( + 1 => 'value' , + 2 => array( 1 ) , + 3 => apply_filters( 'filter', $input, $var ) , /* Comment. */ +); +$bad = [ + 'a' => 'value' , // Comment - the extra spacing is fine, might be for alignment with other comments. + 'b' => array( 1 ) + + + , + 'c' => apply_filters( 'filter', $input, $var ) , +]; + +// NO spacing after comma. +$bad = array( + 3 => apply_filters( 'filter', $input, $var ),/* Comment. */ +); +$bad = [ + 'a' => 'value',// Comment. +]; + +// NO comma after last. +$bad = array( + 1 => 'value', + 2 => array( 1 ), + 3 => apply_filters( 'filter', $input, $var )/* Comment. */ +); +$bad = [ + 'a' => 'value', // Comment - the extra spacing is fine, might be for alignment with other comments. + 'b' => array( 1 ), + 'c' => apply_filters( 'filter', $input, $var ) +]; + +$bad = array( 1 => 'a' , 2 => 'b',3 => 'c', ); +$bad = [ 'a' => 1 , 'b' => 2,'c' => 3, ]; + +$bad = array( 1 , 2, + 3 ); + +// Combining a lot of errors in a nested array. +$bad = array( + 1 => 'value' , + 2 => [ + 'a' => 'value' ,// Comment - the extra spacing is fine, might be for alignment with other comments. + 'b' => array( + 1 + ), + 'c' => apply_filters( 'filter', $input, $var ) + ], + 3 => apply_filters( 'filter', $input, $var )/* Comment. */ +); + +// Alternative array style. +$bad = array( + 1 => 'value' + , 2 => array( 1 ) + , 3 => apply_filters( 'filter', $input, $var )/* Comment. */ +); +$bad = [ + 'a' => 'value' // Comment - the extra spacing is fine, might be for alignment with other comments. + , 'b' => array( 1 ) + , 'c' => apply_filters( 'filter', $input, $var ) +]; +$bad = [ + 'a' => 'value' // Comment - the extra spacing is fine, might be for alignment with other comments. + ,'b' => array( 1 ) + ,'c' => apply_filters( 'filter', $input, $var ), +]; + +$bad = array( + 'first', + 'second' + //'third', + ); + +$bad = array( + 'key3' => function($bar) { + return $bar; + } +); + +// Issue #998. +$a = array( + 'foo' => bar( 1, 29 )); + +// Issue #986. +get_current_screen()->add_help_tab( array( + 'id' => <<add_help_tab( array( +'id' => <<', +) ); diff --git a/WordPress/Tests/Arrays/CommaAfterArrayItemUnitTest.inc.fixed b/WordPress/Tests/Arrays/CommaAfterArrayItemUnitTest.inc.fixed new file mode 100644 index 00000000..3fbeae06 --- /dev/null +++ b/WordPress/Tests/Arrays/CommaAfterArrayItemUnitTest.inc.fixed @@ -0,0 +1,148 @@ + 'value', + 2 => array( 1 ), + 3 => apply_filters( 'filter', $input, $var ), /* Comment. */ +); +$good = [ + 'a' => 'value', // Comment - the extra spacing is fine, might be for alignment with other comments. + 'b' => array( 1 ), + 'c' => apply_filters( 'filter', $input, $var ), +]; + +// OK: that this should be a multi-line array is not the concern of this sniff. +$good = array( 1 => 'a', 2 => 'b', 3 => 'c' ); +$good = [ 'a' => 1, 'b' => 2, 'c' => 3 ]; + +$good = array( 1, 2, // OK: that each item should be on its own line or single line array is not the concern of this sniff. + 3, ); // OK: that the brace should be on another line is not the concern of this sniff. + +/* + * Bad. + */ +// Spacing before comma. +$bad = array( 1, 2, 3 ); // Bad x2. +$bad = [ 'a', 'b', 'c' ]; // Bad x2. + +// Spacing after comma. +$bad = array( 1, 2, 3 ); // Bad x2. +$bad = [ 'a', 'b', 'c' ]; // Bad x2. + +// Comma after last. +$bad = array( 1, 2, 3 ); +$bad = [ 'a', 'b', 'c' ]; + +// Spacing before comma. +$bad = array( + 1 => 'value', + 2 => array( 1 ), + 3 => apply_filters( 'filter', $input, $var ), /* Comment. */ +); +$bad = [ + 'a' => 'value', // Comment - the extra spacing is fine, might be for alignment with other comments. + 'b' => array( 1 ), + 'c' => apply_filters( 'filter', $input, $var ), +]; + +// NO spacing after comma. +$bad = array( + 3 => apply_filters( 'filter', $input, $var ), /* Comment. */ +); +$bad = [ + 'a' => 'value', // Comment. +]; + +// NO comma after last. +$bad = array( + 1 => 'value', + 2 => array( 1 ), + 3 => apply_filters( 'filter', $input, $var ), /* Comment. */ +); +$bad = [ + 'a' => 'value', // Comment - the extra spacing is fine, might be for alignment with other comments. + 'b' => array( 1 ), + 'c' => apply_filters( 'filter', $input, $var ), +]; + +$bad = array( 1 => 'a', 2 => 'b', 3 => 'c' ); +$bad = [ 'a' => 1, 'b' => 2, 'c' => 3 ]; + +$bad = array( 1, 2, + 3, ); + +// Combining a lot of errors in a nested array. +$bad = array( + 1 => 'value', + 2 => [ + 'a' => 'value', // Comment - the extra spacing is fine, might be for alignment with other comments. + 'b' => array( + 1, + ), + 'c' => apply_filters( 'filter', $input, $var ), + ], + 3 => apply_filters( 'filter', $input, $var ), /* Comment. */ +); + +// Alternative array style. +$bad = array( + 1 => 'value', 2 => array( 1 ), 3 => apply_filters( 'filter', $input, $var ), /* Comment. */ +); +$bad = [ + 'a' => 'value', // Comment - the extra spacing is fine, might be for alignment with other comments. + 'b' => array( 1 ), 'c' => apply_filters( 'filter', $input, $var ), +]; +$bad = [ + 'a' => 'value', // Comment - the extra spacing is fine, might be for alignment with other comments. +'b' => array( 1 ), 'c' => apply_filters( 'filter', $input, $var ), +]; + +$bad = array( + 'first', + 'second', + //'third', + ); + +$bad = array( + 'key3' => function($bar) { + return $bar; + }, +); + +// Issue #998. +$a = array( + 'foo' => bar( 1, 29 ), ); + +// Issue #986. +get_current_screen()->add_help_tab( array( + 'id' => <<add_help_tab( array( +'id' => <<', +) ); diff --git a/WordPress/Tests/Arrays/CommaAfterArrayItemUnitTest.php b/WordPress/Tests/Arrays/CommaAfterArrayItemUnitTest.php new file mode 100644 index 00000000..7df0fff2 --- /dev/null +++ b/WordPress/Tests/Arrays/CommaAfterArrayItemUnitTest.php @@ -0,0 +1,72 @@ + => + */ + public function getErrorList() { + return array( + 44 => 2, + 45 => 2, + 48 => 2, + 49 => 2, + 52 => 1, + 53 => 1, + 57 => 1, + 58 => 1, + 59 => 1, + 62 => 1, + 66 => 1, + 67 => 1, + 72 => 1, + 75 => 1, + 82 => 1, + 87 => 1, + 90 => 4, + 91 => 4, + 93 => 2, + 94 => 1, + 98 => 1, + 100 => 2, + 102 => 1, + 104 => 1, + 106 => 1, + 112 => 1, + 113 => 2, + 117 => 1, + 118 => 2, + 122 => 2, + 123 => 2, + 128 => 1, + 135 => 1, + 140 => 1, + ); + } + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array(); + + } + +} // End class. From 36dd20005051e42fed21bb46eb4ee75a92b3e729 Mon Sep 17 00:00:00 2001 From: dixitadusara Date: Thu, 29 Jun 2017 19:04:17 +0530 Subject: [PATCH 086/282] Fix Project history content minor changes in README.md file --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f81ae2bf..a749871f 100644 --- a/README.md +++ b/README.md @@ -34,8 +34,8 @@ This project is a collection of [PHP_CodeSniffer](https://github.com/squizlabs/P - In April 2009 original project from [Urban Giraffe](http://urbangiraffe.com/articles/wordpress-codesniffer-standard/) was published. - In May 2011 the project was forked on GitHub by [Chris Adams](http://chrisadams.me.uk/). - - In April 2012 [XWP](https://xwp.co/) started to dedicate resources to development and lead creation of the the sniffs and rulesets for `WordPress-Core`, `WordPress-VIP` (WordPress.com VIP), and `WordPress-Extra`. - - In 2015, [J.D. Grimes](https://github.com/JDGrimes) began significant contributions, along with maintanance from [Gary Jones](https://github.com/GaryJones). + - In April 2012 [XWP](https://xwp.co/) started to dedicate resources to develop and lead the creation of the sniffs and rulesets for `WordPress-Core`, `WordPress-VIP` (WordPress.com VIP), and `WordPress-Extra`. + - In 2015, [J.D. Grimes](https://github.com/JDGrimes) began significant contributions, along with maintenance from [Gary Jones](https://github.com/GaryJones). - In 2016, [Juliette Reinders Folmer](https://github.com/jrfnl) began contributing heavily, adding more commits in a year than anyone else in 5 years previous since the project's inception. ## Installation From aff39731b05417b1f113d0d9cac7e535c84b469e Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 30 Jun 2017 00:22:23 +0200 Subject: [PATCH 087/282] Minor improvements to the example ruleset file. * Don't imply that the rules which are excluded in the example are broken/buggy. * Change a grammatically incorrect sentence `to to`. * Add example customization for the new `DeprecatedClasses` sniff. --- project.ruleset.xml.example | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/project.ruleset.xml.example b/project.ruleset.xml.example index b2e44d94..07161a28 100644 --- a/project.ruleset.xml.example +++ b/project.ruleset.xml.example @@ -11,19 +11,18 @@ /docroot/wp-content/plugins/* *.twig - + /vendor/* - + @@ -70,6 +69,12 @@ + + + + + + From 14a198a3cb7e6d98e84b5dc450db8fad34194a83 Mon Sep 17 00:00:00 2001 From: Evilebot Tnawi Date: Mon, 27 Feb 2017 17:31:24 +0300 Subject: [PATCH 088/282] Support phpcodesniffer-composer-installer for easy integrate code style https://github.com/DealerDirect/phpcodesniffer-composer-installer --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 121cdd21..9f9a42cb 100644 --- a/composer.json +++ b/composer.json @@ -19,6 +19,7 @@ "wiki" : "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki", "source": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards" }, + "type" : "phpcodesniffer-standard", "scripts" : { "post-install-cmd": "\"vendor/bin/phpcs\" --config-set installed_paths ../../..", "post-update-cmd" : "\"vendor/bin/phpcs\" --config-set installed_paths ../../.." From e986171c4a254ecfe7dbb2f887c4ac6d38cad446 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 30 Jun 2017 00:58:55 +0200 Subject: [PATCH 089/282] Composer: suggest composer plugin & update README Fixes the open actions for PR 855. --- README.md | 12 +++++++++++- composer.json | 3 +++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a749871f..7a473f14 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ The WordPress Coding Standards are currently [not compatible with the upcoming P ### Composer -Standards can be installed with [Composer](https://getcomposer.org/) dependency manager: +Standards can be installed with the [Composer](https://getcomposer.org/) dependency manager: composer create-project wp-coding-standards/wpcs --no-dev @@ -60,6 +60,16 @@ Running this command will: For convenience of using `phpcs` as global command you might want to add path to `wpcs/vendor/bin` directory to a `PATH` environment of your operating system. +#### Installing WPCS as a dependency + +When installing the WordPress Coding Standards as a dependency in a larger project, the above mentioned step 3 will not be executed automatically. + +There are two actively maintained Composer plugins which can handle the registration of standards with PHP_CodeSniffer for you: +* [composer-phpcodesniffer-standards-plugin](https://github.com/higidi/composer-phpcodesniffer-standards-plugin) +* [phpcodesniffer-composer-installer](https://github.com/DealerDirect/phpcodesniffer-composer-installer) + +It is strongly suggested to `require` one of these plugins in your project to handle the registration of external standards with PHPCS for you. + ### Standalone 1. Install PHP_CodeSniffer by following its [installation instructions](https://github.com/squizlabs/PHP_CodeSniffer#installation) (via Composer, PEAR, or Git checkout). diff --git a/composer.json b/composer.json index 9f9a42cb..a26ee8b5 100644 --- a/composer.json +++ b/composer.json @@ -13,6 +13,9 @@ "require" : { "squizlabs/php_codesniffer": "^2.9.0" }, + "suggest" : { + "dealerdirect/phpcodesniffer-composer-installer": "*" + }, "minimum-stability" : "RC", "support" : { "issues": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues", From 04d997ca88f06f630dd9b97350f6d004c776947d Mon Sep 17 00:00:00 2001 From: david-binda Date: Tue, 28 Feb 2017 22:12:26 +0100 Subject: [PATCH 090/282] Adding missing escaping check for `> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi script: # Lint the PHP files against parse errors. diff --git a/WordPress/Sniffs/XSS/EscapeOutputSniff.php b/WordPress/Sniffs/XSS/EscapeOutputSniff.php index 52e2396e..c6f7625c 100644 --- a/WordPress/Sniffs/XSS/EscapeOutputSniff.php +++ b/WordPress/Sniffs/XSS/EscapeOutputSniff.php @@ -144,19 +144,42 @@ class WordPress_Sniffs_XSS_EscapeOutputSniff extends WordPress_Sniff { 'T_END_NOWDOC' => true, ); + /** + * Status of short_open_tag feature + * + * @since 0.11.0 + * + * @var bool + */ + private $short_open_tag_enabled = true; + /** * Returns an array of tokens this test wants to listen for. * * @return array */ public function register() { - return array( + // Check whether short_open_tag is disabled on PHP version < 5.4 (it's enabled by default in later versions). + if ( PHP_VERSION_ID < 50400 && false === (bool) ini_get( 'short_open_tag' ) ) { + $this->short_open_tag_enabled = false; + } + + $tokens = array( T_ECHO, T_PRINT, T_EXIT, T_STRING, + T_OPEN_TAG_WITH_ECHO, ); + /* + * In case short_open_tag is turned off, we can attempt to regex T_INLINE_HTML + * which is how short open tags are being handled in that case. + */ + if ( false === $this->short_open_tag_enabled ) { + $tokens[] = T_INLINE_HTML; + } + return $tokens; } /** @@ -191,6 +214,24 @@ public function process_token( $stackPtr ) { if ( in_array( $function, array( 'trigger_error', 'user_error' ), true ) ) { $end_of_statement = $this->phpcsFile->findEndOfStatement( $open_paren + 1 ); } + } else if ( false === $this->short_open_tag_enabled && T_INLINE_HTML === $this->tokens[ $stackPtr ]['code'] ) { + // Skip if no PHP short_open_tag is in the string. + if ( false === strpos( $this->tokens[ $stackPtr ]['content'], '\S+|\[[^\]]+\]))*)[\s]*;?[\s]*\?\>/', $this->tokens[ $stackPtr ]['content'], $matches ) ) { + $this->phpcsFile->addError( 'Expected next thing to be an escaping function, not %s.', $stackPtr, 'OutputNotEscaped', $matches[1] ); + return; + } + + // Throw warning in case the T_INLINE_HTML looks like a open_short_tag. + if ( false !== strpos( $this->tokens[ $stackPtr ]['content'], 'phpcsFile->addWarning( 'Possible use of PHP short open tag ( " + + + +foo ?> + 1, 207 => 1, 212 => ( PHP_VERSION_ID < 50300 ) ? 1 : 0, // PHPCS on PHP 5.2 does not recognize T_NOWDOC. + 210 => 1, + 212 => 1, + 213 => 1, ); } // end getErrorList() @@ -74,8 +77,14 @@ public function getErrorList() { * @return array => */ public function getWarningList() { - return array(); + $list = array(); + // Adding Warning which is triggerred in case open_short_tag is set to Off. + if ( PHP_VERSION_ID < 50400 && false === (bool) ini_get( 'short_open_tag' ) ) { + $list[211] = 1; + } + + return $list; } } // End class. From f930afb9e331663df56c7418c26850bcab04058b Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 30 Jun 2017 02:16:10 +0200 Subject: [PATCH 091/282] XSS.EscapeOutput sniff: Update the earlier work done by @david-binda * Document the setting of the PHP ini value in the travis build script. * Set the branch this is tested with to `2.9` as PHPCS 3.x has come out since the original PR was pulled and is now `master`. * Remove the `short_open_tag_enabled` property as the value of this is only used once, so the check can just as efficiently be done in the appropriate place. * Adjust the regex delimiter to be backticks. * Pass `$data` as an array as that's expected by PHPCS. * Remove the throwing of a warning when short open echo tags _"might"_ be found. This warning was also added to the upstream `DisallowShortOpenTag` sniff in PHPCS 2.9.0 and would therefore cause duplicate warnings. See squizlabs/PHP_CodeSniffer/pull/1400. * Adjust the unit test line numbers (merge conflict artefact) Also: adds one missing `@since` tag which is unrelated to this PR, but in the same file and make one very long line a little more readable. --- .travis.yml | 3 +- WordPress/Sniffs/XSS/EscapeOutputSniff.php | 61 ++++++++++---------- WordPress/Tests/XSS/EscapeOutputUnitTest.php | 14 ++--- 3 files changed, 37 insertions(+), 41 deletions(-) diff --git a/.travis.yml b/.travis.yml index 71746a0c..5ab50562 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,7 +37,7 @@ matrix: env: PHPCS_BRANCH=2.9 # Test PHP 5.3 with short_open_tags set to On (is Off by default) - php: 5.3 - env: PHPCS_BRANCH=master SHORT_OPEN_TAGS=true + env: PHPCS_BRANCH=2.9 SHORT_OPEN_TAGS=true allow_failures: # Allow failures for unstable builds. - php: nightly @@ -55,6 +55,7 @@ before_install: # test suite is currently not compatible with PHPUnit 6.x. # Fixed at a very specific PHPUnit version which is also compatible with HHVM. - if [[ ${TRAVIS_PHP_VERSION:0:2} != "5." ]]; then wget -P $PHPUNIT_DIR https://phar.phpunit.de/phpunit-5.7.17.phar && chmod +x $PHPUNIT_DIR/phpunit-5.7.17.phar; fi + # Selectively adjust the ini values for the build image to test ini value dependent sniff features. - if [[ "$SHORT_OPEN_TAGS" == "true" ]]; then echo "short_open_tag = On" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi script: diff --git a/WordPress/Sniffs/XSS/EscapeOutputSniff.php b/WordPress/Sniffs/XSS/EscapeOutputSniff.php index c6f7625c..70e26933 100644 --- a/WordPress/Sniffs/XSS/EscapeOutputSniff.php +++ b/WordPress/Sniffs/XSS/EscapeOutputSniff.php @@ -15,9 +15,11 @@ * @package WPCS\WordPressCodingStandards * * @since 2013-06-11 - * @since 0.4.0 This class now extends WordPress_Sniff. - * @since 0.5.0 The various function list properties which used to be contained in this class - * have been moved to the WordPress_Sniff parent class. + * @since 0.4.0 This class now extends WordPress_Sniff. + * @since 0.5.0 The various function list properties which used to be contained in this class + * have been moved to the WordPress_Sniff parent class. + * @since 0.12.0 This sniff will now also check for output escaping when using shorthand + * echo tags ` true, ); - /** - * Status of short_open_tag feature - * - * @since 0.11.0 - * - * @var bool - */ - private $short_open_tag_enabled = true; - /** * Returns an array of tokens this test wants to listen for. * * @return array */ public function register() { - // Check whether short_open_tag is disabled on PHP version < 5.4 (it's enabled by default in later versions). - if ( PHP_VERSION_ID < 50400 && false === (bool) ini_get( 'short_open_tag' ) ) { - $this->short_open_tag_enabled = false; - } $tokens = array( T_ECHO, @@ -173,10 +164,15 @@ public function register() { ); /* - * In case short_open_tag is turned off, we can attempt to regex T_INLINE_HTML - * which is how short open tags are being handled in that case. + * Check whether short open echo tags are disabled and if so, register the + * T_INLINE_HTML token which is how short open tags are being handled in that case. + * + * In PHP < 5.4, support for short open echo tags depended on whether the + * `short_open_tag` ini directive was set to `true`. + * For PHP >= 5.4, the `short_open_tag` no longer affects the short open + * echo tags and these are now always enabled. */ - if ( false === $this->short_open_tag_enabled ) { + if ( PHP_VERSION_ID < 50400 && false === (bool) ini_get( 'short_open_tag' ) ) { $tokens[] = T_INLINE_HTML; } return $tokens; @@ -214,23 +210,23 @@ public function process_token( $stackPtr ) { if ( in_array( $function, array( 'trigger_error', 'user_error' ), true ) ) { $end_of_statement = $this->phpcsFile->findEndOfStatement( $open_paren + 1 ); } - } else if ( false === $this->short_open_tag_enabled && T_INLINE_HTML === $this->tokens[ $stackPtr ]['code'] ) { - // Skip if no PHP short_open_tag is in the string. + } elseif ( T_INLINE_HTML === $this->tokens[ $stackPtr ]['code'] ) { + // Skip if no PHP short_open_tag is found in the string. if ( false === strpos( $this->tokens[ $stackPtr ]['content'], '\S+|\[[^\]]+\]))*)[\s]*;?[\s]*\?\>/', $this->tokens[ $stackPtr ]['content'], $matches ) ) { - $this->phpcsFile->addError( 'Expected next thing to be an escaping function, not %s.', $stackPtr, 'OutputNotEscaped', $matches[1] ); + // Report on what is very likely a PHP short open echo tag outputting a variable. + if ( preg_match( '`\<\?\=[\s]*(\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?:(?:->\S+|\[[^\]]+\]))*)[\s]*;?[\s]*\?\>`', $this->tokens[ $stackPtr ]['content'], $matches ) > 0 ) { + $this->phpcsFile->addError( + 'Expected next thing to be an escaping function, not %s.', + $stackPtr, + 'OutputNotEscaped', + array( $matches[1] ) + ); return; } - // Throw warning in case the T_INLINE_HTML looks like a open_short_tag. - if ( false !== strpos( $this->tokens[ $stackPtr ]['content'], 'phpcsFile->addWarning( 'Possible use of PHP short open tag ( "unsafePrintingFunctions[ $function ] ) ) { - $error = $this->phpcsFile->addError( "Expected next thing to be an escaping function (like %s), not '%s'", $stackPtr, 'UnsafePrintingFunction', array( $this->unsafePrintingFunctions[ $function ], $function ) ); + $error = $this->phpcsFile->addError( + "Expected next thing to be an escaping function (like %s), not '%s'", + $stackPtr, + 'UnsafePrintingFunction', + array( $this->unsafePrintingFunctions[ $function ], $function ) + ); // If the error was reported, don't bother checking the function's arguments. if ( $error ) { diff --git a/WordPress/Tests/XSS/EscapeOutputUnitTest.php b/WordPress/Tests/XSS/EscapeOutputUnitTest.php index d3c7e5a8..41cb3a4b 100644 --- a/WordPress/Tests/XSS/EscapeOutputUnitTest.php +++ b/WordPress/Tests/XSS/EscapeOutputUnitTest.php @@ -64,9 +64,9 @@ public function getErrorList() { 206 => 1, 207 => 1, 212 => ( PHP_VERSION_ID < 50300 ) ? 1 : 0, // PHPCS on PHP 5.2 does not recognize T_NOWDOC. - 210 => 1, - 212 => 1, - 213 => 1, + 223 => 1, + 225 => 1, + 226 => 1, ); } // end getErrorList() @@ -77,14 +77,8 @@ public function getErrorList() { * @return array => */ public function getWarningList() { - $list = array(); + return array(); - // Adding Warning which is triggerred in case open_short_tag is set to Off. - if ( PHP_VERSION_ID < 50400 && false === (bool) ini_get( 'short_open_tag' ) ) { - $list[211] = 1; - } - - return $list; } } // End class. From e94726729f1eaf0829f9b2eff422f82bfb3091ad Mon Sep 17 00:00:00 2001 From: dixitadusara Date: Fri, 30 Jun 2017 10:53:42 +0530 Subject: [PATCH 092/282] Fix README.md Text changes --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f81ae2bf..8c3185b7 100644 --- a/README.md +++ b/README.md @@ -58,13 +58,13 @@ Running this command will: 3. Register WordPress standards in PHP_CodeSniffer configuration. 4. Make `phpcs` command available from `wpcs/vendor/bin`. -For convenience of using `phpcs` as global command you might want to add path to `wpcs/vendor/bin` directory to a `PATH` environment of your operating system. +For the convenience of using `phpcs` as global command, you might want to add path to `wpcs/vendor/bin` directory to a `PATH` environment of your operating system. ### Standalone 1. Install PHP_CodeSniffer by following its [installation instructions](https://github.com/squizlabs/PHP_CodeSniffer#installation) (via Composer, PEAR, or Git checkout). - Do ensure, if for example you're using [VVV](https://github.com/Varying-Vagrant-Vagrants/VVV), that PHP_CodeSniffer's version matches our [requirements](#requirements). + Do ensure, if for example, you're using [VVV](https://github.com/Varying-Vagrant-Vagrants/VVV), that PHP_CodeSniffer's version matches our [requirements](#requirements). 2. Clone WordPress standards repository: @@ -97,7 +97,7 @@ You should then see `WordPress-Core` et al listed when you run `phpcs -i`. ### Standards subsets -The project encompasses a super–set of the sniffs that the WordPress community may need. If you use the `WordPress` standard you will get all the checks. Some of them might be unnecessary for your environment, for example those specific to WordPress VIP coding requirements. +The project encompasses a super–set of the sniffs that the WordPress community may need. If you use the `WordPress` standard you will get all the checks. Some of them might be unnecessary for your environment, for example, those specific to WordPress VIP coding requirements. You can use the following as standard names when invoking `phpcs` to select sniffs, fitting your needs: @@ -125,7 +125,7 @@ The [PHPCompatibility](https://github.com/wimg/PHPCompatibility) ruleset comes h The [PHPCompatibility](https://github.com/wimg/PHPCompatibility) sniffs are designed to analyse your code for cross-PHP version compatibility. Install it as a separate ruleset and either run it separately against your code or add it to your custom ruleset. -Whichever way you run it, do make sure you set the `testVersion` to run the sniffs against. The `testVersion` determines for which PHP versions you will received compatibility information. The recommended setting for this at this moment is `5.2-7.1` to support the same PHP versions as WordPress Core supports. +Whichever way you run it, do make sure you set the `testVersion` to run the sniffs against. The `testVersion` determines for which PHP versions you will receive compatibility information. The recommended setting for this at this moment is `5.2-7.1` to support the same PHP versions as WordPress Core supports. For more information about setting the `testVersion`, see: * [PHPCompatibility: Using the compatibility sniffs](https://github.com/wimg/PHPCompatibility#using-the-compatibility-sniffs) From 848b7d84eeae9b72a3f6c01e1686f1564645aaaa Mon Sep 17 00:00:00 2001 From: dixitadusara Date: Fri, 30 Jun 2017 14:57:28 +0530 Subject: [PATCH 093/282] Fixed text as per suggestion --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8c3185b7..710d527c 100644 --- a/README.md +++ b/README.md @@ -58,13 +58,13 @@ Running this command will: 3. Register WordPress standards in PHP_CodeSniffer configuration. 4. Make `phpcs` command available from `wpcs/vendor/bin`. -For the convenience of using `phpcs` as global command, you might want to add path to `wpcs/vendor/bin` directory to a `PATH` environment of your operating system. +For the convenience of using `phpcs` as a global command, you may want to add the `wpcs/vendor/bin` path to a PATH environment in your operating system. ### Standalone 1. Install PHP_CodeSniffer by following its [installation instructions](https://github.com/squizlabs/PHP_CodeSniffer#installation) (via Composer, PEAR, or Git checkout). - Do ensure, if for example, you're using [VVV](https://github.com/Varying-Vagrant-Vagrants/VVV), that PHP_CodeSniffer's version matches our [requirements](#requirements). + Do ensure that PHP_CodeSniffer's version matches our requirements(#requirements), if, for example, you're using VVV(https://github.com/Varying-Vagrant-Vagrants/VVV). 2. Clone WordPress standards repository: From 03482460b4f23d487353c43dbfdc7924d41f02be Mon Sep 17 00:00:00 2001 From: JDGrimes Date: Fri, 30 Jun 2017 11:59:17 -0400 Subject: [PATCH 094/282] Remove wp_get_post_terms() et al. from VIP Restricted Functions Sniff These functions are now cached as of WordPress 4.7. Fixes #945 --- WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php | 11 ----------- WordPress/Tests/VIP/RestrictedFunctionsUnitTest.inc | 8 ++++---- WordPress/Tests/VIP/RestrictedFunctionsUnitTest.php | 4 ---- 3 files changed, 4 insertions(+), 19 deletions(-) diff --git a/WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php b/WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php index 0e86c306..cb58395a 100644 --- a/WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php +++ b/WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php @@ -168,17 +168,6 @@ public function getGroups() { ), ), - 'wp_get_post_terms' => array( - 'type' => 'error', - 'message' => '%s() is highly discouraged due to not being cached; please use get_the_terms() along with wp_list_pluck() to extract the IDs.', - 'functions' => array( - 'wp_get_post_terms', - 'wp_get_post_categories', - 'wp_get_post_tags', - 'wp_get_object_terms', - ), - ), - 'term_exists' => array( 'type' => 'error', 'message' => '%s() is highly discouraged due to not being cached; please use wpcom_vip_term_exists() instead.', diff --git a/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.inc b/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.inc index 981e04eb..2d2982c4 100644 --- a/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.inc +++ b/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.inc @@ -55,10 +55,10 @@ get_posts(); // Warning. wp_get_recent_posts(); // Warning. get_children(); // Warning. -wp_get_post_terms(); // Error. -wp_get_post_categories(); // Error. -wp_get_post_tags(); // Error. -wp_get_object_terms(); // Error. + + + + term_exists(); // Error. count_user_posts(); // Error. wp_old_slug_redirect(); // Error. diff --git a/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.php b/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.php index 169bff90..6789cbc5 100644 --- a/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.php +++ b/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.php @@ -37,10 +37,6 @@ public function getErrorList() { 50 => 1, 51 => 1, 52 => 1, - 58 => 1, - 59 => 1, - 60 => 1, - 61 => 1, 62 => 1, 63 => 1, 64 => 1, From a173ae736e7b508660e93b4abe38f8158eefb605 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Mon, 3 Jul 2017 14:24:23 +0200 Subject: [PATCH 095/282] Move `Squiz.PHP.EmbeddedPhp` from `Extra` to `Core` As the handbook has been adjusted, this sniff can now be legitimately placed in the Core ruleset. Fixes 1000 --- WordPress-Core/ruleset.xml | 16 ++++++++++++++++ WordPress-Extra/ruleset.xml | 9 --------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index 231d397d..3b3e10f1 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -103,6 +103,22 @@ Already covered by Squiz.Strings.DoubleQuoteUsage --> + + + + + + + + + + - - - - - - - - From 4f415c0941c0021f186242bc62733b667ecb93d7 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 4 Jul 2017 15:58:13 -0700 Subject: [PATCH 096/282] Fix markdown syntax for Travis CI link in readme TOC --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f9368dac..5cf6491e 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ + [Atom](#atom) + [Visual Studio](#visual-studio) * [Running your code through WPCS automatically using CI tools](#running-your-code-through-wpcs-automatically-using-ci-tools) - + [[Travis CI](https://travis-ci.org/)](#-travis-ci--https---travis-ciorg--) + + [Travis CI](#travis-ci) * [Fixing errors or whitelisting them](#fixing-errors-or-whitelisting-them) * [Contributing](#contributing) * [License](#license) From 24609cc71d6270ebc75c25ea8bf9431eb6ba4b92 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 9 Jul 2017 06:57:42 +0200 Subject: [PATCH 097/282] Fix fixer conflict between PEAR.FunctionCallSignature and WP.ArrayDeclarationSpacing Fixes 968 --- WordPress-Core/ruleset.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index 3b3e10f1..de2a1c2c 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -186,10 +186,10 @@ - 0 + 0 - 0 + 0 From cdcebdf4698a9328f2ad71cebcb36cef34b01045 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 9 Jul 2017 15:33:54 +0200 Subject: [PATCH 098/282] Add `PSR2.ControlStructures.SwitchDeclaration` to the `WordPress-Core` ruleset As proposed in https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/982#issuecomment-312607024 Also adds the newly added section + rules from the handbook which came out of the discussion in #982. Partially fixes 982 --- WordPress-Core/ruleset.xml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index de2a1c2c..4d1c6a7e 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -61,6 +61,14 @@ Also covers various single-line array whitespace issues. --> + + + + + + + @@ -205,6 +213,17 @@ + + + + + + + + @@ -213,17 +214,6 @@ - - - - - + /docroot/wp-admin/* /docroot/wp-includes/* /docroot/wp-*.php /docroot/index.php /docroot/xmlrpc.php /docroot/wp-content/plugins/* - *.twig /vendor/* + + /node_modules/* + + + *.min.js + + + +
      diff --git a/WordPress/Sniffs/Classes/ClassInstantiationSniff.php b/WordPress/Sniffs/Classes/ClassInstantiationSniff.php new file mode 100644 index 00000000..e2a646f5 --- /dev/null +++ b/WordPress/Sniffs/Classes/ClassInstantiationSniff.php @@ -0,0 +1,196 @@ +classname_tokens = PHP_CodeSniffer_Tokens::$emptyTokens; + $this->classname_tokens[ T_NS_SEPARATOR ] = T_NS_SEPARATOR; + $this->classname_tokens[ T_STRING ] = T_STRING; + $this->classname_tokens[ T_SELF ] = T_SELF; + $this->classname_tokens[ T_STATIC ] = T_STATIC; + $this->classname_tokens[ T_PARENT ] = T_PARENT; + $this->classname_tokens[ T_ANON_CLASS ] = T_ANON_CLASS; + // Classname in a variable. + $this->classname_tokens[ T_VARIABLE ] = T_VARIABLE; + $this->classname_tokens[ T_DOUBLE_COLON ] = T_DOUBLE_COLON; + $this->classname_tokens[ T_OBJECT_OPERATOR ] = T_OBJECT_OPERATOR; + $this->classname_tokens[ T_OPEN_SQUARE_BRACKET ] = T_OPEN_SQUARE_BRACKET; + $this->classname_tokens[ T_CLOSE_SQUARE_BRACKET ] = T_CLOSE_SQUARE_BRACKET; + + return array( + T_NEW, + T_STRING, // JS. + ); + } + + /** + * Processes this test, when one of its tokens is encountered. + * + * @param int $stackPtr The position of the current token in the stack. + * + * @return void + */ + public function process_token( $stackPtr ) { + // Make sure we have the right token, JS vs PHP. + if ( ( 'PHP' === $this->phpcsFile->tokenizerType && T_NEW !== $this->tokens[ $stackPtr ]['code'] ) + || ( 'JS' === $this->phpcsFile->tokenizerType + && ( T_STRING !== $this->tokens[ $stackPtr ]['code'] + || 'new' !== strtolower( $this->tokens[ $stackPtr ]['content'] ) ) ) + ) { + return; + } + + /* + * Check for new by reference used in PHP files. + */ + if ( 'PHP' === $this->phpcsFile->tokenizerType ) { + $prev_non_empty = $this->phpcsFile->findPrevious( + PHP_CodeSniffer_Tokens::$emptyTokens, + ($stackPtr - 1), + null, + true + ); + + if ( false !== $prev_non_empty && 'T_BITWISE_AND' === $this->tokens[ $prev_non_empty ]['type'] ) { + $this->phpcsFile->recordMetric( $stackPtr, 'Assigning new by reference', 'yes' ); + + $this->phpcsFile->addError( + 'Assigning the return value of new by reference is no longer supported by PHP.', + $stackPtr, + 'NewByReferenceFound' + ); + } else { + $this->phpcsFile->recordMetric( $stackPtr, 'Assigning new by reference', 'no' ); + } + } + + /* + * Check for parenthesis & correct placement thereof. + */ + $next_non_empty_after_class_name = $this->phpcsFile->findNext( + $this->classname_tokens, + ($stackPtr + 1), + null, + true, + null, + true + ); + + if ( false === $next_non_empty_after_class_name ) { + // Live coding. + return; + } + + // Walk back to the last part of the class name. + $has_comment = false; + for ( $classname_ptr = ( $next_non_empty_after_class_name - 1 ); $classname_ptr >= $stackPtr; $classname_ptr-- ) { + if ( ! isset( PHP_CodeSniffer_Tokens::$emptyTokens[ $this->tokens[ $classname_ptr ]['code'] ] ) ) { + // Prevent a false positive on variable variables, disregard them for now. + if ( $stackPtr === $classname_ptr ) { + return; + } + + break; + } + + if ( T_WHITESPACE !== $this->tokens[ $classname_ptr ]['code'] ) { + $has_comment = true; + } + } + + if ( T_OPEN_PARENTHESIS !== $this->tokens[ $next_non_empty_after_class_name ]['code'] ) { + $this->phpcsFile->recordMetric( $stackPtr, 'Object instantiation with parenthesis', 'no' ); + + $fix = $this->phpcsFile->addFixableError( + 'Parenthesis should always be used when instantiating a new object.', + $classname_ptr, + 'MissingParenthesis' + ); + + if ( true === $fix ) { + $this->phpcsFile->fixer->addContent( $classname_ptr, '()' ); + } + } else { + $this->phpcsFile->recordMetric( $stackPtr, 'Object instantiation with parenthesis', 'yes' ); + + if ( ( $next_non_empty_after_class_name - 1 ) !== $classname_ptr ) { + $this->phpcsFile->recordMetric( + $stackPtr, + 'Space between classname and parenthesis', + ( $next_non_empty_after_class_name - $classname_ptr ) + ); + + $error = 'There must be no spaces between the class name and the open parenthesis when instantiating a new object.'; + $error_code = 'SpaceBeforeParenthesis'; + + if ( false === $has_comment ) { + $fix = $this->phpcsFile->addFixableError( $error, $next_non_empty_after_class_name, $error_code ); + + if ( true === $fix ) { + $this->phpcsFile->fixer->beginChangeset(); + for ( $i = ( $next_non_empty_after_class_name - 1 ); $i > $classname_ptr; $i-- ) { + $this->phpcsFile->fixer->replaceToken( $i, '' ); + } + $this->phpcsFile->fixer->endChangeset(); + } + } else { + $fix = $this->phpcsFile->addError( $error, $next_non_empty_after_class_name, $error_code ); + } + } else { + $this->phpcsFile->recordMetric( $stackPtr, 'Space between classname and parenthesis', 0 ); + } + } + } // End process_token(). + +} // End class. diff --git a/WordPress/Tests/Classes/ClassInstantiationUnitTest.1.inc b/WordPress/Tests/Classes/ClassInstantiationUnitTest.1.inc new file mode 100644 index 00000000..a0e7e751 --- /dev/null +++ b/WordPress/Tests/Classes/ClassInstantiationUnitTest.1.inc @@ -0,0 +1,90 @@ +inline_diff_renderer(); +$b = ( new MyClass() )->my_function(); +$b = ( new MyClass() )::$property; + +class ClassA { + public static function get_instance() { + return new self(); + } + + public static function get_other_instance() { + return new static(); + } +} + +class ClassB extends ClassA { + public function get_parent_instance() { + return new parent(); + } +} + +// PHP 7: Anonymous classes. +$util->setLogger( new class() {} ); +$b = new class( 10 ) extends SomeClass implements SomeInterface {}; + + +/* + * Bad. + */ +$a = new MyClass; +$a = new $varHoldingClassName; +$a = new self::$transport[$cap_string]; +$renderer = new $this->inline_diff_renderer; +$b = ( new MyClass )->my_function(); +$b = ( new MyClass )::$property; + +class ClassA { + public static function get_instance() { + return new self; + } + + public static function get_other_instance() { + return new static; + } +} + +class ClassB extends ClassA { + public function get_parent_instance() { + return new parent; + } +} + +// PHP 7: Anonymous classes. +$util->setLogger( new class {} ); +$b = new class extends SomeClass implements SomeInterface {}; + + +// Test some non-typical spacing. +$renderer = new $this-> + inline_diff_renderer (); +$renderer = new $this-> // There can be a comment here. + inline_diff_renderer (); +$renderer = new $this-> + inline_diff_renderer /* or here */ (); +$a = new self :: $transport [ $cap_string ] (); + +$renderer = new $this-> + inline_diff_renderer; +$renderer = new $this-> // There can be a comment here. + inline_diff_renderer; +$renderer = new $this-> + inline_diff_renderer /* or here */ ; +$a = new self :: $transport [ $cap_string ]; + + +// Assigning new by reference. +$b = &new Foobar(); +$b = & new Foobar(); + + +// Currently not accounted for by the sniff, i.e. false negatives. +$a = new $$varHoldingClassName; +$a = new ${$varHoldingClassName}; diff --git a/WordPress/Tests/Classes/ClassInstantiationUnitTest.1.inc.fixed b/WordPress/Tests/Classes/ClassInstantiationUnitTest.1.inc.fixed new file mode 100644 index 00000000..f7bf26b2 --- /dev/null +++ b/WordPress/Tests/Classes/ClassInstantiationUnitTest.1.inc.fixed @@ -0,0 +1,90 @@ +inline_diff_renderer(); +$b = ( new MyClass() )->my_function(); +$b = ( new MyClass() )::$property; + +class ClassA { + public static function get_instance() { + return new self(); + } + + public static function get_other_instance() { + return new static(); + } +} + +class ClassB extends ClassA { + public function get_parent_instance() { + return new parent(); + } +} + +// PHP 7: Anonymous classes. +$util->setLogger( new class() {} ); +$b = new class( 10 ) extends SomeClass implements SomeInterface {}; + + +/* + * Bad. + */ +$a = new MyClass(); +$a = new $varHoldingClassName(); +$a = new self::$transport[$cap_string](); +$renderer = new $this->inline_diff_renderer(); +$b = ( new MyClass() )->my_function(); +$b = ( new MyClass() )::$property; + +class ClassA { + public static function get_instance() { + return new self(); + } + + public static function get_other_instance() { + return new static(); + } +} + +class ClassB extends ClassA { + public function get_parent_instance() { + return new parent(); + } +} + +// PHP 7: Anonymous classes. +$util->setLogger( new class() {} ); +$b = new class() extends SomeClass implements SomeInterface {}; + + +// Test some non-typical spacing. +$renderer = new $this-> + inline_diff_renderer(); +$renderer = new $this-> // There can be a comment here. + inline_diff_renderer(); +$renderer = new $this-> + inline_diff_renderer /* or here */ (); +$a = new self :: $transport [ $cap_string ](); + +$renderer = new $this-> + inline_diff_renderer(); +$renderer = new $this-> // There can be a comment here. + inline_diff_renderer(); +$renderer = new $this-> + inline_diff_renderer() /* or here */ ; +$a = new self :: $transport [ $cap_string ](); + + +// Assigning new by reference. +$b = &new Foobar(); +$b = & new Foobar(); + + +// Currently not accounted for by the sniff, i.e. false negatives. +$a = new $$varHoldingClassName; +$a = new ${$varHoldingClassName}; diff --git a/WordPress/Tests/Classes/ClassInstantiationUnitTest.2.inc b/WordPress/Tests/Classes/ClassInstantiationUnitTest.2.inc new file mode 100644 index 00000000..7b3038a5 --- /dev/null +++ b/WordPress/Tests/Classes/ClassInstantiationUnitTest.2.inc @@ -0,0 +1,17 @@ + => + */ + public function getErrorList( $testFile = '' ) { + + switch ( $testFile ) { + case 'ClassInstantiationUnitTest.1.inc': + return array( + 37 => 1, + 38 => 1, + 39 => 1, + 40 => 1, + 41 => 1, + 42 => 1, + 46 => 1, + 50 => 1, + 56 => 1, + 61 => 1, + 62 => 1, + 67 => 1, + 69 => 1, + 71 => 1, + 72 => 1, + 75 => 1, + 77 => 1, + 79 => 1, + 80 => 1, + 84 => 1, + 85 => 1, + ); + + case 'ClassInstantiationUnitTest.2.inc': + return array( + 16 => 1, + 17 => 1, + ); + + case 'ClassInstantiationUnitTest.js': + return array( + 2 => 1, + 3 => 1, + 4 => 1, + ); + + default: + return array(); + + } + } + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array(); + + } + +} // End class. From c294a3cc809d13b8f55d6c00b46bf5fd9eeb90d4 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 18 Jul 2017 18:45:05 +0200 Subject: [PATCH 108/282] :rocket: Build: only lint the PHP files once per PHP version. No need to do it for each build. --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index fb07a025..71f0c014 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ php: env: # Branch for patches against 2.x. `master` is now 3.x which WPCS is not (yet) compatible with. - - PHPCS_BRANCH=2.9 + - PHPCS_BRANCH=2.9 LINT=1 # Tagged release - PHPCS_BRANCH=2.9.0 @@ -32,9 +32,9 @@ matrix: sudo: required dist: trusty group: edge - env: PHPCS_BRANCH=2.9 + env: PHPCS_BRANCH=2.9 LINT=1 - php: nightly - env: PHPCS_BRANCH=2.9 + env: PHPCS_BRANCH=2.9 LINT=1 # Test PHP 5.3 with short_open_tags set to On (is Off by default) - php: 5.3 env: PHPCS_BRANCH=2.9 SHORT_OPEN_TAGS=true @@ -60,7 +60,7 @@ before_install: script: # Lint the PHP files against parse errors. - - if find . -name "*.php" -exec php -l {} \; | grep "^[Parse error|Fatal error]"; then exit 1; fi; + - if [[ "$LINT" == "1" ]]; then if find . -name "*.php" -exec php -l {} \; | grep "^[Parse error|Fatal error]"; then exit 1; fi; fi # Run the unit tests. - if [[ ${TRAVIS_PHP_VERSION:0:2} == "5." ]]; then phpunit --filter WordPress /tmp/phpcs/tests/AllTests.php; fi - if [[ ${TRAVIS_PHP_VERSION:0:2} != "5." ]]; then php $PHPUNIT_DIR/phpunit-5.7.17.phar --filter WordPress /tmp/phpcs/tests/AllTests.php; fi From a3c928b61904b7510a992e8c285673fe4f22924c Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 13 Jul 2017 19:11:58 +0200 Subject: [PATCH 109/282] Remove variable which is not used anymore. --- WordPress/Sniffs/Arrays/ArrayIndentationSniff.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php index 322ab6d1..329b9a98 100644 --- a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php @@ -264,12 +264,10 @@ public function process_token( $stackPtr ) { } $found_spaces_on_line2 = $this->get_indentation_size( $first_content_on_line2 ); - $line2_indent_diff = 0; $expected_spaces_on_line2 = $expected_spaces; if ( $found_spaces < $found_spaces_on_line2 ) { - $line2_indent_diff = ( $found_spaces_on_line2 - $found_spaces ); - $expected_spaces_on_line2 += $line2_indent_diff; + $expected_spaces_on_line2 += ( $found_spaces_on_line2 - $found_spaces ); } if ( $found_spaces_on_line2 !== $expected_spaces_on_line2 ) { From 0b3dd370e153d5913dae2857e775ae805d493ba7 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 13 Jul 2017 19:37:22 +0200 Subject: [PATCH 110/282] Using `changeset`s is only useful when several related changes are made in one go. --- WordPress/Sniffs/WP/I18nSniff.php | 2 -- .../ControlStructureSpacingSniff.php | 26 ------------------- 2 files changed, 28 deletions(-) diff --git a/WordPress/Sniffs/WP/I18nSniff.php b/WordPress/Sniffs/WP/I18nSniff.php index 65f99ca3..7a1bf7f5 100644 --- a/WordPress/Sniffs/WP/I18nSniff.php +++ b/WordPress/Sniffs/WP/I18nSniff.php @@ -477,9 +477,7 @@ protected function check_text( $context ) { if ( true === $fix ) { $fixed_str = preg_replace( $replace_regexes, $replacements, $content, 1 ); - $this->phpcsFile->fixer->beginChangeset(); $this->phpcsFile->fixer->replaceToken( $stack_ptr, $fixed_str ); - $this->phpcsFile->fixer->endChangeset(); } } diff --git a/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php b/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php index 01941afa..73691356 100644 --- a/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php +++ b/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php @@ -117,9 +117,7 @@ public function process_token( $stackPtr ) { $fix = $this->phpcsFile->addFixableError( $error, $stackPtr, 'NoSpaceAfterStructureOpen' ); if ( true === $fix ) { - $this->phpcsFile->fixer->beginChangeset(); $this->phpcsFile->fixer->addContent( $stackPtr, ' ' ); - $this->phpcsFile->fixer->endChangeset(); } } @@ -146,9 +144,7 @@ public function process_token( $stackPtr ) { $fix = $this->phpcsFile->addFixableError( $error, $scopeOpener, 'NoSpaceBetweenStructureColon' ); if ( true === $fix ) { - $this->phpcsFile->fixer->beginChangeset(); $this->phpcsFile->fixer->addContentBefore( $scopeOpener, ' ' ); - $this->phpcsFile->fixer->endChangeset(); } } } elseif ( 'forbidden' === $this->space_before_colon ) { @@ -158,9 +154,7 @@ public function process_token( $stackPtr ) { $fix = $this->phpcsFile->addFixableError( $error, ( $scopeOpener - 1 ), 'SpaceBetweenStructureColon' ); if ( true === $fix ) { - $this->phpcsFile->fixer->beginChangeset(); $this->phpcsFile->fixer->replaceToken( ( $scopeOpener - 1 ), '' ); - $this->phpcsFile->fixer->endChangeset(); } } } @@ -207,9 +201,7 @@ public function process_token( $stackPtr ) { ); if ( true === $fix ) { - $this->phpcsFile->fixer->beginChangeset(); $this->phpcsFile->fixer->replaceToken( ( $function_name_ptr + 1 ), '' ); - $this->phpcsFile->fixer->endChangeset(); } } } @@ -250,9 +242,7 @@ public function process_token( $stackPtr ) { $fix = $this->phpcsFile->addFixableError( $error, $stackPtr, 'SpaceBeforeClosureOpenParenthesis' ); if ( true === $fix ) { - $this->phpcsFile->fixer->beginChangeset(); $this->phpcsFile->fixer->replaceToken( ( $stackPtr + 1 ), '' ); - $this->phpcsFile->fixer->endChangeset(); } } } elseif ( @@ -268,9 +258,7 @@ public function process_token( $stackPtr ) { $fix = $this->phpcsFile->addFixableError( $error, $stackPtr, 'NoSpaceBeforeOpenParenthesis' ); if ( true === $fix ) { - $this->phpcsFile->fixer->beginChangeset(); $this->phpcsFile->fixer->addContent( $stackPtr, ' ' ); - $this->phpcsFile->fixer->endChangeset(); } } } @@ -289,9 +277,7 @@ public function process_token( $stackPtr ) { ); if ( true === $fix ) { - $this->phpcsFile->fixer->beginChangeset(); $this->phpcsFile->fixer->replaceToken( ( $stackPtr + 1 ), ' ' ); - $this->phpcsFile->fixer->endChangeset(); } } @@ -302,9 +288,7 @@ public function process_token( $stackPtr ) { $fix = $this->phpcsFile->addFixableError( $error, $stackPtr, 'NoSpaceAfterOpenParenthesis' ); if ( true === $fix ) { - $this->phpcsFile->fixer->beginChangeset(); $this->phpcsFile->fixer->addContent( $parenthesisOpener, ' ' ); - $this->phpcsFile->fixer->endChangeset(); } } elseif ( ( ' ' !== $this->tokens[ ( $parenthesisOpener + 1 ) ]['content'] && "\n" !== $this->tokens[ ( $parenthesisOpener + 1 ) ]['content'] @@ -321,9 +305,7 @@ public function process_token( $stackPtr ) { ); if ( true === $fix ) { - $this->phpcsFile->fixer->beginChangeset(); $this->phpcsFile->fixer->replaceToken( ( $parenthesisOpener + 1 ), ' ' ); - $this->phpcsFile->fixer->endChangeset(); } } } @@ -340,9 +322,7 @@ public function process_token( $stackPtr ) { $fix = $this->phpcsFile->addFixableError( $error, $parenthesisCloser, 'NoSpaceBeforeCloseParenthesis' ); if ( true === $fix ) { - $this->phpcsFile->fixer->beginChangeset(); $this->phpcsFile->fixer->addContentBefore( $parenthesisCloser, ' ' ); - $this->phpcsFile->fixer->endChangeset(); } } elseif ( ' ' !== $this->tokens[ ( $parenthesisCloser - 1 ) ]['content'] ) { $prevNonEmpty = $this->phpcsFile->findPrevious( PHP_CodeSniffer_Tokens::$emptyTokens, ( $parenthesisCloser - 1 ), null, true ); @@ -356,9 +336,7 @@ public function process_token( $stackPtr ) { ); if ( true === $fix ) { - $this->phpcsFile->fixer->beginChangeset(); $this->phpcsFile->fixer->replaceToken( ( $parenthesisCloser - 1 ), ' ' ); - $this->phpcsFile->fixer->endChangeset(); } } } @@ -371,9 +349,7 @@ public function process_token( $stackPtr ) { $fix = $this->phpcsFile->addFixableError( $error, $scopeOpener, 'NoSpaceAfterCloseParenthesis' ); if ( true === $fix ) { - $this->phpcsFile->fixer->beginChangeset(); $this->phpcsFile->fixer->addContentBefore( $scopeOpener, ' ' ); - $this->phpcsFile->fixer->endChangeset(); } } } @@ -412,9 +388,7 @@ public function process_token( $stackPtr ) { ); if ( true === $fix ) { - $this->phpcsFile->fixer->beginChangeset(); $this->phpcsFile->fixer->replaceToken( ( $parenthesisCloser + 1 ), ' ' ); - $this->phpcsFile->fixer->endChangeset(); } } } From bf9a149d46711d7c40c2a40b046139bc9967de3f Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 13 Jul 2017 19:37:56 +0200 Subject: [PATCH 111/282] Remove a superfluous `fixer` call where the fixer is not available. --- WordPress/Sniffs/Arrays/CommaAfterArrayItemSniff.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/WordPress/Sniffs/Arrays/CommaAfterArrayItemSniff.php b/WordPress/Sniffs/Arrays/CommaAfterArrayItemSniff.php index 0ec7f103..04b5d566 100644 --- a/WordPress/Sniffs/Arrays/CommaAfterArrayItemSniff.php +++ b/WordPress/Sniffs/Arrays/CommaAfterArrayItemSniff.php @@ -157,8 +157,6 @@ public function process_token( $stackPtr ) { for ( $i = $item['end']; $i > $last_content; $i-- ) { if ( T_WHITESPACE === $this->tokens[ $i ]['code'] ) { - $this->phpcsFile->fixer->replaceToken( $i, '' ); - if ( $this->tokens[ $i ]['content'] === $this->phpcsFile->eolChar ) { $newlines++; } else { From 338b671ecddb774f13e10e25601722bf1adf7f1d Mon Sep 17 00:00:00 2001 From: Stephen Edgar Date: Wed, 19 Jul 2017 15:10:50 +1000 Subject: [PATCH 112/282] Add the addon `libxml2-utils` to the PHP 5.5 bob --- .travis.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.travis.yml b/.travis.yml index 0ed11264..2c41f1d4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,9 @@ sudo: false dist: trusty +cache: + apt: true + language: - php @@ -24,6 +27,10 @@ matrix: # Run PHPCS against WPCS. I just picked to run it against 5.5. - php: 5.5 env: PHPCS_BRANCH=2.9 SNIFF=1 + addons: + apt: + packages: + - libxml2-utils # Run against PHPCS 3.0. I just picked to run it against 5.6. - php: 5.6 env: PHPCS_BRANCH=master From fc0d9c8379b2217fa11ad5331888246eb3fca2d8 Mon Sep 17 00:00:00 2001 From: JDGrimes Date: Wed, 19 Jul 2017 11:58:13 -0400 Subject: [PATCH 113/282] Improve detection of condition beginning in Yoda conditions sniff This sniff is supposed to loop over the left-hand side of the condition, checking for variables. If the left-hand side of the condition is not a variable, then it should not give an error about it. However, there were some issues with how we were detecting the beginning of the left-hand side of the condition. Take the following example code: ```php $sample = false !== strpos( $link, '%pagename%' ); // Ok. ``` This should not cause an issue, because the left-hand side of the condition is just `false`. However, we weren't detecting the beginning of the condition correctly; we'd end up checking right through the `=` assignment operator and seeing the `$sample` variable. As a result, an error would be given for this snippet. To correct this, we just need to take assignment operators into account when detecting the beginning of the condition. With this correction, we can also simplify some other code that was checking for a function call (or certain other tokens) within the condition, that would indicate it didn't need to be checked: - The `T_RETURN` token is actually an indicator of the beginning of the condition, so it should be moved to that check instead. - The `T_CONSTANT_ENCAPSED_STRING` token is no longer needed to be checked at all, because it was added to circumvent the bug that is now fixed by better detection of the beginning of the condition. - The `T_OPEN_PARENTHESIS` really shouldn't be needed, because the closing parenthesis will be detected first anyway (we are looping backward here). The `T_CLOSE_PARENTHESIS` is the only one that needs to stay, because of cases like this: ```php $sample = foo( $var ) !== strpos( $link, '%pagename%' ); // Ok. ``` Without the check for the closing parenthesis token, the `$var` parameter in the call to the `foo()` function would cause the condition to be flagged as needing to be a Yoda condition. Fixes #1036 --- WordPress/Sniffs/PHP/YodaConditionsSniff.php | 4 +++- WordPress/Tests/PHP/YodaConditionsUnitTest.inc | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/WordPress/Sniffs/PHP/YodaConditionsSniff.php b/WordPress/Sniffs/PHP/YodaConditionsSniff.php index eddeaa7a..bd7cfb76 100644 --- a/WordPress/Sniffs/PHP/YodaConditionsSniff.php +++ b/WordPress/Sniffs/PHP/YodaConditionsSniff.php @@ -46,6 +46,8 @@ public function process_token( $stackPtr ) { $beginners = PHP_CodeSniffer_Tokens::$booleanOperators; $beginners[] = T_IF; $beginners[] = T_ELSEIF; + $beginners[] = T_RETURN; + $beginners = array_merge( $beginners, PHP_CodeSniffer_Tokens::$assignmentTokens ); $beginning = $this->phpcsFile->findPrevious( $beginners, $stackPtr, null, false, null, true ); @@ -68,7 +70,7 @@ public function process_token( $stackPtr ) { } // If this is a function call or something, we are OK. - if ( in_array( $this->tokens[ $i ]['code'], array( T_CONSTANT_ENCAPSED_STRING, T_CLOSE_PARENTHESIS, T_OPEN_PARENTHESIS, T_RETURN ), true ) ) { + if ( T_CLOSE_PARENTHESIS === $this->tokens[ $i ]['code'] ) { return; } } diff --git a/WordPress/Tests/PHP/YodaConditionsUnitTest.inc b/WordPress/Tests/PHP/YodaConditionsUnitTest.inc index 5b2cf5e4..d89d9186 100644 --- a/WordPress/Tests/PHP/YodaConditionsUnitTest.inc +++ b/WordPress/Tests/PHP/YodaConditionsUnitTest.inc @@ -90,3 +90,9 @@ if ( $GLOBALS['wpdb']->num_rows === 0 ) {} // Bad. if ( $true == strtolower( $check ) ) {} // Bad. $update = 'yes' === strtolower( $this->from_post( 'update' ) ); // Ok. +$sample = false !== strpos( $link, '%pagename%' ); // Ok. +$sample = true !== strpos( $link, '%pagename%' ); // Ok. +$sample = null !== strpos( $link, '%pagename%' ); // Ok. +$sample = SOME_CONSTANT !== strpos( $link, '%pagename%' ); // Ok. +$sample = foo() !== strpos( $link, '%pagename%' ); // Ok. +$sample = foo( $var ) !== strpos( $link, '%pagename%' ); // Ok. From d55bfe651ecfab0e353bec590b0994aa628f7132 Mon Sep 17 00:00:00 2001 From: JDGrimes Date: Wed, 19 Jul 2017 14:16:18 -0400 Subject: [PATCH 114/282] Only build condition starters array once Improves performance by avoiding doing this every time we process a token, and also by avoiding use of the `array_merge()` function. --- WordPress/Sniffs/PHP/YodaConditionsSniff.php | 26 ++++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/WordPress/Sniffs/PHP/YodaConditionsSniff.php b/WordPress/Sniffs/PHP/YodaConditionsSniff.php index bd7cfb76..667ec80f 100644 --- a/WordPress/Sniffs/PHP/YodaConditionsSniff.php +++ b/WordPress/Sniffs/PHP/YodaConditionsSniff.php @@ -19,12 +19,28 @@ */ class WordPress_Sniffs_PHP_YodaConditionsSniff extends WordPress_Sniff { + /** + * The tokens that indicate the start of a condition. + * + * @since 0.12.0 + * + * @var array + */ + protected $condition_start_tokens; + /** * Returns an array of tokens this test wants to listen for. * * @return array */ public function register() { + + $this->condition_start_tokens = PHP_CodeSniffer_Tokens::$booleanOperators; + $this->condition_start_tokens += PHP_CodeSniffer_Tokens::$assignmentTokens; + $this->condition_start_tokens[ T_IF ] = T_IF; + $this->condition_start_tokens[ T_ELSEIF ] = T_ELSEIF; + $this->condition_start_tokens[ T_RETURN ] = T_RETURN; + return array( T_IS_EQUAL, T_IS_NOT_EQUAL, @@ -43,18 +59,12 @@ public function register() { */ public function process_token( $stackPtr ) { - $beginners = PHP_CodeSniffer_Tokens::$booleanOperators; - $beginners[] = T_IF; - $beginners[] = T_ELSEIF; - $beginners[] = T_RETURN; - $beginners = array_merge( $beginners, PHP_CodeSniffer_Tokens::$assignmentTokens ); - - $beginning = $this->phpcsFile->findPrevious( $beginners, $stackPtr, null, false, null, true ); + $start = $this->phpcsFile->findPrevious( $this->condition_start_tokens, $stackPtr, null, false, null, true ); $needs_yoda = false; // Note: going backwards! - for ( $i = $stackPtr; $i > $beginning; $i-- ) { + for ( $i = $stackPtr; $i > $start; $i-- ) { // Ignore whitespace. if ( isset( PHP_CodeSniffer_Tokens::$emptyTokens[ $this->tokens[ $i ]['code'] ] ) ) { From f1a07184a1e1e194ed566e7d528c8d96209c04f8 Mon Sep 17 00:00:00 2001 From: JDGrimes Date: Wed, 19 Jul 2017 14:27:33 -0400 Subject: [PATCH 115/282] Improve list of condition start tokens And more tests. - By adding `T_OPEN_PARENTHESIS` we can remove `T_IF` and `T_ELSEIF`, and at the same time take in additional structures, like `while` loops. - `T_CASE` is needed for better performance, because `case` statements don't have to have parenthesis around them. - `T_SEMICOLON` is needed for better performance for conditions within `for` loops. --- WordPress/Sniffs/PHP/YodaConditionsSniff.php | 5 ++-- .../Tests/PHP/YodaConditionsUnitTest.inc | 30 +++++++++++++++++++ .../Tests/PHP/YodaConditionsUnitTest.php | 4 +++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/WordPress/Sniffs/PHP/YodaConditionsSniff.php b/WordPress/Sniffs/PHP/YodaConditionsSniff.php index 667ec80f..7db9992f 100644 --- a/WordPress/Sniffs/PHP/YodaConditionsSniff.php +++ b/WordPress/Sniffs/PHP/YodaConditionsSniff.php @@ -37,9 +37,10 @@ public function register() { $this->condition_start_tokens = PHP_CodeSniffer_Tokens::$booleanOperators; $this->condition_start_tokens += PHP_CodeSniffer_Tokens::$assignmentTokens; - $this->condition_start_tokens[ T_IF ] = T_IF; - $this->condition_start_tokens[ T_ELSEIF ] = T_ELSEIF; + $this->condition_start_tokens[ T_CASE ] = T_CASE; $this->condition_start_tokens[ T_RETURN ] = T_RETURN; + $this->condition_start_tokens[ T_SEMICOLON ] = T_SEMICOLON; + $this->condition_start_tokens[ T_OPEN_PARENTHESIS ] = T_OPEN_PARENTHESIS; return array( T_IS_EQUAL, diff --git a/WordPress/Tests/PHP/YodaConditionsUnitTest.inc b/WordPress/Tests/PHP/YodaConditionsUnitTest.inc index d89d9186..86015042 100644 --- a/WordPress/Tests/PHP/YodaConditionsUnitTest.inc +++ b/WordPress/Tests/PHP/YodaConditionsUnitTest.inc @@ -96,3 +96,33 @@ $sample = null !== strpos( $link, '%pagename%' ); // Ok. $sample = SOME_CONSTANT !== strpos( $link, '%pagename%' ); // Ok. $sample = foo() !== strpos( $link, '%pagename%' ); // Ok. $sample = foo( $var ) !== strpos( $link, '%pagename%' ); // Ok. + +if ( $sample = false !== strpos( $link, '%pagename%' ) ) {} // Ok. +if ( $sample = ( false !== strpos( $link, '%pagename%' ) ) ) {} // Ok. +if ( ( $sample = false ) !== strpos( $link, '%pagename%' ) ) {} // Ok. + +switch ( true ) { + case $sample === 'something': // Bad. + // Do something. + break; + + case 'something' === $sample: // OK. + // Do something. + break; +} + +for ( $i = 0; $i !== 100; $i++ ) {} // Bad. +for ( $i = 0; 100 != $i; $i++ ) {} // OK. + +do { + // Something. +} while ( $sample === false ); // Bad. + +do { + // Something. +} while ( CONSTANT_A === $sample ); // OK. + +while ( $sample === false ) {} // Bad. +while ( false != $sample ) {} // OK. + +$a = ( $sample ) === 'yes'; // OK. diff --git a/WordPress/Tests/PHP/YodaConditionsUnitTest.php b/WordPress/Tests/PHP/YodaConditionsUnitTest.php index bdf50962..bc558ffc 100644 --- a/WordPress/Tests/PHP/YodaConditionsUnitTest.php +++ b/WordPress/Tests/PHP/YodaConditionsUnitTest.php @@ -35,6 +35,10 @@ public function getErrorList() { 84 => 1, 88 => 1, 90 => 1, + 105 => 1, + 114 => 1, + 119 => 1, + 125 => 1, ); } From 7323a6e4e1acce7b0cc7e6bfa9b38b2e70038761 Mon Sep 17 00:00:00 2001 From: JDGrimes Date: Wed, 19 Jul 2017 15:22:46 -0400 Subject: [PATCH 116/282] Better alignment --- WordPress/Sniffs/PHP/YodaConditionsSniff.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/WordPress/Sniffs/PHP/YodaConditionsSniff.php b/WordPress/Sniffs/PHP/YodaConditionsSniff.php index 7db9992f..8cf7e996 100644 --- a/WordPress/Sniffs/PHP/YodaConditionsSniff.php +++ b/WordPress/Sniffs/PHP/YodaConditionsSniff.php @@ -35,12 +35,14 @@ class WordPress_Sniffs_PHP_YodaConditionsSniff extends WordPress_Sniff { */ public function register() { - $this->condition_start_tokens = PHP_CodeSniffer_Tokens::$booleanOperators; - $this->condition_start_tokens += PHP_CodeSniffer_Tokens::$assignmentTokens; - $this->condition_start_tokens[ T_CASE ] = T_CASE; - $this->condition_start_tokens[ T_RETURN ] = T_RETURN; - $this->condition_start_tokens[ T_SEMICOLON ] = T_SEMICOLON; - $this->condition_start_tokens[ T_OPEN_PARENTHESIS ] = T_OPEN_PARENTHESIS; + $starters = PHP_CodeSniffer_Tokens::$booleanOperators; + $starters += PHP_CodeSniffer_Tokens::$assignmentTokens; + $starters[ T_CASE ] = T_CASE; + $starters[ T_RETURN ] = T_RETURN; + $starters[ T_SEMICOLON ] = T_SEMICOLON; + $starters[ T_OPEN_PARENTHESIS ] = T_OPEN_PARENTHESIS; + + $this->condition_start_tokens = $starters; return array( T_IS_EQUAL, From 532839ed994a26dfa3db9f46c625831efb96291c Mon Sep 17 00:00:00 2001 From: Ulrich Pogson Date: Thu, 20 Jul 2017 00:54:49 +0200 Subject: [PATCH 117/282] Check for deprecated parameters --- WordPress-Extra/ruleset.xml | 1 + .../Sniffs/WP/DeprecatedParametersSniff.php | 345 ++++++++++++++++++ .../Tests/WP/DeprecatedParametersUnitTest.inc | 66 ++++ .../Tests/WP/DeprecatedParametersUnitTest.php | 49 +++ 4 files changed, 461 insertions(+) create mode 100644 WordPress/Sniffs/WP/DeprecatedParametersSniff.php create mode 100644 WordPress/Tests/WP/DeprecatedParametersUnitTest.inc create mode 100644 WordPress/Tests/WP/DeprecatedParametersUnitTest.php diff --git a/WordPress-Extra/ruleset.xml b/WordPress-Extra/ruleset.xml index e7563a66..4b772309 100644 --- a/WordPress-Extra/ruleset.xml +++ b/WordPress-Extra/ruleset.xml @@ -64,6 +64,7 @@
      + diff --git a/WordPress/Sniffs/WP/DeprecatedParametersSniff.php b/WordPress/Sniffs/WP/DeprecatedParametersSniff.php new file mode 100644 index 00000000..c0419012 --- /dev/null +++ b/WordPress/Sniffs/WP/DeprecatedParametersSniff.php @@ -0,0 +1,345 @@ + + * + * + * + * + * + * @since 0.12.0 + * + * @var string WordPress version. + */ + public $minimum_supported_version = 4.5; + + /** + * Array of function, argument, and default value for deprecated argument. + * + * The functions are ordered alphabetically. + * Last updated for WordPress 4.8.0. + * + * @since 0.12.0 + * + * @var array Multidimensional array with parameter details. + * $target_functions = array( + * (string) Function name. => array( + * (int) Target parameter position, 1-based. => array( + * 'value' => (mixed) Expected default value for the + * deprecated parameter. Currently the default + * values: true, false, null, empty arrays and + * both empty and non-empty strings can be + * handled correctly by the process_parameters() + * method. When an additional default value is + * added, the relevant code in the + * process_parameters() method will need to be + * adjusted. + * 'version' => (int) The WordPress version when deprecated. + * ) + * ) + * ); + */ + protected $target_functions = array( + + 'add_option' => array( + 3 => array( + 'value' => '', + 'version' => '2.3.0', + ), + ), + 'comments_link' => array( + 1 => array( + 'value' => '', + 'version' => '0.72', + ), + 2 => array( + 'value' => '', + 'version' => '1.3.0', + ), + ), + 'comments_number' => array( + 4 => array( + 'value' => '', + 'version' => '1.3.0', + ), + ), + 'convert_chars' => array( + 2 => array( + 'value' => '', + 'version' => '0.71', + ), + ), + 'discover_pingback_server_uri' => array( + 2 => array( + 'value' => '', + 'version' => '2.7.0', + ), + ), + 'get_category_parents' => array( + 5 => array( + 'value' => array(), + 'version' => '4.8.0', + ), + ), + 'get_delete_post_link' => array( + 2 => array( + 'value' => '', + 'version' => '3.0.0', + ), + ), + 'get_last_updated' => array( + 1 => array( + 'value' => '', + 'version' => '3.0.0', // Was previously part of MU. + ), + ), + 'get_the_author' => array( + 1 => array( + 'value' => '', + 'version' => '2.1.0', + ), + ), + 'get_user_option' => array( + 3 => array( + 'value' => '', + 'version' => '2.3.0', + ), + ), + 'get_wp_title_rss' => array( + 1 => array( + 'value' => '–', + 'version' => '4.4.0', + ), + ), + 'is_email' => array( + 2 => array( + 'value' => false, + 'version' => '3.0.0', + ), + ), + 'load_plugin_textdomain' => array( + 2 => array( + 'value' => false, + 'version' => '2.7.0', + ), + ), + 'safecss_filter_attr' => array( + 2 => array( + 'value' => '', + 'version' => '2.8.1', + ), + ), + 'the_attachment_link' => array( + 3 => array( + 'value' => false, + 'version' => '2.5.0', + ), + ), + 'the_author' => array( + 1 => array( + 'value' => '', + 'version' => '2.1.0', + ), + 2 => array( + 'value' => true, + 'version' => '1.5.0', + ), + ), + 'the_author_posts_link' => array( + 1 => array( + 'value' => '', + 'version' => '2.1.0', + ), + ), + 'trackback_rdf' => array( + 1 => array( + 'value' => '', + 'version' => '2.5.0', + ), + ), + 'trackback_url' => array( + 1 => array( + 'value' => true, + 'version' => '2.5.0', + ), + ), + 'update_blog_option' => array( + 4 => array( + 'value' => null, + 'version' => '3.1.0', + ), + ), + 'update_blog_status' => array( + 4 => array( + 'value' => null, + 'version' => '3.1.0', + ), + ), + 'update_user_status' => array( + 4 => array( + 'value' => null, + 'version' => '3.0.2', + ), + ), + 'unregister_setting' => array( + 4 => array( + 'value' => '', + 'version' => '4.7.0', + ), + ), + 'wp_get_http_headers' => array( + 2 => array( + 'value' => false, + 'version' => '2.7.0', + ), + ), + 'wp_get_sidebars_widgets' => array( + 1 => array( + 'value' => true, + 'version' => '2.8.1', + ), + ), + 'wp_install' => array( + 5 => array( + 'value' => '', + 'version' => '2.6.0', + ), + ), + 'wp_new_user_notification' => array( + 2 => array( + 'value' => null, + 'version' => '4.3.1', + ), + ), + 'wp_notify_postauthor' => array( + 2 => array( + 'value' => null, + 'version' => '3.8.0', + ), + ), + 'wp_title_rss' => array( + 1 => array( + 'value' => '–', + 'version' => '4.4.0', + ), + ), + 'wp_upload_bits' => array( + 2 => array( + 'value' => '', + 'version' => '2.0.0', + ), + ), + 'xfn_check' => array( + 3 => array( + 'value' => '', + 'version' => '2.5.0', + ), + ), + + ); // End $target_functions. + + /** + * Process the parameters of a matched function. + * + * @since 0.12.0 + * + * @param int $stackPtr The position of the current token in the stack. + * @param array $group_name The name of the group which was matched. + * @param string $matched_content The token content (function name) which was matched. + * @param array $parameters Array with information about the parameters. + * + * @return void + */ + public function process_parameters( $stackPtr, $group_name, $matched_content, $parameters ) { + $paramCount = count( $parameters ); + foreach ( $this->target_functions[ $matched_content ] as $position => $parameter_args ) { + + // Check that number of parameters defined is not less than the position to check. + if ( $position > $paramCount ) { + break; + } + + // The list will need to updated if the default value is not supported. + switch ( $parameters[ $position ]['raw'] ) { + case 'true': + $matched_parameter = true; + break; + case 'false': + $matched_parameter = false; + break; + case 'null': + $matched_parameter = null; + break; + case 'array()': + case '[]': + $matched_parameter = array(); + break; + default: + $matched_parameter = $this->strip_quotes( $parameters[ $position ]['raw'] ); + break; + } + + if ( $parameter_args['value'] === $matched_parameter ) { + continue; + } + + $message = 'The parameter "%s" at position #%s of %s() has been deprecated since WordPress version %s.'; + $is_error = version_compare( $parameter_args['version'], $this->minimum_supported_version, '<' ); + $code = $this->string_to_errorcode( ucfirst( $matched_content ) . 'Param' . $position . 'Found' ); + + $data = array( + $parameters[ $position ]['raw'], + $position, + $matched_content, + $parameter_args['version'], + ); + + if ( isset( $parameter_args['value'] ) && $position < $paramCount ) { + $message .= ' Use "%s" instead.'; + $data[] = (string) $parameter_args['value']; + } else { + $message .= ' Instead do not pass the parameter.'; + } + + $this->addMessage( $message, $stackPtr, $is_error, $code, $data, 0 ); + } + } + +} diff --git a/WordPress/Tests/WP/DeprecatedParametersUnitTest.inc b/WordPress/Tests/WP/DeprecatedParametersUnitTest.inc new file mode 100644 index 00000000..ba7c2a9c --- /dev/null +++ b/WordPress/Tests/WP/DeprecatedParametersUnitTest.inc @@ -0,0 +1,66 @@ +wp_title_rss( 'siteurl' ); // Ok. +$theme_object->wp_title_rss( 'text_direction' ); // Ok. + +// All will give an Error even though they have a dynamic variable. + +wp_new_user_notification( '', $variable ); +wp_new_user_notification( '', function_name() ); +wp_new_user_notification( '', $this->method_name() ); + +// All will give an ERROR. The functions are ordered alphabetically. + +add_option( '', '', [] ); +add_option( '', '', 1.23 ); +add_option( '', '', 10 ); +add_option( '', '', false ); +add_option( '', '', 'deprecated' ); +comments_link( 'deprecated', 'deprecated' ); +comments_number( '', '', '', 'deprecated' ); +convert_chars( '', 'deprecated' ); +discover_pingback_server_uri( '', 'deprecated' ); +get_delete_post_link( '', 'deprecated' ); +get_last_updated( 'deprecated' ); +get_the_author( 'deprecated' ); +get_user_option( '', '', 'deprecated' ); +get_wp_title_rss( 'deprecated' ); +is_email( '', 'deprecated' ); +is_email( '', 'false' ); // False as a string not bool. +load_plugin_textdomain( '', 'deprecated' ); +safecss_filter_attr( '', 'deprecated' ); +the_attachment_link( '', '', 'deprecated' ); +the_author( 'deprecated', 'deprecated' ); +the_author_posts_link( 'deprecated' ); +trackback_rdf( 'deprecated' ); +trackback_url( 'deprecated' ); +update_blog_option( '', '', '', 'deprecated' ); +update_user_status( '', '', '', 'deprecated' ); +wp_get_http_headers( '', 'deprecated' ); +wp_get_sidebars_widgets( 'deprecated' ); +wp_install( '', '', '', '', 'deprecated' ); +wp_new_user_notification( '', 'deprecated' ); +wp_notify_postauthor( '', 'deprecated' ); +wp_notify_postauthor( '', 'null' ); // Null as a string not null. +wp_title_rss( 'deprecated' ); +wp_upload_bits( '', 'deprecated' ); +xfn_check( '', '', 'deprecated' ); + +// All will give an WARNING as they have been deprecated after WP 4.5. + +get_category_parents( '', '', '', '', array( 'deprecated') ); +unregister_setting( '', '', '', 'deprecated' ); diff --git a/WordPress/Tests/WP/DeprecatedParametersUnitTest.php b/WordPress/Tests/WP/DeprecatedParametersUnitTest.php new file mode 100644 index 00000000..07bebfd2 --- /dev/null +++ b/WordPress/Tests/WP/DeprecatedParametersUnitTest.php @@ -0,0 +1,49 @@ + => + */ + public function getErrorList() { + $errors = array_fill( 28, 34, 1 ); + + $errors[22] = 1; + $errors[23] = 1; + $errors[24] = 1; + + // Override number of errors. + $errors[33] = 2; + $errors[47] = 2; + + return $errors; + } + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array( + 65 => 1, + 66 => 1, + ); + } + +} // End class. From a557bd6daf580898224819493681a67340913903 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 20 Jul 2017 18:50:00 +0200 Subject: [PATCH 118/282] Changelog for the 0.12.0 release. --- CHANGELOG.md | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ff3e655..8e816e00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,75 @@ This projects adheres to [Semantic Versioning](http://semver.org/) and [Keep a C _Nothing yet._ +## [0.12.0] - 2017-07-21 + +### Added +- A default file encoding setting to the `WordPress-Core` ruleset. All files sniffed will now be regarded as `utf-8` by default. +- `WordPress.Arrays.ArrayIndentation` sniff to the `WordPress-Core` ruleset to verify - and auto-fix - the indentation of array items and the array closer for multi-line arrays. This replaces the (partial) indentation fixing contained within the `WordPress.Array.ArrayDeclarationSpacing` sniff. +- `WordPress.Arrays.CommaAfterArrayItem` sniff to the `WordPress-Core` ruleset to enforce that each array item is followed by a comma - except for the last item in a single-line array - and checks the spacing around the comma. This replaces (and improves) the checks which were previously included in the `WordPress.Arrays.ArrayDeclaration` sniff which were causing incorrect fixes and fixer conflicts. +- `WordPress.Functions.FunctionCallSignatureNoParams` sniff to the `WordPress-Core` ruleset to verify that function calls without parameters do not have any whitespace between the parentheses. +- `WordPress.WhiteSpace.DisallowInlineTabs` to the `WordPress-Core` ruleset to verify - and auto-fix - that spaces are used for mid-line alignment. +- `WordPress.WP.CapitalPDangit` sniff to the `WordPress-Core` ruleset to - where relevant - verify that `WordPress` is spelled correctly. For misspellings in text strings and comment text, the sniff can auto-fix violations. +- `Squiz.Classes.SelfMemberReference` whitespace related checks to the `WordPress-Core` ruleset and the additional check for using `self` rather than a FQN to the `WordPress-Extra` ruleset. +- `Squiz.PHP.EmbeddedPhp` sniff to the `WordPress-Core` ruleset to check PHP code embedded within HTML blocks. +- `PSR2.ControlStructures.SwitchDeclaration` to the `WordPress-Core` ruleset to check for the correct layout of `switch` control structures. +- `WordPress.Classes.ClassInstantion` sniff to the `WordPress-Extra` ruleset to detect - and auto-fix - missing parentheses on object instantiation and superfluous whitespace in PHP and JS files. The sniff will also detect `new` being assigned by reference. +- `WordPress.CodeAnalysis.EmptyStatement` sniff to the `WordPress-Extra` ruleset to detect - and auto-fix - superfluous semi-colons and empty PHP open-close tag combinations. +- `WordPress.NamingConventions.PrefixAllGlobals` sniff to the `WordPress-Extra` ruleset to verify that all functions, classes, interfaces, traits, variables, constants and hook names which are declared/defined in the global namespace are prefixed with one of the prefixes provided via a custom property or via the command line. + To activate this sniff, [one or more allowed prefixes should be provided to the sniff](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#naming-conventions-prefix-everything-in-the-global-namespace). This can be done using a custom ruleset or via the command line. + PHP superglobals and WP global variables are exempt from variable name prefixing. Deprecated hook names will also be disregarded when non-prefixed. Back-fills for known native PHP functionality is also accounted for. + For verified exceptions, [unprefixed code can be whitelisted](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Whitelisting-code-which-flags-errors#non-prefixed-functionclassvariableconstant-in-the-global-namespace). + Code in unit test files is automatically exempt from this sniff. +- `WordPress.WP.DeprecatedClasses` sniff to the `WordPress-Extra` ruleset to detect usage of deprecated WordPress classes. +- `WordPress.WP.DeprecatedParameters` sniff to the `WordPress-Extra` ruleset to detect deprecated parameters being passed to WordPress functions with a value other than the expected default. +- The `sanitize_textarea_field()` function to the `sanitizingFunctions` list used by the `WordPress.CSRF.NonceVerification`, `WordPress.VIP.ValidatedSanitizedInput` and `WordPress.XSS.EscapeOutput` sniffs. +- The `find_array_open_closer()` utility method to the `WordPress_Sniff` class. +- Information about setting `installed_paths` using a custom ruleset to the Readme. +- Additional support links to the `composer.json` file. +- Support for Composer PHPCS plugins which sort out the `installed_paths` setting. +- Linting and code-style check of the XML ruleset files provided by WPCS. + +### Changed +- The minimum required PHP_CodeSniffer version to 2.9.0 (was 2.8.1). **Take note**: PHPCS 3.x is not (yet) supported. The next release is expected to fix that. +- Improved support for detecting issues in code using heredoc and/or nowdoc syntax. +- Improved sniff efficiency, precision and performance for a number of sniffs. +- Updated a few sniffs to take advantage of new features and fixes which are included in PHP_CodeSniffer 2.9.0. +- `WordPress.Files.Filename`: The "file name mirrors the class name prefixed with 'class'" check for PHP files containing a class will no longer be applied to typical unit test classes, i.e. for classes which extend `WP_UnitTestCase`, `PHPUnit_Framework_TestCase` and `PHPUnit\Framework\TestCase`. Additional test case base classes can be passed to the sniff using the new [`custom_test_class_whitelist` property](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#custom-unit-test-classes). +- The `WordPress.Files.FileName` sniff allows now for more theme-specific template hierarchy based file name exceptions. +- The whitelist flag for the `WordPress.VIP.SlowQuery` sniff was `tax_query` which was unintuitive. This has now been changed to `slow query` to be in line with other whitelist flags. +- The `WordPress.WhiteSpace.OperatorSpacing` sniff will now ignore operator spacing within `declare()` statements. +- The `WordPress.WhiteSpace.OperatorSpacing` sniff now extends the upstream `Squiz.WhiteSpace.OperatorSpacing` sniff for improved results and will now also examine the spacing around ternary operators and logical (`&&`, `||`) operators. +- The `WordPress.WP.DeprecatedFunctions` sniff will now detect functions deprecated in WP 4.7 and 4.8. Additionally, a number of other deprecated functions which were previously not being detected have been added to the sniff and for a number of functions the "alternative" for the deprecated function has been added/improved. +- The `WordPress.XSS.EscapeOutput` sniff will now also detect unescaped output when the short open echo tags ` Date: Fri, 21 Jul 2017 02:43:24 +0200 Subject: [PATCH 119/282] Unit tests: Prevent bleed through between unit tests. --- .../Tests/Arrays/ArrayAssignmentRestrictionsUnitTest.php | 8 ++++++++ WordPress/Tests/DB/RestrictedClassesUnitTest.php | 8 ++++++++ .../Tests/Variables/VariableRestrictionsUnitTest.php | 8 ++++++++ WordPress/Tests/WP/I18nUnitTest.php | 8 ++++++++ 4 files changed, 32 insertions(+) diff --git a/WordPress/Tests/Arrays/ArrayAssignmentRestrictionsUnitTest.php b/WordPress/Tests/Arrays/ArrayAssignmentRestrictionsUnitTest.php index d4d82e92..f219b3a9 100644 --- a/WordPress/Tests/Arrays/ArrayAssignmentRestrictionsUnitTest.php +++ b/WordPress/Tests/Arrays/ArrayAssignmentRestrictionsUnitTest.php @@ -33,6 +33,14 @@ protected function setUp() { ); } + /** + * Reset the $groups property. + */ + protected function tearDown() { + WordPress_AbstractArrayAssignmentRestrictionsSniff::$groups = array(); + parent::tearDown(); + } + /** * Returns the lines where errors should occur. * diff --git a/WordPress/Tests/DB/RestrictedClassesUnitTest.php b/WordPress/Tests/DB/RestrictedClassesUnitTest.php index bef641cf..94a8adef 100644 --- a/WordPress/Tests/DB/RestrictedClassesUnitTest.php +++ b/WordPress/Tests/DB/RestrictedClassesUnitTest.php @@ -37,6 +37,14 @@ protected function setUp() { ); } + /** + * Reset the $groups property. + */ + protected function tearDown() { + WordPress_AbstractFunctionRestrictionsSniff::$unittest_groups = array(); + parent::tearDown(); + } + /** * Skip this test on PHP 5.2 as otherwise testing the namespace resolving would fail. * diff --git a/WordPress/Tests/Variables/VariableRestrictionsUnitTest.php b/WordPress/Tests/Variables/VariableRestrictionsUnitTest.php index 354ab051..4a2c217c 100644 --- a/WordPress/Tests/Variables/VariableRestrictionsUnitTest.php +++ b/WordPress/Tests/Variables/VariableRestrictionsUnitTest.php @@ -57,6 +57,14 @@ protected function setUp() { ); } + /** + * Reset the $groups property. + */ + protected function tearDown() { + WordPress_AbstractVariableRestrictionsSniff::$groups = array(); + parent::tearDown(); + } + /** * Returns the lines where errors should occur. * diff --git a/WordPress/Tests/WP/I18nUnitTest.php b/WordPress/Tests/WP/I18nUnitTest.php index a2864005..a2de4531 100644 --- a/WordPress/Tests/WP/I18nUnitTest.php +++ b/WordPress/Tests/WP/I18nUnitTest.php @@ -23,6 +23,14 @@ protected function setUp() { PHP_CodeSniffer::setConfigData( 'text_domain', 'my-slug,default', true ); } + /** + * Reset the $groups property. + */ + protected function tearDown() { + PHP_CodeSniffer::setConfigData( 'text_domain', null, true ); + parent::tearDown(); + } + /** * Returns the lines where errors should occur. * From 06d67332dd73654e40f2f5063df9dd90f85157a4 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 22 Jul 2017 00:09:14 +0200 Subject: [PATCH 120/282] Remove ArrayDeclaration sniff: move checks for spacing before and between parentheses #### `WordPress.Arrays.ArrayDeclaration.SpaceAfterKeyword` This check has been moved to the `ArrayDeclarationSpacing` sniff. While doing this, I also discovered a bug in the upstream code (which we were using). While the specific situation is quite obscure, it should still be addressed, so this has been fixed in the new check in `ArrayDeclarationSpacing` and I've also reported it upstream squizlabs/PHP_CodeSniffer/issues/1570 #### `WordPress.Arrays.ArrayDeclaration.SpaceInEmptyArray` This check has been moved to the `ArrayDeclarationSpacing` sniff. --- .../Arrays/ArrayDeclarationSpacingSniff.php | 59 ++++++++++++++++++- .../ArrayDeclarationSpacingUnitTest.inc | 33 +++++++++++ .../ArrayDeclarationSpacingUnitTest.inc.fixed | 31 ++++++++++ .../ArrayDeclarationSpacingUnitTest.php | 11 +++- 4 files changed, 130 insertions(+), 4 deletions(-) diff --git a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php index 06c18ea0..17ea100e 100644 --- a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php @@ -13,6 +13,8 @@ * WordPress specific checks which are not covered by the `WordPress.Arrays.ArrayDeclaration`/ * `Squiz.Arrays.ArrayDeclaration` sniff. * + * - Check for no space between array keyword and array opener. + * - Check for no space between the parentheses of an empty array. * - Checks for one space after the array opener / before the array closer in single-line arrays. * - Checks that associative arrays are multi-line. * @@ -79,10 +81,63 @@ public function process_token( $stackPtr ) { $closer = $array_open_close['closer']; unset( $array_open_close ); - // This array is empty, so the below checks aren't necessary. - if ( ( $opener + 1 ) === $closer ) { + /* + * Long arrays only: Check for space between the array keyword and the open parenthesis. + */ + if ( T_ARRAY === $this->tokens[ $stackPtr ]['code'] ) { + + if ( ( $stackPtr + 1 ) !== $opener ) { + $error = 'There must be no space between the "array" keyword and the opening parenthesis'; + $error_code = 'SpaceAfterKeyword'; + + $nextNonWhitespace = $this->phpcsFile->findNext( T_WHITESPACE, ( $stackPtr + 1 ), ( $opener + 1 ), true ); + if ( $nextNonWhitespace !== $opener ) { + // Don't auto-fix: Something other than whitespace found between keyword and open parenthesis. + $this->phpcsFile->addError( $error, $stackPtr, $error_code ); + } else { + + $fix = $this->phpcsFile->addFixableError( $error, $stackPtr, $error_code ); + + if ( true === $fix ) { + $this->phpcsFile->fixer->beginChangeset(); + for ( $i = ( $stackPtr + 1 ); $i < $opener; $i++ ) { + $this->phpcsFile->fixer->replaceToken( $i, '' ); + } + $this->phpcsFile->fixer->endChangeset(); + unset( $i ); + } + } + unset( $error, $error_code, $nextNonWhitespace, $fix ); + } + } + + /* + * Check for empty arrays. + */ + $nextNonWhitespace = $this->phpcsFile->findNext( T_WHITESPACE, ( $opener + 1 ), ( $closer + 1 ), true ); + if ( $nextNonWhitespace === $closer ) { + + if ( ( $opener + 1 ) !== $closer ) { + $fix = $this->phpcsFile->addFixableError( + 'Empty array declaration must have no space between the parentheses', + $stackPtr, + 'SpaceInEmptyArray' + ); + + if ( true === $fix ) { + $this->phpcsFile->fixer->beginChangeset(); + for ( $i = ( $opener + 1 ); $i < $closer; $i++ ) { + $this->phpcsFile->fixer->replaceToken( $i, '' ); + } + $this->phpcsFile->fixer->endChangeset(); + unset( $i ); + } + } + + // This array is empty, so the below checks aren't necessary. return; } + unset( $nextNonWhitespace ); // We're only interested in single-line arrays. if ( $this->tokens[ $opener ]['line'] !== $this->tokens[ $closer ]['line'] ) { diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc index fbdc7574..c61818b8 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc @@ -27,3 +27,36 @@ $bad = array( 'key1' => 'value1', /* comment */ 'key2' => 'value2' ); // Bad. // Test for (not) fixing non-associative array with a nested associative array which *will* be fixed. $bad = array( 'value1', 'value2', [ 'sub1' => 1, 'sub2' => 2 ], 'value4' ); // Bad. + +/* + * Test spacing between array keyword and open parenthesis. + */ +$a = array(); // OK. +$b = array (); // Bad. +$train = array +( + true, + 'aaa' +); // Bad - space between keyword and opener. + +$a = array +// Bad. +( 'a', 'b' ); + +$a = array /* Bad. */ ( 'a', 'b' ); + +/* + * Tests for empty array with space between parentheses. + */ +// OK. +$a = array(); +$value = array( /* comment */ ); +$x = array( + // comment + ); + +// Bad. +$value = array ( ); +$value = array( ); +$x = array( + ); diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed index a514cde1..c2a6a615 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed @@ -52,3 +52,34 @@ $bad = array( $bad = array( 'value1', 'value2', [ 'sub1' => 1, 'sub2' => 2 ], 'value4' ); // Bad. + +/* + * Test spacing between array keyword and open parenthesis. + */ +$a = array(); // OK. +$b = array(); // Bad. +$train = array( + true, + 'aaa' +); // Bad - space between keyword and opener. + +$a = array +// Bad. +( 'a', 'b' ); + +$a = array /* Bad. */ ( 'a', 'b' ); + +/* + * Tests for empty array with space between parentheses. + */ +// OK. +$a = array(); +$value = array( /* comment */ ); +$x = array( + // comment + ); + +// Bad. +$value = array(); +$value = array(); +$x = array(); diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php index dd4e6ce2..fa7b95a1 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php @@ -22,8 +22,8 @@ class WordPress_Tests_Arrays_ArrayDeclarationSpacingUnitTest extends AbstractSni */ public function getErrorList() { return array( - 5 => 2, - 8 => 2, + 5 => 2, + 8 => 2, 10 => 1, 13 => 4, 17 => 2, @@ -31,6 +31,13 @@ public function getErrorList() { 23 => 1, 26 => 1, 29 => 1, + 35 => 1, + 36 => 1, + 42 => 1, + 46 => 1, + 59 => 2, + 60 => 1, + 61 => 1, ); } From 2a9fd60b98807381a62868ddc30944a6b0407e2b Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 22 Jul 2017 00:11:54 +0200 Subject: [PATCH 121/282] Remove ArrayDeclaration sniff: move checks for array item/closing brace on new line #### `WordPress.Arrays.ArrayDeclaration.CloseBraceNewLine` This check has been moved to the `ArrayDeclarationSpacing` sniff. #### `WordPress.Arrays.ArrayDeclaration.FirstIndexNoNewline/FirstValueNoNewline/IndexNoNewline/ValueNoNewline` These checks have been moved to the `ArrayDeclarationSpacing` sniff and merged into one. I don't see any particular added value in having different error codes for the first line and subsequent lines, nor dependent on whether the array is associative or not. Includes some adjustments to the unit test case `fixed` file to account for these fixes being made to existing unit test cases. --- .../Arrays/ArrayDeclarationSpacingSniff.php | 139 +++++++++++++++++- .../ArrayDeclarationSpacingUnitTest.inc | 38 ++++- .../ArrayDeclarationSpacingUnitTest.inc.fixed | 85 +++++++++-- .../ArrayDeclarationSpacingUnitTest.php | 9 ++ 4 files changed, 256 insertions(+), 15 deletions(-) diff --git a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php index 17ea100e..b42646f1 100644 --- a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php @@ -17,6 +17,8 @@ * - Check for no space between the parentheses of an empty array. * - Checks for one space after the array opener / before the array closer in single-line arrays. * - Checks that associative arrays are multi-line. + * - Checks that each array item in a multi-line array starts on a new line. + * - Checks that the array closer in a multi-line array is on a new line. * * @link https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#indentation * @@ -139,11 +141,27 @@ public function process_token( $stackPtr ) { } unset( $nextNonWhitespace ); - // We're only interested in single-line arrays. - if ( $this->tokens[ $opener ]['line'] !== $this->tokens[ $closer ]['line'] ) { - return; + // Pass off to either the single line or multi-line array analysis. + if ( $this->tokens[ $opener ]['line'] === $this->tokens[ $closer ]['line'] ) { + $this->process_single_line_array( $stackPtr, $opener, $closer ); + } else { + $this->process_multi_line_array( $stackPtr, $opener, $closer ); } + } + /** + * Process a single-line array. + * + * @since 0.13.0 The actual checks contained in this method used to + * be in the `process()` method. + * + * @param int $stackPtr The position of the current token in the stack. + * @param int $opener The position of the array opener. + * @param int $closer The position of the array closer. + * + * @return void + */ + protected function process_single_line_array( $stackPtr, $opener, $closer ) { /* * Check that associative arrays are always multi-line. */ @@ -219,7 +237,7 @@ public function process_token( $stackPtr ) { $this->phpcsFile->fixer->endChangeset(); } - // No need to check for spacing around parentheses as this array should be multi-line. + // No need to check for spacing around opener/closer as this array should be multi-line. return; } } @@ -279,4 +297,117 @@ public function process_token( $stackPtr ) { } } + /** + * Process a multi-line array. + * + * @since 0.13.0 The actual checks contained in this method used to + * be in the `ArrayDeclaration` sniff. + * + * @param int $stackPtr The position of the current token in the stack. + * @param int $opener The position of the array opener. + * @param int $closer The position of the array closer. + * + * @return void + */ + protected function process_multi_line_array( $stackPtr, $opener, $closer ) { + /* + * Check that the closing bracket is on a new line. + */ + $last_content = $this->phpcsFile->findPrevious( T_WHITESPACE, ( $closer - 1 ), $opener, true ); + if ( false !== $last_content + && $this->tokens[ $last_content ]['line'] === $this->tokens[ $closer ]['line'] + ) { + $fix = $this->phpcsFile->addFixableError( + 'Closing parenthesis of array declaration must be on a new line', + $closer, + 'CloseBraceNewLine' + ); + if ( true === $fix ) { + $this->phpcsFile->fixer->beginChangeset(); + + if ( $last_content < ( $closer - 1 ) + && T_WHITESPACE === $this->tokens[ ( $closer - 1 ) ]['code'] + ) { + // Remove whitespace which would otherwise becoming trailing + // (as it gives problems with the fixed file). + $this->phpcsFile->fixer->replaceToken( ( $closer - 1 ), '' ); + } + + $this->phpcsFile->fixer->addNewlineBefore( $closer ); + $this->phpcsFile->fixer->endChangeset(); + } + } + + /* + * Check that each array item starts on a new line. + */ + $array_items = $this->get_function_call_parameters( $stackPtr ); + $end_of_last_item = $opener; + + foreach ( $array_items as $item ) { + $end_of_this_item = ( $item['end'] + 1 ); + + // Find the line on which the item starts. + $first_content = $this->phpcsFile->findNext( + array( T_WHITESPACE, T_DOC_COMMENT_WHITESPACE ), + $item['start'], + $end_of_this_item, + true + ); + + // Ignore comments after array items if the next real content starts on a new line. + if ( T_COMMENT === $this->tokens[ $first_content ]['code'] ) { + $next = $this->phpcsFile->findNext( + array( T_WHITESPACE, T_DOC_COMMENT_WHITESPACE ), + ( $first_content + 1 ), + $end_of_this_item, + true + ); + + if ( false === $next ) { + // Shouldn't happen, but just in case. + $end_of_last_item = $end_of_this_item; + continue; + } + + if ( $this->tokens[ $next ]['line'] !== $this->tokens[ $first_content ]['line'] ) { + $first_content = $next; + } + } + + if ( false === $first_content ) { + // Shouldn't happen, but just in case. + $end_of_last_item = $end_of_this_item; + continue; + } + + if ( $this->tokens[ $end_of_last_item ]['line'] === $this->tokens[ $first_content ]['line'] ) { + + $fix = $this->phpcsFile->addFixableError( + 'Each item in a multi-line array must be on a new line', + $first_content, + 'ArrayItemNoNewLine' + ); + + if ( true === $fix ) { + + $this->phpcsFile->fixer->beginChangeset(); + + if ( $item['start'] <= ( $first_content - 1 ) + && T_WHITESPACE === $this->tokens[ ( $first_content - 1 ) ]['code'] + ) { + // Remove whitespace which would otherwise becoming trailing + // (as it gives problems with the fixed file). + $this->phpcsFile->fixer->replaceToken( ( $first_content - 1 ), '' ); + } + + $this->phpcsFile->fixer->addNewlineBefore( $first_content ); + $this->phpcsFile->fixer->endChangeset(); + } + } + + $end_of_last_item = $end_of_this_item; + } + } + } // End class. diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc index c61818b8..6acbfc00 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc @@ -25,7 +25,7 @@ $bad = array( // Test for fixing associative arrays with comments between values. $bad = array( 'key1' => 'value1', /* comment */ 'key2' => 'value2' ); // Bad. -// Test for (not) fixing non-associative array with a nested associative array which *will* be fixed. +// Test for fixing non-associative array with a nested associative array which *will* be fixed. $bad = array( 'value1', 'value2', [ 'sub1' => 1, 'sub2' => 2 ], 'value4' ); // Bad. /* @@ -60,3 +60,39 @@ $value = array ( ); $value = array( ); $x = array( ); + +/* + * Tests for multi-line arrays - closing brace on new line + array items each on new line. + */ +// OK. +$value = array( + 1, + 2, /* Comment. */ + 3, +); + +$value = array( + 1 => $one, + 2 => $two, // Comment. + 3 => $three, // Comment. +); + +// Bad. +$value = array(1, + 2 , 3 , +); + +$value = array(1 => $one, + 2 => $two , /* Comment. */ 3 => $three , ); + +$value = array( + '1'=> TRUE, FALSE, '3' => 'aaa',); + +$x = array('name' => 'test', + ); + +$foo = array(1 +, 2); + +$fields = array( + 'value' => 'type'); diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed index c2a6a615..d48bcf31 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed @@ -8,7 +8,8 @@ $query_vars = array( 'food' ); // Bad, no spaces after opening and before closin $test = array( 1, 2 ); $bad = array( -'key' => 'value' ); // Bad, each value of an associative array should start on a new line. +'key' => 'value' +); // Bad, each value of an associative array should start on a new line. // Test for fixing nested associative arrays. $bad = array( @@ -16,11 +17,15 @@ array( 'key1' => 'value1', 'key2' => [ 'sub1' => 1, -'sub2' => 2] ), +'sub2' => 2 +] +), $key3 => 'value3', [ 'value4', -10 => 'value5', ] ); // Bad. +10 => 'value5', +] +); // Bad. // Test for fixing mixed single & multi-line nested associative arrays. $bad = array( @@ -28,11 +33,14 @@ $bad = array( 'key1' => 'value1', array( 'sub1' => 1, -'sub2' => 2,)), +'sub2' => 2, +) +), $key3 => 'value3', [ 'value4', -10 => 'value5' ] +10 => 'value5' +] ); // Bad. // Test for fixing associative arrays with multiple values & line indented with whitespace. @@ -41,17 +49,25 @@ array( 'key2' => 'value2', $key3 => 'value3', 'value4', -10 => 'value5' ); // Bad. +10 => 'value5' +); // Bad. // Test for fixing associative arrays with comments between values. $bad = array( 'key1' => 'value1', /* comment */ -'key2' => 'value2' ); // Bad. +'key2' => 'value2' +); // Bad. -// Test for (not) fixing non-associative array with a nested associative array which *will* be fixed. -$bad = array( 'value1', 'value2', [ +// Test for fixing non-associative array with a nested associative array which *will* be fixed. +$bad = array( +'value1', +'value2', +[ 'sub1' => 1, -'sub2' => 2 ], 'value4' ); // Bad. +'sub2' => 2 +], +'value4' +); // Bad. /* * Test spacing between array keyword and open parenthesis. @@ -83,3 +99,52 @@ $x = array( $value = array(); $value = array(); $x = array(); + +/* + * Tests for multi-line arrays - closing brace on new line + array items each on new line. + */ +// OK. +$value = array( + 1, + 2, /* Comment. */ + 3, +); + +$value = array( + 1 => $one, + 2 => $two, // Comment. + 3 => $three, // Comment. +); + +// Bad. +$value = array( +1, + 2 , +3 , +); + +$value = array( +1 => $one, + 2 => $two , +/* Comment. */ 3 => $three , +); + +$value = array( + '1'=> TRUE, +FALSE, +'3' => 'aaa', +); + +$x = array( +'name' => 'test', + ); + +$foo = array( +1 +, +2 +); + +$fields = array( + 'value' => 'type' +); diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php index fa7b95a1..013297b0 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php @@ -38,6 +38,15 @@ public function getErrorList() { 59 => 2, 60 => 1, 61 => 1, + 81 => 1, + 82 => 1, + 85 => 1, + 86 => 2, + 89 => 3, + 91 => 1, + 94 => 1, + 95 => 2, + 98 => 1, ); } From bb2266b94188946f7581afbdca06691509e8c56a Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 22 Jul 2017 09:45:45 +0200 Subject: [PATCH 122/282] Remove ArrayDeclaration sniff: deprecate the sniff and remove from ruleset * Empty out the ArrayDeclaration sniff file and remove references to it in the `WordPress-Core` ruleset. * Remove perfunctory test file explaining why this wasn't unit tested here. * Minor touch up of documentation referring to the sniff. * Remove the file exclusion from the WPCS own custom PHPCS ruleset. --- WordPress-Core/ruleset.xml | 14 +- .../Sniffs/Arrays/ArrayDeclarationSniff.php | 622 +----------------- .../Arrays/ArrayDeclarationSpacingSniff.php | 6 +- .../Sniffs/Arrays/ArrayIndentationSniff.php | 4 +- .../Tests/Arrays/ArrayDeclarationUnitTest.txt | 13 - bin/phpcs.xml | 5 - 6 files changed, 38 insertions(+), 626 deletions(-) delete mode 100644 WordPress/Tests/Arrays/ArrayDeclarationUnitTest.txt diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index d85d4b92..f31faff8 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -46,21 +46,13 @@ - - - - - - - - - - - + + + diff --git a/WordPress/Sniffs/Arrays/ArrayDeclarationSniff.php b/WordPress/Sniffs/Arrays/ArrayDeclarationSniff.php index 9e1e4be8..b3fbb456 100644 --- a/WordPress/Sniffs/Arrays/ArrayDeclarationSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayDeclarationSniff.php @@ -7,10 +7,6 @@ * @license https://opensource.org/licenses/MIT MIT */ -if ( ! class_exists( 'Squiz_Sniffs_Arrays_ArrayDeclarationSniff', true ) ) { - throw new PHP_CodeSniffer_Exception( 'Class Squiz_Sniffs_Arrays_ArrayDeclarationSniff not found' ); -} - /** * Enforces WordPress array format, based upon Squiz code. * @@ -18,600 +14,42 @@ * * @package WPCS\WordPressCodingStandards * - * @since 0.1.0 - * @since 0.5.0 Now extends `Squiz_Sniffs_Arrays_ArrayDeclarationSniff`. - * @since 0.11.0 The additional single-line array checks have been moved to their own - * sniff WordPress.Arrays.ArrayDeclarationSpacing. - * This class now only contains a slimmed down version of the upstream sniff. - * - * DO NOT MAKE CHANGES TO THIS SNIFF - other than syncing with upstream -. - * ANY CHANGES NECESSARY SHOULD BE PULLED TO THE UPSTREAM SNIFF AND SYNCED IN AFTER MERGE! - * The code style of this sniff should be ignored so as to facilitate easy syncing with - * upstream. - * - * {@internal The upstream version is similar, except that we exclude a few errors. - * Unfortunately we have to actually comment out the code rather than just using - * the upstream sniff and `` in our ruleset, due to a bug/non-configurability - * of the sniff. - * {@see https://github.com/squizlabs/PHP_CodeSniffer/issues/582} }} - * - * Last synced with parent class October 5 2016 at commit ea32814346ecf29791de701b3fa464a9ca43f45b. - * @link https://github.com/squizlabs/PHP_CodeSniffer/blob/master/CodeSniffer/Standards/Squiz/Sniffs/Arrays/ArrayDeclarationSniff.php + * @since 0.1.0 + * @since 0.5.0 Now extends `Squiz_Sniffs_Arrays_ArrayDeclarationSniff`. + * @since 0.11.0 The additional single-line array checks have been moved to their own + * sniff WordPress.Arrays.ArrayDeclarationSpacing. + * This class now only contains a slimmed down version of the upstream sniff. + * @deprecated 0.13.0 This sniff has now been deprecated. Most checks which were previously + * contained herein had recently been excluded in favour of dedicated + * sniffs with higher precision. The last remaining checks which were not + * already covered elsewhere have been moved to the `ArrayDeclarationSpacing` + * sniff. + * This class is left here to prevent breaking custom rulesets which refer + * to this sniff. */ -class WordPress_Sniffs_Arrays_ArrayDeclarationSniff extends Squiz_Sniffs_Arrays_ArrayDeclarationSniff { +class WordPress_Sniffs_Arrays_ArrayDeclarationSniff { /** - * Process a multi-line array. + * Don't use. * - * @since 0.5.0 + * @deprecated 0.13.0 * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. - * @param int $arrayStart Position of the array opener in the token stack. - * @param int $arrayEnd Position of the array closer in the token stack. + * @return int[] */ - public function processMultiLineArray( PHP_CodeSniffer_File $phpcsFile, $stackPtr, $arrayStart, $arrayEnd ) { - $tokens = $phpcsFile->getTokens(); - $keywordStart = $tokens[ $stackPtr ]['column']; - - // Check the closing bracket is on a new line. - $lastContent = $phpcsFile->findPrevious( T_WHITESPACE, ( $arrayEnd - 1 ), $arrayStart, true ); - if ( $tokens[ $lastContent ]['line'] === $tokens[ $arrayEnd ]['line'] ) { - $error = 'Closing parenthesis of array declaration must be on a new line'; - $fix = $phpcsFile->addFixableError( $error, $arrayEnd, 'CloseBraceNewLine' ); - if ($fix === true) { - $phpcsFile->fixer->addNewlineBefore( $arrayEnd ); - } - /* - } elseif ( $tokens[ $arrayEnd ]['column'] !== $keywordStart ) { - // Check the closing bracket is lined up under the "a" in array. - $expected = ( $keywordStart - 1 ); - $found = ( $tokens[ $arrayEnd ]['column'] - 1 ); - $error = 'Closing parenthesis not aligned correctly; expected %s space(s) but found %s'; - $data = array( - $expected, - $found, - ); - - $fix = $phpcsFile->addFixableError( $error, $arrayEnd, 'CloseBraceNotAligned', $data ); - if ($fix === true) { - if ($found === 0) { - $phpcsFile->fixer->addContent( ( $arrayEnd - 1 ), str_repeat(' ', $expected ) ); - } else { - $phpcsFile->fixer->replaceToken( ( $arrayEnd - 1 ), str_repeat(' ', $expected ) ); - } - } - */ - } // end if - - $keyUsed = false; - $singleUsed = false; - $indices = array(); - $maxLength = 0; - - if ($tokens[$stackPtr]['code'] === T_ARRAY) { - $lastToken = $tokens[ $stackPtr ]['parenthesis_opener']; - } else { - $lastToken = $stackPtr; - } - - // Find all the double arrows that reside in this scope. - for ( $nextToken = ( $stackPtr + 1 ); $nextToken < $arrayEnd; $nextToken++ ) { - // Skip bracketed statements, like function calls. - if ($tokens[$nextToken]['code'] === T_OPEN_PARENTHESIS - && (isset($tokens[$nextToken]['parenthesis_owner']) === false - || $tokens[ $nextToken ]['parenthesis_owner'] !== $stackPtr ) - ) { - $nextToken = $tokens[ $nextToken ]['parenthesis_closer']; - continue; - } - - if ( in_array( $tokens[ $nextToken ]['code'], array( T_ARRAY, T_OPEN_SHORT_ARRAY, T_CLOSURE ), true ) === true ) { - // Let subsequent calls of this test handle nested arrays. - if ($tokens[$lastToken]['code'] !== T_DOUBLE_ARROW) { - $indices[] = array( 'value' => $nextToken ); - $lastToken = $nextToken; - } - - if ($tokens[$nextToken]['code'] === T_ARRAY) { - $nextToken = $tokens[ $tokens[ $nextToken ]['parenthesis_opener'] ]['parenthesis_closer']; - } else if ($tokens[$nextToken]['code'] === T_OPEN_SHORT_ARRAY) { - $nextToken = $tokens[ $nextToken ]['bracket_closer']; - } else { - // T_CLOSURE. - $nextToken = $tokens[ $nextToken ]['scope_closer']; - } - - $nextToken = $phpcsFile->findNext( T_WHITESPACE, ( $nextToken + 1 ), null, true ); - if ($tokens[$nextToken]['code'] !== T_COMMA) { - $nextToken--; - } else { - $lastToken = $nextToken; - } - - continue; - }//end if - - if ($tokens[$nextToken]['code'] !== T_DOUBLE_ARROW - && $tokens[$nextToken]['code'] !== T_COMMA - ) { - continue; - } - - $currentEntry = array(); - - if ($tokens[$nextToken]['code'] === T_COMMA) { - /* - $stackPtrCount = 0; - if (isset($tokens[$stackPtr]['nested_parenthesis']) === true) { - $stackPtrCount = count( $tokens[ $stackPtr ]['nested_parenthesis'] ); - } - - $commaCount = 0; - if (isset($tokens[$nextToken]['nested_parenthesis']) === true) { - $commaCount = count( $tokens[ $nextToken ]['nested_parenthesis'] ); - if ($tokens[$stackPtr]['code'] === T_ARRAY) { - // Remove parenthesis that are used to define the array. - $commaCount--; - } - } - - if ( $commaCount > $stackPtrCount ) { - // This comma is inside more parenthesis than the ARRAY keyword, - // then there it is actually a comma used to separate arguments - // in a function call. - continue; - } - - if ($keyUsed === true && $tokens[$lastToken]['code'] === T_COMMA) { - $error = 'No key specified for array entry; first entry specifies key'; - $phpcsFile->addError( $error, $nextToken, 'NoKeySpecified' ); - return; - } - */ - - if ($keyUsed === false) { - /* - if ($tokens[($nextToken - 1)]['code'] === T_WHITESPACE) { - $content = $tokens[ ( $nextToken - 2 ) ]['content']; - if ( $tokens[ ( $nextToken - 1 ) ]['content'] === $phpcsFile->eolChar ) { - $spaceLength = 'newline'; - } else { - $spaceLength = $tokens[ ( $nextToken - 1 ) ]['length']; - } - - $error = 'Expected 0 spaces between "%s" and comma; %s found'; - $data = array( - $content, - $spaceLength, - ); - - $fix = $phpcsFile->addFixableError( $error, $nextToken, 'SpaceBeforeComma', $data ); - if ($fix === true) { - $phpcsFile->fixer->replaceToken( ( $nextToken - 1 ), '' ); - } - } - */ - - $valueContent = $phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens, - ( $lastToken + 1 ), - $nextToken, - true - ); - - $indices[] = array( 'value' => $valueContent ); - // $singleUsed = true; - }//end if - - $lastToken = $nextToken; - continue; - - }//end if - - if ($tokens[$nextToken]['code'] === T_DOUBLE_ARROW) { - /* - if ($singleUsed === true) { - $error = 'Key specified for array entry; first entry has no key'; - $phpcsFile->addError( $error, $nextToken, 'KeySpecified' ); - return; - } - */ - - $currentEntry['arrow'] = $nextToken; - $keyUsed = true; - - // Find the start of index that uses this double arrow. - $indexEnd = $phpcsFile->findPrevious( T_WHITESPACE, ( $nextToken - 1 ), $arrayStart, true ); - $indexStart = $phpcsFile->findStartOfStatement( $indexEnd ); - - if ( $indexStart === $indexEnd ) { - $currentEntry['index'] = $indexEnd; - $currentEntry['index_content'] = $tokens[ $indexEnd ]['content']; - } else { - $currentEntry['index'] = $indexStart; - $currentEntry['index_content'] = $phpcsFile->getTokensAsString( $indexStart, ( $indexEnd - $indexStart + 1 ) ); - } - - $indexLength = strlen( $currentEntry['index_content'] ); - if ( $maxLength < $indexLength ) { - $maxLength = $indexLength; - } - - // Find the value of this index. - $nextContent = $phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens, - ( $nextToken + 1 ), - $arrayEnd, - true - ); - - $currentEntry['value'] = $nextContent; - $indices[] = $currentEntry; - $lastToken = $nextToken; - }//end if - }//end for - - // Check for mutli-line arrays that should be single-line. - $singleValue = false; - - if (empty($indices) === true) { - $singleValue = true; - } else if (count($indices) === 1 && $tokens[$lastToken]['code'] === T_COMMA) { - // There may be another array value without a comma. - $exclude = PHP_CodeSniffer_Tokens::$emptyTokens; - $exclude[] = T_COMMA; - $nextContent = $phpcsFile->findNext( $exclude, ( $indices[0]['value'] + 1 ), $arrayEnd, true ); - if ($nextContent === false) { - $singleValue = true; - } - } - - /* - if ($singleValue === true) { - // Array cannot be empty, so this is a multi-line array with - // a single value. It should be defined on single line. - $error = 'Multi-line array contains a single value; use single-line array instead'; - $fix = $phpcsFile->addFixableError( $error, $stackPtr, 'MultiLineNotAllowed' ); - - if ($fix === true) { - $phpcsFile->fixer->beginChangeset(); - for ( $i = ( $arrayStart + 1 ); $i < $arrayEnd; $i++ ) { - if ($tokens[$i]['code'] !== T_WHITESPACE) { - break; - } - - $phpcsFile->fixer->replaceToken( $i, '' ); - } - - for ( $i = ( $arrayEnd - 1 ); $i > $arrayStart; $i-- ) { - if ($tokens[$i]['code'] !== T_WHITESPACE) { - break; - } - - $phpcsFile->fixer->replaceToken( $i, '' ); - } - - $phpcsFile->fixer->endChangeset(); - } - - return; - } // end if - */ - - /* - This section checks for arrays that don't specify keys. - - Arrays such as: - array( - 'aaa', - 'bbb', - 'd', - ); - */ - - if ($keyUsed === false && empty($indices) === false) { - $count = count( $indices ); - $lastIndex = $indices[ ( $count - 1 ) ]['value']; - - $trailingContent = $phpcsFile->findPrevious( - PHP_CodeSniffer_Tokens::$emptyTokens, - ( $arrayEnd - 1 ), - $lastIndex, - true - ); - - /* - if ($tokens[$trailingContent]['code'] !== T_COMMA) { - $phpcsFile->recordMetric( $stackPtr, 'Array end comma', 'no' ); - $error = 'Comma required after last value in array declaration'; - $fix = $phpcsFile->addFixableError( $error, $trailingContent, 'NoCommaAfterLast' ); - if ($fix === true) { - $phpcsFile->fixer->addContent( $trailingContent, ',' ); - } - } else { - $phpcsFile->recordMetric( $stackPtr, 'Array end comma', 'yes' ); - } - */ + public function register() { + return array(); + } - $lastValueLine = false; - foreach ( $indices as $value ) { - if (empty($value['value']) === true) { - // Array was malformed and we couldn't figure out - // the array value correctly, so we have to ignore it. - // Other parts of this sniff will correct the error. - continue; - } - - if ($lastValueLine !== false && $tokens[$value['value']]['line'] === $lastValueLine) { - $error = 'Each value in a multi-line array must be on a new line'; - $fix = $phpcsFile->addFixableError( $error, $value['value'], 'ValueNoNewline' ); - if ($fix === true) { - if ($tokens[($value['value'] - 1)]['code'] === T_WHITESPACE) { - $phpcsFile->fixer->replaceToken( ( $value['value'] - 1 ), '' ); - } - - $phpcsFile->fixer->addNewlineBefore( $value['value'] ); - } - /* - } else if ($tokens[($value['value'] - 1)]['code'] === T_WHITESPACE) { - $expected = $keywordStart; - - $first = $phpcsFile->findFirstOnLine( T_WHITESPACE, $value['value'], true ); - $found = ($tokens[ $first ]['column'] - 1); - if ( $found !== $expected ) { - $error = 'Array value not aligned correctly; expected %s spaces but found %s'; - $data = array( - $expected, - $found, - ); - - $fix = $phpcsFile->addFixableError( $error, $value['value'], 'ValueNotAligned', $data ); - if ($fix === true) { - if ($found === 0) { - $phpcsFile->fixer->addContent( ( $value['value'] - 1 ), str_repeat(' ', $expected ) ); - } else { - $phpcsFile->fixer->replaceToken( ( $value['value'] - 1 ), str_repeat(' ', $expected ) ); - } - } - } - */ - } // end if - - $lastValueLine = $tokens[ $value['value'] ]['line']; - }//end foreach - }//end if - - /* - Below the actual indentation of the array is checked. - Errors will be thrown when a key is not aligned, when - a double arrow is not aligned, and when a value is not - aligned correctly. - If an error is found in one of the above areas, then errors - are not reported for the rest of the line to avoid reporting - spaces and columns incorrectly. Often fixing the first - problem will fix the other 2 anyway. - - For example: - - $a = array( - 'index' => '2', - ); - - or - - $a = [ - 'index' => '2', - ]; - - In this array, the double arrow is indented too far, but this - will also cause an error in the value's alignment. If the arrow were - to be moved back one space however, then both errors would be fixed. - */ - - $numValues = count( $indices ); - - $indicesStart = ( $keywordStart + 1 ); - $arrowStart = ( $indicesStart + $maxLength + 1 ); - //$valueStart = ($arrowStart + 3); - $indexLine = $tokens[ $stackPtr ]['line']; - //$lastIndexLine = null; - foreach ( $indices as $index ) { - if (isset($index['index']) === false) { - // Array value only. - if ( $tokens[ $index['value'] ]['line'] === $tokens[ $stackPtr ]['line'] && $numValues > 1 ) { - $error = 'The first value in a multi-value array must be on a new line'; - $fix = $phpcsFile->addFixableError( $error, $stackPtr, 'FirstValueNoNewline' ); - if ($fix === true) { - $phpcsFile->fixer->addNewlineBefore( $index['value'] ); - } - } - - continue; - } - - $lastIndexLine = $indexLine; - $indexLine = $tokens[ $index['index'] ]['line']; - - if ( $indexLine === $tokens[ $stackPtr ]['line'] ) { - $error = 'The first index in a multi-value array must be on a new line'; - $fix = $phpcsFile->addFixableError( $error, $index['index'], 'FirstIndexNoNewline' ); - if ($fix === true) { - $phpcsFile->fixer->addNewlineBefore( $index['index'] ); - } - - continue; - } - - if ( $indexLine === $lastIndexLine ) { - $error = 'Each index in a multi-line array must be on a new line'; - $fix = $phpcsFile->addFixableError( $error, $index['index'], 'IndexNoNewline' ); - if ($fix === true) { - if ($tokens[($index['index'] - 1)]['code'] === T_WHITESPACE) { - $phpcsFile->fixer->replaceToken( ( $index['index'] - 1 ), '' ); - } - - $phpcsFile->fixer->addNewlineBefore( $index['index'] ); - } - - continue; - } - - /* - if ( $tokens[ $index['index'] ]['column'] !== $indicesStart ) { - $expected = ( $indicesStart - 1 ); - $found = ( $tokens[ $index['index'] ]['column'] - 1 ); - $error = 'Array key not aligned correctly; expected %s spaces but found %s'; - $data = array( - $expected, - $found, - ); - - $fix = $phpcsFile->addFixableError( $error, $index['index'], 'KeyNotAligned', $data ); - if ($fix === true) { - if ($found === 0) { - $phpcsFile->fixer->addContent( ( $index['index'] - 1 ), str_repeat(' ', $expected ) ); - } else { - $phpcsFile->fixer->replaceToken( ( $index['index'] - 1 ), str_repeat(' ', $expected ) ); - } - } - - continue; - } - - if ( $tokens[ $index['arrow'] ]['column'] !== $arrowStart ) { - $expected = ( $arrowStart - ( strlen( $index['index_content'] ) + $tokens[ $index['index'] ]['column'] ) ); - $found = ( $tokens[ $index['arrow'] ]['column'] - ( strlen( $index['index_content'] ) + $tokens[ $index['index'] ]['column'] ) ); - $error = 'Array double arrow not aligned correctly; expected %s space(s) but found %s'; - $data = array( - $expected, - $found, - ); - - $fix = $phpcsFile->addFixableError( $error, $index['arrow'], 'DoubleArrowNotAligned', $data ); - if ($fix === true) { - if ($found === 0) { - $phpcsFile->fixer->addContent( ( $index['arrow'] - 1 ), str_repeat(' ', $expected ) ); - } else { - $phpcsFile->fixer->replaceToken( ( $index['arrow'] - 1 ), str_repeat(' ', $expected ) ); - } - } - - continue; - } - - if ( $tokens[ $index['value'] ]['column'] !== $valueStart ) { - $expected = ( $valueStart - ( $tokens[ $index['arrow'] ]['length'] + $tokens[ $index['arrow'] ]['column'] ) ); - $found = ( $tokens[ $index['value'] ]['column'] - ( $tokens[ $index['arrow'] ]['length'] + $tokens[ $index['arrow'] ]['column'] ) ); - if ( $found < 0 ) { - $found = 'newline'; - } - - $error = 'Array value not aligned correctly; expected %s space(s) but found %s'; - $data = array( - $expected, - $found, - ); - - $fix = $phpcsFile->addFixableError( $error, $index['arrow'], 'ValueNotAligned', $data ); - if ($fix === true) { - if ($found === 'newline') { - $prev = $phpcsFile->findPrevious( T_WHITESPACE, ( $index['value'] - 1 ), null, true ); - $phpcsFile->fixer->beginChangeset(); - for ( $i = ( $prev + 1 ); $i < $index['value']; $i++ ) { - $phpcsFile->fixer->replaceToken( $i, '' ); - } - - $phpcsFile->fixer->replaceToken( ( $index['value'] - 1 ), str_repeat(' ', $expected ) ); - $phpcsFile->fixer->endChangeset(); - } else if ($found === 0) { - $phpcsFile->fixer->addContent( ( $index['value'] - 1 ), str_repeat(' ', $expected ) ); - } else { - $phpcsFile->fixer->replaceToken( ( $index['value'] - 1 ), str_repeat(' ', $expected ) ); - } - } - } // end if - */ - - // Check each line ends in a comma. - /* - $valueLine = $tokens[ $index['value'] ]['line']; - $nextComma = false; - for ( $i = $index['value']; $i < $arrayEnd; $i++ ) { - // Skip bracketed statements, like function calls. - if ($tokens[$i]['code'] === T_OPEN_PARENTHESIS) { - $i = $tokens[ $i ]['parenthesis_closer']; - $valueLine = $tokens[ $i ]['line']; - continue; - } - - if ($tokens[$i]['code'] === T_ARRAY) { - $i = $tokens[ $tokens[ $i ]['parenthesis_opener'] ]['parenthesis_closer']; - $valueLine = $tokens[ $i ]['line']; - continue; - } - - // Skip to the end of multi-line strings. - if (isset(PHP_CodeSniffer_Tokens::$stringTokens[$tokens[$i]['code']]) === true) { - $i = $phpcsFile->findNext($tokens[$i]['code'], ($i + 1), null, true); - $i--; - $valueLine = $tokens[$i]['line']; - continue; - } - - if ($tokens[$i]['code'] === T_OPEN_SHORT_ARRAY) { - $i = $tokens[ $i ]['bracket_closer']; - $valueLine = $tokens[ $i ]['line']; - continue; - } - - if ($tokens[$i]['code'] === T_CLOSURE) { - $i = $tokens[ $i ]['scope_closer']; - $valueLine = $tokens[ $i ]['line']; - continue; - } - - if ($tokens[$i]['code'] === T_COMMA) { - $nextComma = $i; - break; - } - }//end for - - if ($nextComma === false || ($tokens[$nextComma]['line'] !== $valueLine)) { - $error = 'Each line in an array declaration must end in a comma'; - $fix = $phpcsFile->addFixableError( $error, $index['value'], 'NoComma' ); - - if ($fix === true) { - // Find the end of the line and put a comma there. - for ($i = ($index['value'] + 1); $i < $arrayEnd; $i++) { - if ( $tokens[ $i ]['line'] > $valueLine ) { - break; - } - } - - $phpcsFile->fixer->addContentBefore( ( $i - 1 ), ',' ); - } - } - - // Check that there is no space before the comma. - if ($nextComma !== false && $tokens[($nextComma - 1)]['code'] === T_WHITESPACE) { - $content = $tokens[ ( $nextComma - 2 ) ]['content']; - $spaceLength = $tokens[ ( $nextComma - 1 ) ]['length']; - $error = 'Expected 0 spaces between "%s" and comma; %s found'; - $data = array( - $content, - $spaceLength, - ); - - $fix = $phpcsFile->addFixableError( $error, $nextComma, 'SpaceBeforeComma', $data ); - if ($fix === true) { - $phpcsFile->fixer->replaceToken( ( $nextComma - 1 ), '' ); - } - } - */ - }//end foreach - - }//end processMultiLineArray() + /** + * Don't use. + * + * @deprecated 0.13.0 + * + * @param PHP_CodeSniffer_File $phpcsFile A PHP_CodeSniffer file. + * @param int $stackPtr The position of the token. + * + * @return void + */ + public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) {} } // End class. diff --git a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php index b42646f1..3d7c985c 100644 --- a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php @@ -10,9 +10,6 @@ /** * Enforces WordPress array spacing format. * - * WordPress specific checks which are not covered by the `WordPress.Arrays.ArrayDeclaration`/ - * `Squiz.Arrays.ArrayDeclaration` sniff. - * * - Check for no space between array keyword and array opener. * - Check for no space between the parentheses of an empty array. * - Checks for one space after the array opener / before the array closer in single-line arrays. @@ -30,6 +27,9 @@ * - Added sniffing & fixing for associative arrays. * @since 0.12.0 Decoupled this sniff from the upstream sniff completely. * This sniff now extends the `WordPress_Sniff` instead. + * @since 0.13.0 Added the last remaining checks from the `ArrayDeclaration` sniff + * which were not covered elsewhere. The `ArrayDeclaration` sniff has + * now been deprecated. */ class WordPress_Sniffs_Arrays_ArrayDeclarationSpacingSniff extends WordPress_Sniff { diff --git a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php index 329b9a98..29fb9f60 100644 --- a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php @@ -141,7 +141,7 @@ public function process_token( $stackPtr ) { * Otherwise, only report the error, don't try and fix it (yet). * * It will get corrected in a future loop of the fixer once the closer - * has been moved to its own line by the `ArrayDeclaration` sniff. + * has been moved to its own line by the `ArrayDeclarationSpacing` sniff. */ $this->phpcsFile->addError( $error, @@ -184,7 +184,7 @@ public function process_token( $stackPtr ) { } // Bow out from reporting and fixing mixed multi-line/single-line arrays. - // That is handled by the ArrayDeclarationSniff. + // That is handled by the ArrayDeclarationSpacingSniff. if ( $this->tokens[ $first_content ]['line'] === $this->tokens[ $end_of_previous_item ]['line'] || ( 1 !== $this->tokens[ $first_content ]['column'] && T_WHITESPACE !== $this->tokens[ ( $first_content - 1 ) ]['code'] ) diff --git a/WordPress/Tests/Arrays/ArrayDeclarationUnitTest.txt b/WordPress/Tests/Arrays/ArrayDeclarationUnitTest.txt deleted file mode 100644 index 4b8ea342..00000000 --- a/WordPress/Tests/Arrays/ArrayDeclarationUnitTest.txt +++ /dev/null @@ -1,13 +0,0 @@ -/** - * THIS SNIFF IS INTENTIONALLY NOT TESTED HERE. - * - * The WordPress.Arrays.ArrayDeclaration sniff is a duplicate of the upstream - * Squiz.Arrays.ArrayDeclaration sniff with some checks commented out. - * - * As such all checks contained in the sniff are already tested upstream and - * the tests should not be duplicated here. - * - * @package WPCS\WordPressCodingStandards - * @link https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards - * @license https://opensource.org/licenses/MIT MIT - */ diff --git a/bin/phpcs.xml b/bin/phpcs.xml index 6e933911..03f52da5 100644 --- a/bin/phpcs.xml +++ b/bin/phpcs.xml @@ -2,11 +2,6 @@ The Coding standard for the WordPress Coding Standards itself. - - /WordPress/Sniffs/Arrays/ArrayDeclarationSniff.php - From e7d43983ce9b0336b8450f34d31a26b58bfa1a0a Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 22 Jul 2017 09:46:01 +0200 Subject: [PATCH 123/282] Remove ArrayDeclaration sniff: test both long as well as short arrays for spacing Creates a second copy of the `ArrayDeclarationSpacingUnitTest` file. The first (original) test case file now tests long arrays `array()`. The second (copy) test case file now tests short arrays `[]`. The test cases in both files are the same, except for the fact that the short array test case file does not contain the tests for _space between array keyword and opener_ as that's not applicable. --- ... => ArrayDeclarationSpacingUnitTest.1.inc} | 9 +- ...rayDeclarationSpacingUnitTest.1.inc.fixed} | 19 ++- .../ArrayDeclarationSpacingUnitTest.2.inc | 84 +++++++++++ ...rrayDeclarationSpacingUnitTest.2.inc.fixed | 137 ++++++++++++++++++ .../ArrayDeclarationSpacingUnitTest.php | 92 ++++++++---- 5 files changed, 302 insertions(+), 39 deletions(-) rename WordPress/Tests/Arrays/{ArrayDeclarationSpacingUnitTest.inc => ArrayDeclarationSpacingUnitTest.1.inc} (86%) rename WordPress/Tests/Arrays/{ArrayDeclarationSpacingUnitTest.inc.fixed => ArrayDeclarationSpacingUnitTest.1.inc.fixed} (96%) create mode 100644 WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc create mode 100644 WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc.fixed diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc similarity index 86% rename from WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc rename to WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc index 6acbfc00..5727abba 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc @@ -1,4 +1,7 @@ 'value' ); // Bad, each value of an associative array should start on a new line. // Test for fixing nested associative arrays. -$bad = array( array( 'key1' => 'value1', 'key2' => ['sub1' => 1, 'sub2' => 2] ), $key3 => 'value3', [ 'value4', 10 => 'value5', ] ); // Bad. +$bad = array( array( 'key1' => 'value1', 'key2' => array('sub1' => 1, 'sub2' => 2) ), $key3 => 'value3', array( 'value4', 10 => 'value5', ) ); // Bad. // Test for fixing mixed single & multi-line nested associative arrays. $bad = array( array( 'key1' => 'value1', array('sub1' => 1,'sub2' => 2,)), $key3 => 'value3', - [ 'value4', 10 => 'value5' ] + array( 'value4', 10 => 'value5' ) ); // Bad. // Test for fixing associative arrays with multiple values & line indented with whitespace. @@ -26,7 +29,7 @@ $bad = array( $bad = array( 'key1' => 'value1', /* comment */ 'key2' => 'value2' ); // Bad. // Test for fixing non-associative array with a nested associative array which *will* be fixed. -$bad = array( 'value1', 'value2', [ 'sub1' => 1, 'sub2' => 2 ], 'value4' ); // Bad. +$bad = array( 'value1', 'value2', array( 'sub1' => 1, 'sub2' => 2 ), 'value4' ); // Bad. /* * Test spacing between array keyword and open parenthesis. diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc.fixed similarity index 96% rename from WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed rename to WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc.fixed index d48bcf31..b3e18bbd 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.inc.fixed +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc.fixed @@ -1,4 +1,7 @@ 'value1', -'key2' => [ +'key2' => array( 'sub1' => 1, 'sub2' => 2 -] +) ), $key3 => 'value3', -[ +array( 'value4', 10 => 'value5', -] +) ); // Bad. // Test for fixing mixed single & multi-line nested associative arrays. @@ -37,10 +40,10 @@ array( ) ), $key3 => 'value3', - [ + array( 'value4', 10 => 'value5' -] +) ); // Bad. // Test for fixing associative arrays with multiple values & line indented with whitespace. @@ -62,10 +65,10 @@ $bad = array( $bad = array( 'value1', 'value2', -[ +array( 'sub1' => 1, 'sub2' => 2 -], +), 'value4' ); // Bad. diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc new file mode 100644 index 00000000..53802a52 --- /dev/null +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc @@ -0,0 +1,84 @@ + 'value' ]; // Bad, each value of an associative array should start on a new line. + +// Test for fixing nested associative arrays. +$bad = [ [ 'key1' => 'value1', 'key2' => ['sub1' => 1, 'sub2' => 2] ], $key3 => 'value3', [ 'value4', 10 => 'value5', ] ]; // Bad. + +// Test for fixing mixed single & multi-line nested associative arrays. +$bad = [ + [ 'key1' => 'value1', ['sub1' => 1,'sub2' => 2,]], + $key3 => 'value3', + [ 'value4', 10 => 'value5' ] +]; // Bad. + +// Test for fixing associative arrays with multiple values & line indented with whitespace. + $bad = [ 'key1' => 'value1', 'key2' => 'value2', $key3 => 'value3', 'value4', 10 => 'value5' ]; // Bad. + +// Test for fixing associative arrays with comments between values. +$bad = [ 'key1' => 'value1', /* comment */ 'key2' => 'value2' ]; // Bad. + +// Test for fixing non-associative array with a nested associative array which *will* be fixed. +$bad = [ 'value1', 'value2', [ 'sub1' => 1, 'sub2' => 2 ], 'value4' ]; // Bad. + +/* + * Tests for empty array with space between parentheses. + */ +// OK. +$a = []; +$value = [ /* comment */ ]; +$x = [ + // comment + ]; + +// Bad. +$value = [ ]; +$value = [ ]; +$x = [ + ]; + +/* + * Tests for multi-line arrays - closing brace on new line + array items each on new line. + */ +// OK. +$value = [ + 1, + 2, /* Comment. */ + 3, +]; + +$value = [ + 1 => $one, + 2 => $two, // Comment. + 3 => $three, // Comment. +]; + +// Bad. +$value = [1, + 2 , 3 , +]; + +$value = [1 => $one, + 2 => $two , /* Comment. */ 3 => $three , ]; + +$value = [ + '1'=> TRUE, FALSE, '3' => 'aaa',]; + +$x = ['name' => 'test', + ]; + +$foo = [1 +, 2]; + +$fields = [ + 'value' => 'type']; diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc.fixed b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc.fixed new file mode 100644 index 00000000..8ed5a400 --- /dev/null +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc.fixed @@ -0,0 +1,137 @@ + 'value' +]; // Bad, each value of an associative array should start on a new line. + +// Test for fixing nested associative arrays. +$bad = [ +[ +'key1' => 'value1', +'key2' => [ +'sub1' => 1, +'sub2' => 2 +] +], +$key3 => 'value3', +[ +'value4', +10 => 'value5', +] +]; // Bad. + +// Test for fixing mixed single & multi-line nested associative arrays. +$bad = [ + [ +'key1' => 'value1', +[ +'sub1' => 1, +'sub2' => 2, +] +], + $key3 => 'value3', + [ +'value4', +10 => 'value5' +] +]; // Bad. + +// Test for fixing associative arrays with multiple values & line indented with whitespace. + $bad = [ +'key1' => 'value1', +'key2' => 'value2', +$key3 => 'value3', +'value4', +10 => 'value5' +]; // Bad. + +// Test for fixing associative arrays with comments between values. +$bad = [ +'key1' => 'value1', /* comment */ +'key2' => 'value2' +]; // Bad. + +// Test for fixing non-associative array with a nested associative array which *will* be fixed. +$bad = [ +'value1', +'value2', +[ +'sub1' => 1, +'sub2' => 2 +], +'value4' +]; // Bad. + +/* + * Tests for empty array with space between parentheses. + */ +// OK. +$a = []; +$value = [ /* comment */ ]; +$x = [ + // comment + ]; + +// Bad. +$value = []; +$value = []; +$x = []; + +/* + * Tests for multi-line arrays - closing brace on new line + array items each on new line. + */ +// OK. +$value = [ + 1, + 2, /* Comment. */ + 3, +]; + +$value = [ + 1 => $one, + 2 => $two, // Comment. + 3 => $three, // Comment. +]; + +// Bad. +$value = [ +1, + 2 , +3 , +]; + +$value = [ +1 => $one, + 2 => $two , +/* Comment. */ 3 => $three , +]; + +$value = [ + '1'=> TRUE, +FALSE, +'3' => 'aaa', +]; + +$x = [ +'name' => 'test', + ]; + +$foo = [ +1 +, +2 +]; + +$fields = [ + 'value' => 'type' +]; diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php index 013297b0..5537e46e 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php @@ -18,36 +18,72 @@ class WordPress_Tests_Arrays_ArrayDeclarationSpacingUnitTest extends AbstractSni /** * Returns the lines where errors should occur. * + * @param string $testFile The name of the file being tested. + * * @return array => */ - public function getErrorList() { - return array( - 5 => 2, - 8 => 2, - 10 => 1, - 13 => 4, - 17 => 2, - 19 => 1, - 23 => 1, - 26 => 1, - 29 => 1, - 35 => 1, - 36 => 1, - 42 => 1, - 46 => 1, - 59 => 2, - 60 => 1, - 61 => 1, - 81 => 1, - 82 => 1, - 85 => 1, - 86 => 2, - 89 => 3, - 91 => 1, - 94 => 1, - 95 => 2, - 98 => 1, - ); + public function getErrorList( $testFile = '' ) { + + switch ( $testFile ) { + // Long arrays. + case 'ArrayDeclarationSpacingUnitTest.1.inc': + return array( + 8 => 2, + 11 => 2, + 13 => 1, + 16 => 4, + 20 => 2, + 22 => 1, + 26 => 1, + 29 => 1, + 32 => 1, + 38 => 1, + 39 => 1, + 45 => 1, + 49 => 1, + 62 => 2, + 63 => 1, + 64 => 1, + 84 => 1, + 85 => 1, + 88 => 1, + 89 => 2, + 92 => 3, + 94 => 1, + 97 => 1, + 98 => 2, + 101 => 1, + ); + + // Short arrays. + case 'ArrayDeclarationSpacingUnitTest.2.inc': + return array( + 8 => 2, + 11 => 2, + 13 => 1, + 16 => 4, + 20 => 2, + 22 => 1, + 26 => 1, + 29 => 1, + 32 => 1, + 45 => 1, + 46 => 1, + 47 => 1, + 67 => 1, + 68 => 1, + 71 => 1, + 72 => 2, + 75 => 3, + 77 => 1, + 80 => 1, + 81 => 2, + 84 => 1, + ); + + default: + return array(); + } } /** From b14688d7481dbfd6883dee14f0d8c49e0e3d72eb Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 21 Jul 2017 00:12:09 +0200 Subject: [PATCH 124/282] PHPCS 3.x prep: work round a function which will no longer exist The `removeTokenListener()` method was used to prevent the sniffs using these abstracts from being called for further files, however, this method will no longer exist in PHPCS 3.x with no alternative. The `AbstractFunctionRestrictionSniff` also uses a `getGroups()` method, but calls it earlier and prevents the child sniffs from being run without groups by just not registering any token listeners if no groups are found. This same methodology has now been implemented in the two abstracts which used the `removeTokenListener()` method, effectively making these sniffs more efficient and preventing the removal of the method from becoming a problem. --- ...stractArrayAssignmentRestrictionsSniff.php | 47 ++++++++++++++---- .../AbstractVariableRestrictionsSniff.php | 48 +++++++++++++++---- .../ArrayAssignmentRestrictionsSniff.php | 2 +- .../Variables/VariableRestrictionsSniff.php | 2 +- 4 files changed, 79 insertions(+), 20 deletions(-) diff --git a/WordPress/AbstractArrayAssignmentRestrictionsSniff.php b/WordPress/AbstractArrayAssignmentRestrictionsSniff.php index 89005221..c5cf5fd8 100644 --- a/WordPress/AbstractArrayAssignmentRestrictionsSniff.php +++ b/WordPress/AbstractArrayAssignmentRestrictionsSniff.php @@ -47,12 +47,26 @@ abstract class WordPress_AbstractArrayAssignmentRestrictionsSniff extends WordPr */ protected $excluded_groups = array(); + /** + * Cache for the group information. + * + * @since 0.13.0 + * + * @var array + */ + protected $groups_cache = array(); + /** * Returns an array of tokens this test wants to listen for. * * @return array */ public function register() { + // Retrieve the groups only once and don't set up a listener if there are no groups. + if ( false === $this->setup_groups() ) { + return array(); + } + return array( T_DOUBLE_ARROW, T_CLOSE_SQUARE_BRACKET, @@ -80,6 +94,28 @@ public function register() { */ abstract public function getGroups(); + /** + * Cache the groups. + * + * @since 0.13.0 + * + * @return bool True if the groups were setup. False if not. + */ + protected function setup_groups() { + $this->groups_cache = $this->getGroups(); + + if ( empty( $this->groups_cache ) && empty( self::$groups ) ) { + return false; + } + + // Allow for adding extra unit tests. + if ( ! empty( self::$groups ) ) { + $this->groups_cache = array_merge( $this->groups_cache, self::$groups ); + } + + return true; + } + /** * Processes this test, when one of its tokens is encountered. * @@ -89,15 +125,8 @@ abstract public function getGroups(); */ public function process_token( $stackPtr ) { - $groups = $this->getGroups(); - - if ( empty( $groups ) ) { - $this->phpcsFile->removeTokenListener( $this, $this->register() ); - return; - } - $this->excluded_groups = $this->merge_custom_array( $this->exclude ); - if ( array_diff_key( $groups, $this->excluded_groups ) === array() ) { + if ( array_diff_key( $this->groups_cache, $this->excluded_groups ) === array() ) { // All groups have been excluded. // Don't remove the listener as the exclude property can be changed inline. return; @@ -149,7 +178,7 @@ public function process_token( $stackPtr ) { return; } - foreach ( $groups as $groupName => $group ) { + foreach ( $this->groups_cache as $groupName => $group ) { if ( isset( $this->excluded_groups[ $groupName ] ) ) { continue; diff --git a/WordPress/AbstractVariableRestrictionsSniff.php b/WordPress/AbstractVariableRestrictionsSniff.php index b1bb20e0..324f4853 100644 --- a/WordPress/AbstractVariableRestrictionsSniff.php +++ b/WordPress/AbstractVariableRestrictionsSniff.php @@ -48,12 +48,26 @@ abstract class WordPress_AbstractVariableRestrictionsSniff extends WordPress_Sni */ protected $excluded_groups = array(); + /** + * Cache for the group information. + * + * @since 0.13.0 + * + * @var array + */ + protected $groups_cache = array(); + /** * Returns an array of tokens this test wants to listen for. * * @return array */ public function register() { + // Retrieve the groups only once and don't set up a listener if there are no groups. + if ( false === $this->setup_groups() ) { + return array(); + } + return array( T_VARIABLE, T_OBJECT_OPERATOR, @@ -84,6 +98,28 @@ public function register() { */ abstract public function getGroups(); + /** + * Cache the groups. + * + * @since 0.13.0 + * + * @return bool True if the groups were setup. False if not. + */ + protected function setup_groups() { + $this->groups_cache = $this->getGroups(); + + if ( empty( $this->groups_cache ) && empty( self::$groups ) ) { + return false; + } + + // Allow for adding extra unit tests. + if ( ! empty( self::$groups ) ) { + $this->groups_cache = array_merge( $this->groups_cache, self::$groups ); + } + + return true; + } + /** * Processes this test, when one of its tokens is encountered. * @@ -94,16 +130,10 @@ abstract public function getGroups(); */ public function process_token( $stackPtr ) { - $token = $this->tokens[ $stackPtr ]; - $groups = $this->getGroups(); - - if ( empty( $groups ) ) { - $this->phpcsFile->removeTokenListener( $this, $this->register() ); - return; - } + $token = $this->tokens[ $stackPtr ]; $this->excluded_groups = $this->merge_custom_array( $this->exclude ); - if ( array_diff_key( $groups, $this->excluded_groups ) === array() ) { + if ( array_diff_key( $this->groups_cache, $this->excluded_groups ) === array() ) { // All groups have been excluded. // Don't remove the listener as the exclude property can be changed inline. return; @@ -118,7 +148,7 @@ public function process_token( $stackPtr ) { } } - foreach ( $groups as $groupName => $group ) { + foreach ( $this->groups_cache as $groupName => $group ) { if ( isset( $this->excluded_groups[ $groupName ] ) ) { continue; diff --git a/WordPress/Sniffs/Arrays/ArrayAssignmentRestrictionsSniff.php b/WordPress/Sniffs/Arrays/ArrayAssignmentRestrictionsSniff.php index a122a7fa..5fbe91df 100644 --- a/WordPress/Sniffs/Arrays/ArrayAssignmentRestrictionsSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayAssignmentRestrictionsSniff.php @@ -38,7 +38,7 @@ class WordPress_Sniffs_Arrays_ArrayAssignmentRestrictionsSniff extends WordPress * @return array */ public function getGroups() { - return parent::$groups; + return array(); } /** diff --git a/WordPress/Sniffs/Variables/VariableRestrictionsSniff.php b/WordPress/Sniffs/Variables/VariableRestrictionsSniff.php index e8d16d88..f28a07af 100644 --- a/WordPress/Sniffs/Variables/VariableRestrictionsSniff.php +++ b/WordPress/Sniffs/Variables/VariableRestrictionsSniff.php @@ -39,7 +39,7 @@ class WordPress_Sniffs_Variables_VariableRestrictionsSniff extends WordPress_Abs * @return array */ public function getGroups() { - return parent::$groups; + return array(); } } // End class. From be850cb35f2dd931c540e6afebf5e43ce7e302f0 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 22 Jul 2017 19:50:04 +0200 Subject: [PATCH 125/282] PHPCS 3.x compat: Namespace all sniffs which extend from one of the WPCS base sniffs Includes adjustment of FQCN references in `@see` and `@uses` documentation. --- .../AbstractArrayAssignmentRestrictionsSniff.php | 6 +++++- WordPress/AbstractClassRestrictionsSniff.php | 6 +++++- WordPress/AbstractFunctionParameterSniff.php | 6 +++++- WordPress/AbstractFunctionRestrictionsSniff.php | 6 +++++- WordPress/AbstractVariableRestrictionsSniff.php | 6 +++++- WordPress/Sniff.php | 4 +++- .../Arrays/ArrayAssignmentRestrictionsSniff.php | 10 ++++++++-- WordPress/Sniffs/Arrays/ArrayDeclarationSniff.php | 6 +++++- .../Sniffs/Arrays/ArrayDeclarationSpacingSniff.php | 7 ++++++- WordPress/Sniffs/Arrays/ArrayIndentationSniff.php | 7 ++++++- .../Arrays/ArrayKeySpacingRestrictionsSniff.php | 7 ++++++- WordPress/Sniffs/Arrays/CommaAfterArrayItemSniff.php | 7 ++++++- WordPress/Sniffs/CSRF/NonceVerificationSniff.php | 7 ++++++- WordPress/Sniffs/Classes/ClassInstantiationSniff.php | 10 +++++++--- WordPress/Sniffs/CodeAnalysis/EmptyStatementSniff.php | 7 ++++++- WordPress/Sniffs/DB/RestrictedClassesSniff.php | 7 ++++++- WordPress/Sniffs/DB/RestrictedFunctionsSniff.php | 7 ++++++- WordPress/Sniffs/Files/FileNameSniff.php | 9 +++++++-- WordPress/Sniffs/Functions/DontExtractSniff.php | 7 ++++++- .../Functions/FunctionCallSignatureNoParamsSniff.php | 7 ++++++- .../Sniffs/Functions/FunctionRestrictionsSniff.php | 10 ++++++++-- .../NamingConventions/PrefixAllGlobalsSniff.php | 9 +++++++-- .../NamingConventions/ValidFunctionNameSniff.php | 1 + .../Sniffs/NamingConventions/ValidHookNameSniff.php | 7 ++++++- .../NamingConventions/ValidVariableNameSniff.php | 8 +++++--- WordPress/Sniffs/PHP/DevelopmentFunctionsSniff.php | 7 ++++++- WordPress/Sniffs/PHP/DiscouragedFunctionsSniff.php | 6 +++++- WordPress/Sniffs/PHP/DiscouragedPHPFunctionsSniff.php | 7 ++++++- WordPress/Sniffs/PHP/POSIXFunctionsSniff.php | 7 ++++++- WordPress/Sniffs/PHP/StrictComparisonsSniff.php | 7 ++++++- WordPress/Sniffs/PHP/StrictInArraySniff.php | 7 ++++++- WordPress/Sniffs/PHP/YodaConditionsSniff.php | 7 ++++++- WordPress/Sniffs/VIP/AdminBarRemovalSniff.php | 7 ++++++- WordPress/Sniffs/VIP/CronIntervalSniff.php | 7 ++++++- WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php | 7 ++++++- .../Sniffs/VIP/FileSystemWritesDisallowSniff.php | 7 ++++++- WordPress/Sniffs/VIP/OrderByRandSniff.php | 7 ++++++- WordPress/Sniffs/VIP/PluginMenuSlugSniff.php | 7 ++++++- WordPress/Sniffs/VIP/PostsPerPageSniff.php | 7 ++++++- WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php | 7 ++++++- WordPress/Sniffs/VIP/RestrictedVariablesSniff.php | 7 ++++++- WordPress/Sniffs/VIP/SessionFunctionsUsageSniff.php | 7 ++++++- WordPress/Sniffs/VIP/SessionVariableUsageSniff.php | 7 ++++++- WordPress/Sniffs/VIP/SlowDBQuerySniff.php | 7 ++++++- WordPress/Sniffs/VIP/SuperGlobalInputUsageSniff.php | 9 +++++++-- WordPress/Sniffs/VIP/TimezoneChangeSniff.php | 7 ++++++- WordPress/Sniffs/VIP/ValidatedSanitizedInputSniff.php | 11 ++++++++--- WordPress/Sniffs/Variables/GlobalVariablesSniff.php | 11 +++++++---- .../Sniffs/Variables/VariableRestrictionsSniff.php | 10 ++++++++-- WordPress/Sniffs/WP/AlternativeFunctionsSniff.php | 7 ++++++- WordPress/Sniffs/WP/CapitalPDangitSniff.php | 7 ++++++- WordPress/Sniffs/WP/DeprecatedClassesSniff.php | 7 ++++++- WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php | 7 ++++++- WordPress/Sniffs/WP/DeprecatedParametersSniff.php | 7 ++++++- WordPress/Sniffs/WP/DiscouragedFunctionsSniff.php | 7 ++++++- WordPress/Sniffs/WP/EnqueuedResourcesSniff.php | 7 ++++++- WordPress/Sniffs/WP/I18nSniff.php | 7 ++++++- WordPress/Sniffs/WP/PreparedSQLSniff.php | 7 ++++++- .../Sniffs/WhiteSpace/CastStructureSpacingSniff.php | 7 ++++++- .../WhiteSpace/ControlStructureSpacingSniff.php | 7 ++++++- .../Sniffs/WhiteSpace/DisallowInlineTabsSniff.php | 7 ++++++- WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php | 1 + WordPress/Sniffs/XSS/EscapeOutputSniff.php | 9 +++++++-- 63 files changed, 371 insertions(+), 77 deletions(-) diff --git a/WordPress/AbstractArrayAssignmentRestrictionsSniff.php b/WordPress/AbstractArrayAssignmentRestrictionsSniff.php index c5cf5fd8..b5558e14 100644 --- a/WordPress/AbstractArrayAssignmentRestrictionsSniff.php +++ b/WordPress/AbstractArrayAssignmentRestrictionsSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress; + +use WordPress\Sniff; + /** * Restricts array assignment of certain keys. * @@ -18,7 +22,7 @@ * `WordPress_Sniffs_Arrays_ArrayAssignmentRestrictionsSniff` to * `WordPress_AbstractArrayAssignmentRestrictionsSniff`. */ -abstract class WordPress_AbstractArrayAssignmentRestrictionsSniff extends WordPress_Sniff { +abstract class AbstractArrayAssignmentRestrictionsSniff extends Sniff { /** * Exclude groups. diff --git a/WordPress/AbstractClassRestrictionsSniff.php b/WordPress/AbstractClassRestrictionsSniff.php index c83dc7e6..b37cd490 100644 --- a/WordPress/AbstractClassRestrictionsSniff.php +++ b/WordPress/AbstractClassRestrictionsSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress; + +use WordPress\AbstractFunctionRestrictionsSniff; + /** * Restricts usage of some classes. * @@ -14,7 +18,7 @@ * * @since 0.10.0 */ -abstract class WordPress_AbstractClassRestrictionsSniff extends WordPress_AbstractFunctionRestrictionsSniff { +abstract class AbstractClassRestrictionsSniff extends AbstractFunctionRestrictionsSniff { /** * Regex pattern with placeholder for the class names. diff --git a/WordPress/AbstractFunctionParameterSniff.php b/WordPress/AbstractFunctionParameterSniff.php index f9e7fbc6..b201354a 100644 --- a/WordPress/AbstractFunctionParameterSniff.php +++ b/WordPress/AbstractFunctionParameterSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress; + +use WordPress\AbstractFunctionRestrictionsSniff; + /** * Advises about parameters used in function calls. * @@ -14,7 +18,7 @@ * * @since 0.11.0 */ -abstract class WordPress_AbstractFunctionParameterSniff extends WordPress_AbstractFunctionRestrictionsSniff { +abstract class AbstractFunctionParameterSniff extends AbstractFunctionRestrictionsSniff { /** * The group name for this group of functions. diff --git a/WordPress/AbstractFunctionRestrictionsSniff.php b/WordPress/AbstractFunctionRestrictionsSniff.php index 81fe126a..a607d21e 100644 --- a/WordPress/AbstractFunctionRestrictionsSniff.php +++ b/WordPress/AbstractFunctionRestrictionsSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress; + +use WordPress\Sniff; + /** * Restricts usage of some functions. * @@ -19,7 +23,7 @@ * `WordPress_AbstractFunctionRestrictionsSniff`. * @since 0.11.0 Extends the WordPress_Sniff class. */ -abstract class WordPress_AbstractFunctionRestrictionsSniff extends WordPress_Sniff { +abstract class AbstractFunctionRestrictionsSniff extends Sniff { /** * Exclude groups. diff --git a/WordPress/AbstractVariableRestrictionsSniff.php b/WordPress/AbstractVariableRestrictionsSniff.php index 324f4853..5ed71212 100644 --- a/WordPress/AbstractVariableRestrictionsSniff.php +++ b/WordPress/AbstractVariableRestrictionsSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress; + +use WordPress\Sniff; + /** * Restricts usage of some variables. * @@ -19,7 +23,7 @@ * `WordPress_AbstractVariableRestrictionsSniff`. * @since 0.11.0 Extends the WordPress_Sniff class. */ -abstract class WordPress_AbstractVariableRestrictionsSniff extends WordPress_Sniff { +abstract class AbstractVariableRestrictionsSniff extends Sniff { /** * Exclude groups. diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index e3746dc5..ec47c6dd 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -7,6 +7,8 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress; + /** * Represents a PHP_CodeSniffer sniff for sniffing WordPress coding standards. * @@ -26,7 +28,7 @@ * In the rare few cases where the array values *do* have meaning, this * is documented in the property documentation.}} */ -abstract class WordPress_Sniff implements PHP_CodeSniffer_Sniff { +abstract class Sniff implements PHP_CodeSniffer_Sniff { /** * List of the functions which verify nonces. diff --git a/WordPress/Sniffs/Arrays/ArrayAssignmentRestrictionsSniff.php b/WordPress/Sniffs/Arrays/ArrayAssignmentRestrictionsSniff.php index 5fbe91df..f48d1e2c 100644 --- a/WordPress/Sniffs/Arrays/ArrayAssignmentRestrictionsSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayAssignmentRestrictionsSniff.php @@ -7,21 +7,27 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\Arrays; + +use WordPress\AbstractArrayAssignmentRestrictionsSniff; + /** * Restricts array assignment of certain keys. * * @package WPCS\WordPressCodingStandards * * @since 0.3.0 + * @since 0.13.0 Class name changed: this class is now namespaced. + * * @deprecated 0.10.0 The functionality which used to be contained in this class has been moved to * the WordPress_AbstractArrayAssignmentRestrictionsSniff class. * This class is left here to prevent backward-compatibility breaks for * custom sniffs extending the old class and references to this * sniff from custom phpcs.xml files. * This file is also still used to unit test the abstract class. - * @see WordPress_AbstractArrayAssignmentRestrictionsSniff + * @see \WordPress\AbstractArrayAssignmentRestrictionsSniff */ -class WordPress_Sniffs_Arrays_ArrayAssignmentRestrictionsSniff extends WordPress_AbstractArrayAssignmentRestrictionsSniff { +class ArrayAssignmentRestrictionsSniff extends AbstractArrayAssignmentRestrictionsSniff { /** * Groups of variables to restrict. diff --git a/WordPress/Sniffs/Arrays/ArrayDeclarationSniff.php b/WordPress/Sniffs/Arrays/ArrayDeclarationSniff.php index b3fbb456..9f3e593d 100644 --- a/WordPress/Sniffs/Arrays/ArrayDeclarationSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayDeclarationSniff.php @@ -7,6 +7,8 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\Arrays; + /** * Enforces WordPress array format, based upon Squiz code. * @@ -19,6 +21,8 @@ * @since 0.11.0 The additional single-line array checks have been moved to their own * sniff WordPress.Arrays.ArrayDeclarationSpacing. * This class now only contains a slimmed down version of the upstream sniff. + * @since 0.13.0 Class name changed: this class is now namespaced. + * * @deprecated 0.13.0 This sniff has now been deprecated. Most checks which were previously * contained herein had recently been excluded in favour of dedicated * sniffs with higher precision. The last remaining checks which were not @@ -27,7 +31,7 @@ * This class is left here to prevent breaking custom rulesets which refer * to this sniff. */ -class WordPress_Sniffs_Arrays_ArrayDeclarationSniff { +class ArrayDeclarationSniff { /** * Don't use. diff --git a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php index 3d7c985c..36c075e1 100644 --- a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\Arrays; + +use WordPress\Sniff; + /** * Enforces WordPress array spacing format. * @@ -30,8 +34,9 @@ * @since 0.13.0 Added the last remaining checks from the `ArrayDeclaration` sniff * which were not covered elsewhere. The `ArrayDeclaration` sniff has * now been deprecated. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_Arrays_ArrayDeclarationSpacingSniff extends WordPress_Sniff { +class ArrayDeclarationSpacingSniff extends Sniff { /** * Token this sniff targets. diff --git a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php index 29fb9f60..9a679487 100644 --- a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\Arrays; + +use WordPress\Sniff; + /** * Enforces WordPress array indentation for multi-line arrays. * @@ -15,11 +19,12 @@ * @package WPCS\WordPressCodingStandards * * @since 0.12.0 + * @since 0.13.0 Class name changed: this class is now namespaced. * * {@internal This sniff should eventually be pulled upstream as part of a solution * for https://github.com/squizlabs/PHP_CodeSniffer/issues/582 }} */ -class WordPress_Sniffs_Arrays_ArrayIndentationSniff extends WordPress_Sniff { +class ArrayIndentationSniff extends Sniff { /** * Should tabs be used for indenting? diff --git a/WordPress/Sniffs/Arrays/ArrayKeySpacingRestrictionsSniff.php b/WordPress/Sniffs/Arrays/ArrayKeySpacingRestrictionsSniff.php index 851bf91e..73e38aa6 100644 --- a/WordPress/Sniffs/Arrays/ArrayKeySpacingRestrictionsSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayKeySpacingRestrictionsSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\Arrays; + +use WordPress\Sniff; + /** * Check for proper spacing in array key references. * @@ -17,8 +21,9 @@ * @since 0.3.0 * @since 0.7.0 This sniff now has the ability to fix a number of the issues it flags. * @since 0.12.0 This class now extends WordPress_Sniff. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_Arrays_ArrayKeySpacingRestrictionsSniff extends WordPress_Sniff { +class ArrayKeySpacingRestrictionsSniff extends Sniff { /** * Returns an array of tokens this test wants to listen for. diff --git a/WordPress/Sniffs/Arrays/CommaAfterArrayItemSniff.php b/WordPress/Sniffs/Arrays/CommaAfterArrayItemSniff.php index 04b5d566..f2ef8252 100644 --- a/WordPress/Sniffs/Arrays/CommaAfterArrayItemSniff.php +++ b/WordPress/Sniffs/Arrays/CommaAfterArrayItemSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\Arrays; + +use WordPress\Sniff; + /** * Enforces a comma after each array item and the spacing around it. * @@ -22,8 +26,9 @@ * @package WPCS\WordPressCodingStandards * * @since 0.12.0 + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_Arrays_CommaAfterArrayItemSniff extends WordPress_Sniff { +class CommaAfterArrayItemSniff extends Sniff { /** * Returns an array of tokens this test wants to listen for. diff --git a/WordPress/Sniffs/CSRF/NonceVerificationSniff.php b/WordPress/Sniffs/CSRF/NonceVerificationSniff.php index 215b67ea..d9828410 100644 --- a/WordPress/Sniffs/CSRF/NonceVerificationSniff.php +++ b/WordPress/Sniffs/CSRF/NonceVerificationSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\CSRF; + +use WordPress\Sniff; + /** * Checks that nonce verification accompanies form processing. * @@ -15,8 +19,9 @@ * @package WPCS\WordPressCodingStandards * * @since 0.5.0 + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_CSRF_NonceVerificationSniff extends WordPress_Sniff { +class NonceVerificationSniff extends Sniff { /** * Superglobals to notify about when not accompanied by an nonce check. diff --git a/WordPress/Sniffs/Classes/ClassInstantiationSniff.php b/WordPress/Sniffs/Classes/ClassInstantiationSniff.php index e2a646f5..2465a66c 100644 --- a/WordPress/Sniffs/Classes/ClassInstantiationSniff.php +++ b/WordPress/Sniffs/Classes/ClassInstantiationSniff.php @@ -7,10 +7,13 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\Classes; + +use WordPress\Sniff; + /** - * WordPress_Sniffs_Classes_ClassInstantiationSniff. - * * Verifies object instantiation statements. + * * - Demand the use of parenthesis. * - Demand no space between the class name and the parenthesis. * - Forbid assigning new by reference. @@ -21,8 +24,9 @@ * @package WPCS\WordPressCodingStandards * * @since 0.12.0 + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_Classes_ClassInstantiationSniff extends WordPress_Sniff { +class ClassInstantiationSniff extends Sniff { /** * A list of tokenizers this sniff supports. diff --git a/WordPress/Sniffs/CodeAnalysis/EmptyStatementSniff.php b/WordPress/Sniffs/CodeAnalysis/EmptyStatementSniff.php index 07ad7d47..3778fd03 100644 --- a/WordPress/Sniffs/CodeAnalysis/EmptyStatementSniff.php +++ b/WordPress/Sniffs/CodeAnalysis/EmptyStatementSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\CodeAnalysis; + +use WordPress\Sniff; + /** * Checks against empty statements. * @@ -22,8 +26,9 @@ * @package WPCS\WordPressCodingStandards * * @since 0.12.0 + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_CodeAnalysis_EmptyStatementSniff extends WordPress_Sniff { +class EmptyStatementSniff extends Sniff { /** * Returns an array of tokens this test wants to listen for. diff --git a/WordPress/Sniffs/DB/RestrictedClassesSniff.php b/WordPress/Sniffs/DB/RestrictedClassesSniff.php index 37ca463e..1083c86c 100644 --- a/WordPress/Sniffs/DB/RestrictedClassesSniff.php +++ b/WordPress/Sniffs/DB/RestrictedClassesSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\DB; + +use WordPress\AbstractClassRestrictionsSniff; + /** * Verifies that no database related PHP classes are used. * @@ -20,8 +24,9 @@ * @package WPCS\WordPressCodingStandards * * @since 0.10.0 + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_DB_RestrictedClassesSniff extends WordPress_AbstractClassRestrictionsSniff { +class RestrictedClassesSniff extends AbstractClassRestrictionsSniff { /** * Groups of classes to restrict. diff --git a/WordPress/Sniffs/DB/RestrictedFunctionsSniff.php b/WordPress/Sniffs/DB/RestrictedFunctionsSniff.php index 56a84f78..557d5771 100644 --- a/WordPress/Sniffs/DB/RestrictedFunctionsSniff.php +++ b/WordPress/Sniffs/DB/RestrictedFunctionsSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\DB; + +use WordPress\AbstractFunctionRestrictionsSniff; + /** * Verifies that no database related PHP functions are used. * @@ -20,8 +24,9 @@ * @package WPCS\WordPressCodingStandards * * @since 0.10.0 + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_DB_RestrictedFunctionsSniff extends WordPress_AbstractFunctionRestrictionsSniff { +class RestrictedFunctionsSniff extends AbstractFunctionRestrictionsSniff { /** * Groups of functions to restrict. diff --git a/WordPress/Sniffs/Files/FileNameSniff.php b/WordPress/Sniffs/Files/FileNameSniff.php index cec2fa4f..624edc49 100644 --- a/WordPress/Sniffs/Files/FileNameSniff.php +++ b/WordPress/Sniffs/Files/FileNameSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\Files; + +use WordPress\Sniff; + /** * Ensures filenames do not contain underscores. * @@ -22,10 +26,11 @@ * - This sniff will now allow for underscores in file names for certain theme * specific exceptions if the `$is_theme` property is set to `true`. * @since 0.12.0 - Now extends the `WordPress_Sniff` class. + * @since 0.13.0 Class name changed: this class is now namespaced. * - * @uses WordPress_Sniff::$custom_test_class_whitelist + * @uses \WordPress\Sniff::$custom_test_class_whitelist */ -class WordPress_Sniffs_Files_FileNameSniff extends WordPress_Sniff { +class FileNameSniff extends Sniff { /** * Regex for the theme specific exceptions. diff --git a/WordPress/Sniffs/Functions/DontExtractSniff.php b/WordPress/Sniffs/Functions/DontExtractSniff.php index 3cf94991..026e6cc5 100644 --- a/WordPress/Sniffs/Functions/DontExtractSniff.php +++ b/WordPress/Sniffs/Functions/DontExtractSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\Functions; + +use WordPress\AbstractFunctionRestrictionsSniff; + /** * Restricts the usage of extract(). * @@ -15,8 +19,9 @@ * @package WPCS\WordPressCodingStandards * * @since 0.10.0 Previously this check was contained within WordPress_Sniffs_VIP_RestrictedFunctionsSniff. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_Functions_DontExtractSniff extends WordPress_AbstractFunctionRestrictionsSniff { +class DontExtractSniff extends AbstractFunctionRestrictionsSniff { /** * Groups of functions to restrict. diff --git a/WordPress/Sniffs/Functions/FunctionCallSignatureNoParamsSniff.php b/WordPress/Sniffs/Functions/FunctionCallSignatureNoParamsSniff.php index 1d9bcafc..0f94a1f1 100644 --- a/WordPress/Sniffs/Functions/FunctionCallSignatureNoParamsSniff.php +++ b/WordPress/Sniffs/Functions/FunctionCallSignatureNoParamsSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\Functions; + +use WordPress\Sniff; + /** * Enforces no whitespace between the parenthesis of a function call without parameters. * @@ -15,8 +19,9 @@ * @package WPCS\WordPressCodingStandards * * @since 0.12.0 + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_Functions_FunctionCallSignatureNoParamsSniff extends WordPress_Sniff { +class FunctionCallSignatureNoParamsSniff extends Sniff { /** * Returns an array of tokens this test wants to listen for. diff --git a/WordPress/Sniffs/Functions/FunctionRestrictionsSniff.php b/WordPress/Sniffs/Functions/FunctionRestrictionsSniff.php index 483e6cb0..af829d27 100644 --- a/WordPress/Sniffs/Functions/FunctionRestrictionsSniff.php +++ b/WordPress/Sniffs/Functions/FunctionRestrictionsSniff.php @@ -7,20 +7,26 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\Functions; + +use WordPress\AbstractFunctionRestrictionsSniff; + /** * Restricts usage of some functions. * * @package WPCS\WordPressCodingStandards * * @since 0.3.0 + * @since 0.13.0 Class name changed: this class is now namespaced. + * * @deprecated 0.10.0 The functionality which used to be contained in this class has been moved to * the WordPress_AbstractFunctionRestrictionsSniff class. * This class is left here to prevent backward-compatibility breaks for * custom sniffs extending the old class and references to this * sniff from custom phpcs.xml files. - * @see WordPress_AbstractFunctionRestrictionsSniff + * @see \WordPress\AbstractFunctionRestrictionsSniff */ -class WordPress_Sniffs_Functions_FunctionRestrictionsSniff extends WordPress_AbstractFunctionRestrictionsSniff { +class FunctionRestrictionsSniff extends AbstractFunctionRestrictionsSniff { /** * Groups of functions to restrict. diff --git a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php index 856aed26..fecbac87 100644 --- a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php +++ b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php @@ -7,16 +7,21 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\NamingConventions; + +use WordPress\AbstractFunctionParameterSniff; + /** * Verify that everything defined in the global namespace is prefixed with a theme/plugin specific prefix. * * @package WPCS\WordPressCodingStandards * * @since 0.12.0 + * @since 0.13.0 Class name changed: this class is now namespaced. * - * @uses WordPress_Sniff::$custom_test_class_whitelist + * @uses \WordPress\Sniff::$custom_test_class_whitelist */ -class WordPress_Sniffs_NamingConventions_PrefixAllGlobalsSniff extends WordPress_AbstractFunctionParameterSniff { +class PrefixAllGlobalsSniff extends AbstractFunctionParameterSniff { /** * Error message template. diff --git a/WordPress/Sniffs/NamingConventions/ValidFunctionNameSniff.php b/WordPress/Sniffs/NamingConventions/ValidFunctionNameSniff.php index d23effcc..d4b5f3a9 100644 --- a/WordPress/Sniffs/NamingConventions/ValidFunctionNameSniff.php +++ b/WordPress/Sniffs/NamingConventions/ValidFunctionNameSniff.php @@ -19,6 +19,7 @@ * @package WPCS\WordPressCodingStandards * * @since 0.1.0 + * @since 0.13.0 Class name changed: this class is now namespaced. * * Last synced with parent class July 2016 up to commit 4fea2e651109e41066a81e22e004d851fb1287f6. * @link https://github.com/squizlabs/PHP_CodeSniffer/blob/master/CodeSniffer/Standards/PEAR/Sniffs/NamingConventions/ValidFunctionNameSniff.php diff --git a/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php b/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php index bc4b1361..0974b7d7 100644 --- a/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php +++ b/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\NamingConventions; + +use WordPress\AbstractFunctionParameterSniff; + /** * Use lowercase letters in action and filter names. Separate words via underscores. * @@ -21,8 +25,9 @@ * * @since 0.10.0 * @since 0.11.0 Extends the WordPress_AbstractFunctionParameterSniff class. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_NamingConventions_ValidHookNameSniff extends WordPress_AbstractFunctionParameterSniff { +class ValidHookNameSniff extends AbstractFunctionParameterSniff { /** * Additional word separators. diff --git a/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php b/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php index 55a353b7..deac96a7 100644 --- a/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php +++ b/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php @@ -10,6 +10,7 @@ if ( ! class_exists( 'PHP_CodeSniffer_Standards_AbstractVariableSniff', true ) ) { throw new PHP_CodeSniffer_Exception( 'Class PHP_CodeSniffer_Standards_AbstractVariableSniff not found' ); } +use WordPress\Sniff; /** * Checks the naming of variables and member variables. @@ -19,6 +20,7 @@ * @package WPCS\WordPressCodingStandards * * @since 0.9.0 + * @since 0.13.0 Class name changed: this class is now namespaced. * * Last synced with base class July 2014 at commit ed257ca0e56ad86cd2a4d6fa38ce0b95141c824f. * @link https://github.com/squizlabs/PHP_CodeSniffer/blob/master/CodeSniffer/Standards/Squiz/Sniffs/NamingConventions/ValidVariableNameSniff.php @@ -301,10 +303,10 @@ protected function mergeWhiteList( $phpcs_file ) { || $this->customVariablesWhitelist !== $this->addedCustomProperties['variables'] ) { // Fix property potentially passed as comma-delimited string. - $customProperties = WordPress_Sniff::merge_custom_array( $this->customPropertiesWhitelist, array(), false ); + $customProperties = Sniff::merge_custom_array( $this->customPropertiesWhitelist, array(), false ); if ( ! empty( $this->customVariablesWhitelist ) ) { - $customProperties = WordPress_Sniff::merge_custom_array( + $customProperties = Sniff::merge_custom_array( $this->customVariablesWhitelist, $customProperties, false @@ -317,7 +319,7 @@ protected function mergeWhiteList( $phpcs_file ) { ); } - $this->whitelisted_mixed_case_member_var_names = WordPress_Sniff::merge_custom_array( + $this->whitelisted_mixed_case_member_var_names = Sniff::merge_custom_array( $customProperties, $this->whitelisted_mixed_case_member_var_names ); diff --git a/WordPress/Sniffs/PHP/DevelopmentFunctionsSniff.php b/WordPress/Sniffs/PHP/DevelopmentFunctionsSniff.php index bf2e8365..a38d190c 100644 --- a/WordPress/Sniffs/PHP/DevelopmentFunctionsSniff.php +++ b/WordPress/Sniffs/PHP/DevelopmentFunctionsSniff.php @@ -7,14 +7,19 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\PHP; + +use WordPress\AbstractFunctionRestrictionsSniff; + /** * Restrict the use of various development functions. * * @package WPCS\WordPressCodingStandards * * @since 0.11.0 + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_PHP_DevelopmentFunctionsSniff extends WordPress_AbstractFunctionRestrictionsSniff { +class DevelopmentFunctionsSniff extends AbstractFunctionRestrictionsSniff { /** * Groups of functions to restrict. diff --git a/WordPress/Sniffs/PHP/DiscouragedFunctionsSniff.php b/WordPress/Sniffs/PHP/DiscouragedFunctionsSniff.php index e141eb94..cef9e831 100644 --- a/WordPress/Sniffs/PHP/DiscouragedFunctionsSniff.php +++ b/WordPress/Sniffs/PHP/DiscouragedFunctionsSniff.php @@ -7,6 +7,8 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\PHP; + /** * Discourages the use of various native PHP functions and suggests alternatives. * @@ -15,6 +17,8 @@ * @since 0.1.0 * @since 0.10.0 The checks for the POSIX functions have been replaced by the stand-alone * sniff WordPress_Sniffs_PHP_POSIXFunctionsSniff. + * @since 0.13.0 Class name changed: this class is now namespaced. + * * @deprecated 0.11.0 The checks for the PHP development functions have been replaced by the * stand-alone sniff WordPress_Sniffs_PHP_DevelopmentFunctionsSniff. * The checks for the WP deprecated functions have been replaced by the @@ -29,7 +33,7 @@ * function. To check for `register_globals` ini directive use * PHPCompatibility_Sniffs_PHP_DeprecatedIniDirectivesSniff from wimg/PHPCompatibility. */ -class WordPress_Sniffs_PHP_DiscouragedFunctionsSniff { +class DiscouragedFunctionsSniff { /** * Don't use. diff --git a/WordPress/Sniffs/PHP/DiscouragedPHPFunctionsSniff.php b/WordPress/Sniffs/PHP/DiscouragedPHPFunctionsSniff.php index 4b8ca5c4..a6e12e13 100644 --- a/WordPress/Sniffs/PHP/DiscouragedPHPFunctionsSniff.php +++ b/WordPress/Sniffs/PHP/DiscouragedPHPFunctionsSniff.php @@ -7,14 +7,19 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\PHP; + +use WordPress\AbstractFunctionRestrictionsSniff; + /** * Discourages the use of various native PHP functions and suggests alternatives. * * @package WPCS\WordPressCodingStandards * * @since 0.11.0 + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_PHP_DiscouragedPHPFunctionsSniff extends WordPress_AbstractFunctionRestrictionsSniff { +class DiscouragedPHPFunctionsSniff extends AbstractFunctionRestrictionsSniff { /** * Groups of functions to discourage. diff --git a/WordPress/Sniffs/PHP/POSIXFunctionsSniff.php b/WordPress/Sniffs/PHP/POSIXFunctionsSniff.php index 936bdedf..cab71a4e 100644 --- a/WordPress/Sniffs/PHP/POSIXFunctionsSniff.php +++ b/WordPress/Sniffs/PHP/POSIXFunctionsSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\PHP; + +use WordPress\AbstractFunctionRestrictionsSniff; + /** * Perl compatible regular expressions (PCRE, preg_ functions) should be used in preference * to their POSIX counterparts. @@ -18,8 +22,9 @@ * * @since 0.10.0 Previously this check was contained within WordPress_Sniffs_VIP_RestrictedFunctionsSniff * and the WordPress_Sniffs_PHP_DiscouragedPHPFunctionsSniff. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_PHP_POSIXFunctionsSniff extends WordPress_AbstractFunctionRestrictionsSniff { +class POSIXFunctionsSniff extends AbstractFunctionRestrictionsSniff { /** * Groups of functions to restrict. diff --git a/WordPress/Sniffs/PHP/StrictComparisonsSniff.php b/WordPress/Sniffs/PHP/StrictComparisonsSniff.php index c87d9a0b..e24b98b4 100644 --- a/WordPress/Sniffs/PHP/StrictComparisonsSniff.php +++ b/WordPress/Sniffs/PHP/StrictComparisonsSniff.php @@ -7,19 +7,24 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\PHP; + +use WordPress\Sniff; + /** * Enforces Strict Comparison checks, based upon Squiz code. * * @package WPCS\WordPressCodingStandards * * @since 0.4.0 + * @since 0.13.0 Class name changed: this class is now namespaced. * * Last synced with base class ?[unknown date]? at commit ?[unknown commit]?. * It is currently unclear whether this sniff is actually based on Squiz code on whether the above * reference to it is a copy/paste oversight. * @link Possibly: https://github.com/squizlabs/PHP_CodeSniffer/blob/master/CodeSniffer/Standards/Squiz/Sniffs/Operators/ComparisonOperatorUsageSniff.php */ -class WordPress_Sniffs_PHP_StrictComparisonsSniff extends WordPress_Sniff { +class StrictComparisonsSniff extends Sniff { /** * Returns an array of tokens this test wants to listen for. diff --git a/WordPress/Sniffs/PHP/StrictInArraySniff.php b/WordPress/Sniffs/PHP/StrictInArraySniff.php index cc67f244..45a68b9e 100644 --- a/WordPress/Sniffs/PHP/StrictInArraySniff.php +++ b/WordPress/Sniffs/PHP/StrictInArraySniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\PHP; + +use WordPress\AbstractFunctionParameterSniff; + /** * Flag calling in_array(), array_search() and array_keys() without true as the third parameter. * @@ -19,8 +23,9 @@ * The sniff no longer needlessly extends the WordPress_Sniffs_Arrays_ArrayAssignmentRestrictionsSniff * which it didn't use. * @since 0.11.0 Refactored to extend the new WordPress_AbstractFunctionParameterSniff. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_PHP_StrictInArraySniff extends WordPress_AbstractFunctionParameterSniff { +class StrictInArraySniff extends AbstractFunctionParameterSniff { /** * The group name for this group of functions. diff --git a/WordPress/Sniffs/PHP/YodaConditionsSniff.php b/WordPress/Sniffs/PHP/YodaConditionsSniff.php index 8cf7e996..dda70d79 100644 --- a/WordPress/Sniffs/PHP/YodaConditionsSniff.php +++ b/WordPress/Sniffs/PHP/YodaConditionsSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\PHP; + +use WordPress\Sniff; + /** * Enforces Yoda conditional statements. * @@ -16,8 +20,9 @@ * * @since 0.3.0 * @since 0.12.0 This class now extends WordPress_Sniff. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_PHP_YodaConditionsSniff extends WordPress_Sniff { +class YodaConditionsSniff extends Sniff { /** * The tokens that indicate the start of a condition. diff --git a/WordPress/Sniffs/VIP/AdminBarRemovalSniff.php b/WordPress/Sniffs/VIP/AdminBarRemovalSniff.php index 0dd2c5c4..a9343d62 100644 --- a/WordPress/Sniffs/VIP/AdminBarRemovalSniff.php +++ b/WordPress/Sniffs/VIP/AdminBarRemovalSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\VIP; + +use WordPress\AbstractFunctionParameterSniff; + /** * Discourages removal of the admin bar. * @@ -18,8 +22,9 @@ * @since 0.11.0 - Extends the WordPress_AbstractFunctionParameterSniff class. * - Added the $remove_only property. * - Now also sniffs for manipulation of the admin bar visibility through CSS. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_VIP_AdminBarRemovalSniff extends WordPress_AbstractFunctionParameterSniff { +class AdminBarRemovalSniff extends AbstractFunctionParameterSniff { /** * A list of tokenizers this sniff supports. diff --git a/WordPress/Sniffs/VIP/CronIntervalSniff.php b/WordPress/Sniffs/VIP/CronIntervalSniff.php index 1c255a5a..1c30f478 100644 --- a/WordPress/Sniffs/VIP/CronIntervalSniff.php +++ b/WordPress/Sniffs/VIP/CronIntervalSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\VIP; + +use WordPress\Sniff; + /** * Flag cron schedules less than 15 minutes. * @@ -17,8 +21,9 @@ * @since 0.3.0 * @since 0.11.0 - Extends the WordPress_Sniff class. * - Now deals correctly with WP time constants. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_VIP_CronIntervalSniff extends WordPress_Sniff { +class CronIntervalSniff extends Sniff { /** * Known WP Time constant names and their value. diff --git a/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php b/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php index eb92de37..a7aa8444 100644 --- a/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php +++ b/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\VIP; + +use WordPress\Sniff; + /** * Flag Database direct queries. * @@ -18,8 +22,9 @@ * @since 0.3.0 * @since 0.6.0 Removed the add_unique_message() function as it is no longer needed. * @since 0.11.0 This class now extends WordPress_Sniff. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_VIP_DirectDatabaseQuerySniff extends WordPress_Sniff { +class DirectDatabaseQuerySniff extends Sniff { /** * List of custom cache get functions. diff --git a/WordPress/Sniffs/VIP/FileSystemWritesDisallowSniff.php b/WordPress/Sniffs/VIP/FileSystemWritesDisallowSniff.php index e535328f..104a71a4 100644 --- a/WordPress/Sniffs/VIP/FileSystemWritesDisallowSniff.php +++ b/WordPress/Sniffs/VIP/FileSystemWritesDisallowSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\VIP; + +use WordPress\AbstractFunctionRestrictionsSniff; + /** * Disallow Filesystem writes. * @@ -17,8 +21,9 @@ * @since 0.3.0 * @since 0.11.0 Extends the WordPress_AbstractFunctionRestrictionsSniff instead of the * Generic_Sniffs_PHP_ForbiddenFunctionsSniff. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_VIP_FileSystemWritesDisallowSniff extends WordPress_AbstractFunctionRestrictionsSniff { +class FileSystemWritesDisallowSniff extends AbstractFunctionRestrictionsSniff { /** * If true, an error will be thrown; otherwise a warning. diff --git a/WordPress/Sniffs/VIP/OrderByRandSniff.php b/WordPress/Sniffs/VIP/OrderByRandSniff.php index 158a1131..e592a989 100644 --- a/WordPress/Sniffs/VIP/OrderByRandSniff.php +++ b/WordPress/Sniffs/VIP/OrderByRandSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\VIP; + +use WordPress\AbstractArrayAssignmentRestrictionsSniff; + /** * Flag using orderby => rand. * @@ -15,8 +19,9 @@ * @package WPCS\WordPressCodingStandards * * @since 0.9.0 + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_VIP_OrderByRandSniff extends WordPress_AbstractArrayAssignmentRestrictionsSniff { +class OrderByRandSniff extends AbstractArrayAssignmentRestrictionsSniff { /** * Groups of variables to restrict. diff --git a/WordPress/Sniffs/VIP/PluginMenuSlugSniff.php b/WordPress/Sniffs/VIP/PluginMenuSlugSniff.php index e99b0b20..655d9e79 100644 --- a/WordPress/Sniffs/VIP/PluginMenuSlugSniff.php +++ b/WordPress/Sniffs/VIP/PluginMenuSlugSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\VIP; + +use WordPress\AbstractFunctionParameterSniff; + /** * Warn about __FILE__ for page registration. * @@ -16,8 +20,9 @@ * * @since 0.3.0 * @since 0.11.0 Refactored to extend the new WordPress_AbstractFunctionParameterSniff. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_VIP_PluginMenuSlugSniff extends WordPress_AbstractFunctionParameterSniff { +class PluginMenuSlugSniff extends AbstractFunctionParameterSniff { /** * The group name for this group of functions. diff --git a/WordPress/Sniffs/VIP/PostsPerPageSniff.php b/WordPress/Sniffs/VIP/PostsPerPageSniff.php index 6db73490..d4f28adc 100644 --- a/WordPress/Sniffs/VIP/PostsPerPageSniff.php +++ b/WordPress/Sniffs/VIP/PostsPerPageSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\VIP; + +use WordPress\AbstractArrayAssignmentRestrictionsSniff; + /** * Flag returning high or infinite posts_per_page. * @@ -15,8 +19,9 @@ * @package WPCS\WordPressCodingStandards * * @since 0.3.0 + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_VIP_PostsPerPageSniff extends WordPress_AbstractArrayAssignmentRestrictionsSniff { +class PostsPerPageSniff extends AbstractArrayAssignmentRestrictionsSniff { /** * Groups of variables to restrict. diff --git a/WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php b/WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php index cb58395a..41914ec2 100644 --- a/WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php +++ b/WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\VIP; + +use WordPress\AbstractFunctionRestrictionsSniff; + /** * Restricts usage of some functions in VIP context. * @@ -24,8 +28,9 @@ * The check for `parse_url()` and `curl_*` have been moved to the stand-alone sniff * WordPress_Sniffs_WP_AlternativeFunctionsSniff. * The check for `eval()` now defers to the upstream Squiz.PHP.Eval sniff. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_VIP_RestrictedFunctionsSniff extends WordPress_AbstractFunctionRestrictionsSniff { +class RestrictedFunctionsSniff extends AbstractFunctionRestrictionsSniff { /** * Groups of functions to restrict. diff --git a/WordPress/Sniffs/VIP/RestrictedVariablesSniff.php b/WordPress/Sniffs/VIP/RestrictedVariablesSniff.php index d184daed..05737ceb 100644 --- a/WordPress/Sniffs/VIP/RestrictedVariablesSniff.php +++ b/WordPress/Sniffs/VIP/RestrictedVariablesSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\VIP; + +use WordPress\AbstractVariableRestrictionsSniff; + /** * Restricts usage of some variables in VIP context. * @@ -15,8 +19,9 @@ * @package WPCS\WordPressCodingStandards * * @since 0.3.0 + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_VIP_RestrictedVariablesSniff extends WordPress_AbstractVariableRestrictionsSniff { +class RestrictedVariablesSniff extends AbstractVariableRestrictionsSniff { /** * Groups of variables to restrict. diff --git a/WordPress/Sniffs/VIP/SessionFunctionsUsageSniff.php b/WordPress/Sniffs/VIP/SessionFunctionsUsageSniff.php index 96ed685c..9ae5c0f1 100644 --- a/WordPress/Sniffs/VIP/SessionFunctionsUsageSniff.php +++ b/WordPress/Sniffs/VIP/SessionFunctionsUsageSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\VIP; + +use WordPress\AbstractFunctionRestrictionsSniff; + /** * Discourages the use of session functions. * @@ -17,8 +21,9 @@ * @since 0.3.0 * @since 0.11.0 Extends the WordPress_AbstractFunctionRestrictionsSniff instead of the * Generic_Sniffs_PHP_ForbiddenFunctionsSniff. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_VIP_SessionFunctionsUsageSniff extends WordPress_AbstractFunctionRestrictionsSniff { +class SessionFunctionsUsageSniff extends AbstractFunctionRestrictionsSniff { /** * Groups of functions to restrict. diff --git a/WordPress/Sniffs/VIP/SessionVariableUsageSniff.php b/WordPress/Sniffs/VIP/SessionVariableUsageSniff.php index f4b48639..74edbef6 100644 --- a/WordPress/Sniffs/VIP/SessionVariableUsageSniff.php +++ b/WordPress/Sniffs/VIP/SessionVariableUsageSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\VIP; + +use WordPress\Sniff; + /** * Discourages the use of the session variable. * Creating a session writes a file to the server and is unreliable in a multi-server environment. @@ -19,8 +23,9 @@ * @since 0.10.0 The sniff no longer needlessly extends the Generic_Sniffs_PHP_ForbiddenFunctionsSniff * which it didn't use. * @since 0.12.0 This class now extends WordPress_Sniff. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_VIP_SessionVariableUsageSniff extends WordPress_Sniff { +class SessionVariableUsageSniff extends Sniff { /** * Returns an array of tokens this test wants to listen for. diff --git a/WordPress/Sniffs/VIP/SlowDBQuerySniff.php b/WordPress/Sniffs/VIP/SlowDBQuerySniff.php index 9485cd41..d3b022fe 100644 --- a/WordPress/Sniffs/VIP/SlowDBQuerySniff.php +++ b/WordPress/Sniffs/VIP/SlowDBQuerySniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\VIP; + +use WordPress\AbstractArrayAssignmentRestrictionsSniff; + /** * Flag potentially slow queries. * @@ -18,8 +22,9 @@ * @since 0.12.0 Introduced new and more intuitively named 'slow query' whitelist * comment, replacing the 'tax_query' whitelist comment which is now * deprecated. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_VIP_SlowDBQuerySniff extends WordPress_AbstractArrayAssignmentRestrictionsSniff { +class SlowDBQuerySniff extends AbstractArrayAssignmentRestrictionsSniff { /** * Groups of variables to restrict. diff --git a/WordPress/Sniffs/VIP/SuperGlobalInputUsageSniff.php b/WordPress/Sniffs/VIP/SuperGlobalInputUsageSniff.php index 5c492065..c3b77372 100644 --- a/WordPress/Sniffs/VIP/SuperGlobalInputUsageSniff.php +++ b/WordPress/Sniffs/VIP/SuperGlobalInputUsageSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\VIP; + +use WordPress\Sniff; + /** * Flag any usage of super global input var ( _GET / _POST / etc. ). * @@ -15,9 +19,10 @@ * @package WPCS\WordPressCodingStandards * * @since 0.3.0 - * @since 0.4.0 This class now extends WordPress_Sniff. + * @since 0.4.0 This class now extends WordPress_Sniff. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_VIP_SuperGlobalInputUsageSniff extends WordPress_Sniff { +class SuperGlobalInputUsageSniff extends Sniff { /** * Returns an array of tokens this test wants to listen for. diff --git a/WordPress/Sniffs/VIP/TimezoneChangeSniff.php b/WordPress/Sniffs/VIP/TimezoneChangeSniff.php index 2fe0fc1c..5740f9eb 100644 --- a/WordPress/Sniffs/VIP/TimezoneChangeSniff.php +++ b/WordPress/Sniffs/VIP/TimezoneChangeSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\VIP; + +use WordPress\AbstractFunctionRestrictionsSniff; + /** * Disallow the changing of timezone. * @@ -17,8 +21,9 @@ * @since 0.3.0 * @since 0.11.0 Extends the WordPress_AbstractFunctionRestrictionsSniff instead of the * Generic_Sniffs_PHP_ForbiddenFunctionsSniff. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_VIP_TimezoneChangeSniff extends WordPress_AbstractFunctionRestrictionsSniff { +class TimezoneChangeSniff extends AbstractFunctionRestrictionsSniff { /** * Groups of functions to restrict. diff --git a/WordPress/Sniffs/VIP/ValidatedSanitizedInputSniff.php b/WordPress/Sniffs/VIP/ValidatedSanitizedInputSniff.php index 3edc5754..04a5e870 100644 --- a/WordPress/Sniffs/VIP/ValidatedSanitizedInputSniff.php +++ b/WordPress/Sniffs/VIP/ValidatedSanitizedInputSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\VIP; + +use WordPress\Sniff; + /** * Flag any non-validated/sanitized input ( _GET / _POST / etc. ). * @@ -15,10 +19,11 @@ * @package WPCS\WordPressCodingStandards * * @since 0.3.0 - * @since 0.4.0 This class now extends WordPress_Sniff. - * @since 0.5.0 Method getArrayIndexKey() has been moved to WordPress_Sniff. + * @since 0.4.0 This class now extends WordPress_Sniff. + * @since 0.5.0 Method getArrayIndexKey() has been moved to WordPress_Sniff. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_VIP_ValidatedSanitizedInputSniff extends WordPress_Sniff { +class ValidatedSanitizedInputSniff extends Sniff { /** * Check for validation functions for a variable within its own parenthesis only. diff --git a/WordPress/Sniffs/Variables/GlobalVariablesSniff.php b/WordPress/Sniffs/Variables/GlobalVariablesSniff.php index 55214417..68386b7c 100644 --- a/WordPress/Sniffs/Variables/GlobalVariablesSniff.php +++ b/WordPress/Sniffs/Variables/GlobalVariablesSniff.php @@ -7,9 +7,11 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\Variables; + +use WordPress\Sniff; + /** - * WordPress_Sniffs_Variables_GlobalVariablesSniff. - * * Warns about overwriting WordPress native global variables. * * @package WPCS\WordPressCodingStandards @@ -17,10 +19,11 @@ * @since 0.3.0 * @since 0.4.0 This class now extends WordPress_Sniff. * @since 0.12.0 The $wp_globals property has been moved to the WordPress_Sniff. + * @since 0.13.0 Class name changed: this class is now namespaced. * - * @uses WordPress_Sniff::$custom_test_class_whitelist + * @uses \WordPress\Sniff::$custom_test_class_whitelist */ -class WordPress_Sniffs_Variables_GlobalVariablesSniff extends WordPress_Sniff { +class GlobalVariablesSniff extends Sniff { /** * Returns an array of tokens this test wants to listen for. diff --git a/WordPress/Sniffs/Variables/VariableRestrictionsSniff.php b/WordPress/Sniffs/Variables/VariableRestrictionsSniff.php index f28a07af..9b85e725 100644 --- a/WordPress/Sniffs/Variables/VariableRestrictionsSniff.php +++ b/WordPress/Sniffs/Variables/VariableRestrictionsSniff.php @@ -7,21 +7,27 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\Variables; + +use WordPress\AbstractVariableRestrictionsSniff; + /** * Restricts usage of some variables. * * @package WPCS\WordPressCodingStandards * * @since 0.3.0 + * @since 0.13.0 Class name changed: this class is now namespaced. + * * @deprecated 0.10.0 The functionality which used to be contained in this class has been moved to * the WordPress_AbstractVariableRestrictionsSniff class. * This class is left here to prevent backward-compatibility breaks for * custom sniffs extending the old class and references to this * sniff from custom phpcs.xml files. * This file is also still used to unit test the abstract class. - * @see WordPress_AbstractVariableRestrictionsSniff + * @see \WordPress\AbstractVariableRestrictionsSniff */ -class WordPress_Sniffs_Variables_VariableRestrictionsSniff extends WordPress_AbstractVariableRestrictionsSniff { +class VariableRestrictionsSniff extends AbstractVariableRestrictionsSniff { /** * Groups of variables to restrict. diff --git a/WordPress/Sniffs/WP/AlternativeFunctionsSniff.php b/WordPress/Sniffs/WP/AlternativeFunctionsSniff.php index 7deda9d7..e96d41a5 100644 --- a/WordPress/Sniffs/WP/AlternativeFunctionsSniff.php +++ b/WordPress/Sniffs/WP/AlternativeFunctionsSniff.php @@ -7,14 +7,19 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\WP; + +use WordPress\AbstractFunctionRestrictionsSniff; + /** * Discourages the use of various functions and suggests (WordPress) alternatives. * * @package WPCS\WordPressCodingStandards * * @since 0.11.0 + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_WP_AlternativeFunctionsSniff extends WordPress_AbstractFunctionRestrictionsSniff { +class AlternativeFunctionsSniff extends AbstractFunctionRestrictionsSniff { /** * Groups of functions to restrict. diff --git a/WordPress/Sniffs/WP/CapitalPDangitSniff.php b/WordPress/Sniffs/WP/CapitalPDangitSniff.php index b80964d9..b2ead93d 100644 --- a/WordPress/Sniffs/WP/CapitalPDangitSniff.php +++ b/WordPress/Sniffs/WP/CapitalPDangitSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\WP; + +use WordPress\Sniff; + /** * Capital P Dangit! * @@ -15,8 +19,9 @@ * @package WPCS\WordPressCodingStandards * * @since 0.12.0 + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_WP_CapitalPDangitSniff extends WordPress_Sniff { +class CapitalPDangitSniff extends Sniff { /** * Regex to match a large number or spelling variations of WordPress in text strings. diff --git a/WordPress/Sniffs/WP/DeprecatedClassesSniff.php b/WordPress/Sniffs/WP/DeprecatedClassesSniff.php index 3145c821..05d0428f 100644 --- a/WordPress/Sniffs/WP/DeprecatedClassesSniff.php +++ b/WordPress/Sniffs/WP/DeprecatedClassesSniff.php @@ -7,14 +7,19 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\WP; + +use WordPress\AbstractClassRestrictionsSniff; + /** * Restricts the use of deprecated WordPress classes and suggests alternatives. * * @package WPCS\WordPressCodingStandards * * @since 0.12.0 + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_WP_DeprecatedClassesSniff extends WordPress_AbstractClassRestrictionsSniff { +class DeprecatedClassesSniff extends AbstractClassRestrictionsSniff { /** * Minimum WordPress version. diff --git a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php index 1604e175..d2cc7491 100644 --- a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php +++ b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php @@ -7,14 +7,19 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\WP; + +use WordPress\AbstractFunctionRestrictionsSniff; + /** * Restricts the use of various deprecated WordPress functions and suggests alternatives. * * @package WPCS\WordPressCodingStandards * * @since 0.11.0 + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_WP_DeprecatedFunctionsSniff extends WordPress_AbstractFunctionRestrictionsSniff { +class DeprecatedFunctionsSniff extends AbstractFunctionRestrictionsSniff { /** * Minimum WordPress version. diff --git a/WordPress/Sniffs/WP/DeprecatedParametersSniff.php b/WordPress/Sniffs/WP/DeprecatedParametersSniff.php index c0419012..7f0c26e0 100644 --- a/WordPress/Sniffs/WP/DeprecatedParametersSniff.php +++ b/WordPress/Sniffs/WP/DeprecatedParametersSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\WP; + +use WordPress\AbstractFunctionParameterSniff; + /** * Check for usage of deprecated parameters in WP functions and suggest alternative based on the parameter passed. * @@ -19,8 +23,9 @@ * @package WPCS\WordPressCodingStandards * * @since 0.12.0 + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_WP_DeprecatedParametersSniff extends WordPress_AbstractFunctionParameterSniff { +class DeprecatedParametersSniff extends AbstractFunctionParameterSniff { /** * The group name for this group of functions. diff --git a/WordPress/Sniffs/WP/DiscouragedFunctionsSniff.php b/WordPress/Sniffs/WP/DiscouragedFunctionsSniff.php index a2045f23..8e1deb76 100644 --- a/WordPress/Sniffs/WP/DiscouragedFunctionsSniff.php +++ b/WordPress/Sniffs/WP/DiscouragedFunctionsSniff.php @@ -7,14 +7,19 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\WP; + +use WordPress\AbstractFunctionRestrictionsSniff; + /** * Discourages the use of various WordPress functions and suggests alternatives. * * @package WPCS\WordPressCodingStandards * * @since 0.11.0 + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_WP_DiscouragedFunctionsSniff extends WordPress_AbstractFunctionRestrictionsSniff { +class DiscouragedFunctionsSniff extends AbstractFunctionRestrictionsSniff { /** * Groups of functions to restrict. diff --git a/WordPress/Sniffs/WP/EnqueuedResourcesSniff.php b/WordPress/Sniffs/WP/EnqueuedResourcesSniff.php index 8b2fe574..ea9af15b 100644 --- a/WordPress/Sniffs/WP/EnqueuedResourcesSniff.php +++ b/WordPress/Sniffs/WP/EnqueuedResourcesSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\WP; + +use WordPress\Sniff; + /** * Makes sure scripts and styles are enqueued and not explicitly echo'd. * @@ -16,8 +20,9 @@ * * @since 0.3.0 * @since 0.12.0 This class now extends WordPress_Sniff. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_WP_EnqueuedResourcesSniff extends WordPress_Sniff { +class EnqueuedResourcesSniff extends Sniff { /** * Returns an array of tokens this test wants to listen for. diff --git a/WordPress/Sniffs/WP/I18nSniff.php b/WordPress/Sniffs/WP/I18nSniff.php index 7a1bf7f5..06536475 100644 --- a/WordPress/Sniffs/WP/I18nSniff.php +++ b/WordPress/Sniffs/WP/I18nSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\WP; + +use WordPress\Sniff; + /** * Makes sure WP internationalization functions are used properly. * @@ -20,8 +24,9 @@ * - Now has the ability to handle text-domain set via the command-line * as a comma-delimited list. * `phpcs --runtime-set text_domain my-slug,default` + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_WP_I18nSniff extends WordPress_Sniff { +class I18nSniff extends Sniff { /** * These Regexes copied from http://php.net/manual/en/function.sprintf.php#93552 diff --git a/WordPress/Sniffs/WP/PreparedSQLSniff.php b/WordPress/Sniffs/WP/PreparedSQLSniff.php index 85d3202a..e9fef1af 100644 --- a/WordPress/Sniffs/WP/PreparedSQLSniff.php +++ b/WordPress/Sniffs/WP/PreparedSQLSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\WP; + +use WordPress\Sniff; + /** * Sniff for prepared SQL. * @@ -17,8 +21,9 @@ * @package WPCS\WordPressCodingStandards * * @since 0.8.0 + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_WP_PreparedSQLSniff extends WordPress_Sniff { +class PreparedSQLSniff extends Sniff { /** * The lists of $wpdb methods. diff --git a/WordPress/Sniffs/WhiteSpace/CastStructureSpacingSniff.php b/WordPress/Sniffs/WhiteSpace/CastStructureSpacingSniff.php index 16bc7de9..f5c34669 100755 --- a/WordPress/Sniffs/WhiteSpace/CastStructureSpacingSniff.php +++ b/WordPress/Sniffs/WhiteSpace/CastStructureSpacingSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\WhiteSpace; + +use WordPress\Sniff; + /** * Ensure cast statements don't contain whitespace, but *are* surrounded by whitespace, based upon Squiz code. * @@ -18,8 +22,9 @@ * @since 0.11.0 This sniff now has the ability to fix the issues it flags. * @since 0.11.0 The error level for all errors thrown by this sniff has been raised from warning to error. * @since 0.12.0 This class now extends WordPress_Sniff. + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_WhiteSpace_CastStructureSpacingSniff extends WordPress_Sniff { +class CastStructureSpacingSniff extends Sniff { /** * Returns an array of tokens this test wants to listen for. diff --git a/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php b/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php index 73691356..88ad2be2 100644 --- a/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php +++ b/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\WhiteSpace; + +use WordPress\Sniff; + /** * Enforces spacing around logical operators and assignments, based upon Squiz code. * @@ -16,13 +20,14 @@ * @since 2013-06-11 This sniff no longer supports JS. * @since 0.3.0 This sniff now has the ability to fix most errors it flags. * @since 0.7.0 This class now extends WordPress_Sniff. + * @since 0.13.0 Class name changed: this class is now namespaced. * * Last synced with base class 2017-01-15 at commit b024ad84656c37ef5733c6998ebc1e60957b2277. * Note: This class has diverged quite far from the original. All the same, checking occassionally * to see if there are upstream fixes made from which this sniff can benefit, is warranted. * @link https://github.com/squizlabs/PHP_CodeSniffer/blob/master/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php */ -class WordPress_Sniffs_WhiteSpace_ControlStructureSpacingSniff extends WordPress_Sniff { +class ControlStructureSpacingSniff extends Sniff { /** * Check for blank lines on start/end of control structures. diff --git a/WordPress/Sniffs/WhiteSpace/DisallowInlineTabsSniff.php b/WordPress/Sniffs/WhiteSpace/DisallowInlineTabsSniff.php index 7ca26d2c..f8555e55 100644 --- a/WordPress/Sniffs/WhiteSpace/DisallowInlineTabsSniff.php +++ b/WordPress/Sniffs/WhiteSpace/DisallowInlineTabsSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\WhiteSpace; + +use WordPress\Sniff; + /** * Enforces using spaces for mid-line alignment. * @@ -15,8 +19,9 @@ * @package WPCS\WordPressCodingStandards * * @since 0.12.0 + * @since 0.13.0 Class name changed: this class is now namespaced. */ -class WordPress_Sniffs_WhiteSpace_DisallowInlineTabsSniff extends WordPress_Sniff { +class DisallowInlineTabsSniff extends Sniff { /** * The --tab-width CLI value that is being used. diff --git a/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php b/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php index 921dfcd4..7677bd3f 100644 --- a/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php +++ b/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php @@ -28,6 +28,7 @@ * T_BOOLEAN_NOT and the logical operators (`&&` and the like) - via the * registration method and changing the value of the customizable * $ignoreNewlines property. + * @since 0.13.0 Class name changed: this class is now namespaced. * * Last synced with base class June 2017 at commit 41127aa4764536f38f504fb3f7b8831f05919c89. * @link https://github.com/squizlabs/PHP_CodeSniffer/blob/master/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/OperatorSpacingSniff.php diff --git a/WordPress/Sniffs/XSS/EscapeOutputSniff.php b/WordPress/Sniffs/XSS/EscapeOutputSniff.php index 70e26933..7af4d77f 100644 --- a/WordPress/Sniffs/XSS/EscapeOutputSniff.php +++ b/WordPress/Sniffs/XSS/EscapeOutputSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\XSS; + +use WordPress\Sniff; + /** * Verifies that all outputted strings are escaped. * @@ -20,8 +24,9 @@ * have been moved to the WordPress_Sniff parent class. * @since 0.12.0 This sniff will now also check for output escaping when using shorthand * echo tags ` Date: Sat, 22 Jul 2017 20:24:14 +0200 Subject: [PATCH 126/282] PHPCS 3.x compat: Namespace all sniffs which extend an upstream sniff --- .../Sniffs/NamingConventions/ValidFunctionNameSniff.php | 8 ++++---- .../Sniffs/NamingConventions/ValidVariableNameSniff.php | 8 ++++---- WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/WordPress/Sniffs/NamingConventions/ValidFunctionNameSniff.php b/WordPress/Sniffs/NamingConventions/ValidFunctionNameSniff.php index d4b5f3a9..e9960b4e 100644 --- a/WordPress/Sniffs/NamingConventions/ValidFunctionNameSniff.php +++ b/WordPress/Sniffs/NamingConventions/ValidFunctionNameSniff.php @@ -7,9 +7,9 @@ * @license https://opensource.org/licenses/MIT MIT */ -if ( ! class_exists( 'PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff', true ) ) { - throw new PHP_CodeSniffer_Exception( 'Class PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff not found' ); -} +namespace WordPress\Sniffs\NamingConventions; + +use PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff as PHPCS_PEAR_ValidFunctionNameSniff; /** * Enforces WordPress function name and method name format, based upon Squiz code. @@ -27,7 +27,7 @@ * {@internal While this class extends the PEAR parent, it does not actually use the checks * contained in the parent. It only uses the properties and the token registration from the parent.}} */ -class WordPress_Sniffs_NamingConventions_ValidFunctionNameSniff extends PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff { +class ValidFunctionNameSniff extends PHPCS_PEAR_ValidFunctionNameSniff { /** * Additional double underscore prefixed methods specific to certain PHP native extensions. diff --git a/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php b/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php index deac96a7..5b950885 100644 --- a/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php +++ b/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php @@ -7,9 +7,9 @@ * @license https://opensource.org/licenses/MIT MIT */ -if ( ! class_exists( 'PHP_CodeSniffer_Standards_AbstractVariableSniff', true ) ) { - throw new PHP_CodeSniffer_Exception( 'Class PHP_CodeSniffer_Standards_AbstractVariableSniff not found' ); -} +namespace WordPress\Sniffs\NamingConventions; + +use PHP_CodeSniffer_Standards_AbstractVariableSniff as PHPCS_AbstractVariableSniff; use WordPress\Sniff; /** @@ -25,7 +25,7 @@ * Last synced with base class July 2014 at commit ed257ca0e56ad86cd2a4d6fa38ce0b95141c824f. * @link https://github.com/squizlabs/PHP_CodeSniffer/blob/master/CodeSniffer/Standards/Squiz/Sniffs/NamingConventions/ValidVariableNameSniff.php */ -class WordPress_Sniffs_NamingConventions_ValidVariableNameSniff extends PHP_CodeSniffer_Standards_AbstractVariableSniff { +class ValidVariableNameSniff extends PHPCS_AbstractVariableSniff { /** * PHP Reserved Vars. diff --git a/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php b/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php index 7677bd3f..9f537635 100644 --- a/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php +++ b/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php @@ -7,9 +7,9 @@ * @license https://opensource.org/licenses/MIT MIT */ -if ( ! class_exists( 'Squiz_Sniffs_WhiteSpace_OperatorSpacingSniff', true ) ) { - throw new PHP_CodeSniffer_Exception( 'Class Squiz_Sniffs_WhiteSpace_OperatorSpacingSniff not found' ); -} +namespace WordPress\Sniffs\WhiteSpace; + +use Squiz_Sniffs_WhiteSpace_OperatorSpacingSniff as PHPCS_Squiz_OperatorSpacingSniff; /** * Verify operator spacing, uses the Squiz sniff, but additionally also sniffs for the `!` (boolean not) operator. @@ -33,7 +33,7 @@ * Last synced with base class June 2017 at commit 41127aa4764536f38f504fb3f7b8831f05919c89. * @link https://github.com/squizlabs/PHP_CodeSniffer/blob/master/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/OperatorSpacingSniff.php */ -class WordPress_Sniffs_WhiteSpace_OperatorSpacingSniff extends Squiz_Sniffs_WhiteSpace_OperatorSpacingSniff { +class OperatorSpacingSniff extends PHPCS_Squiz_OperatorSpacingSniff { /** * Allow newlines instead of spaces. From 5c4759149ffbd774e4a425473a2a82f06bdf99d0 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 20 Jul 2017 05:13:44 +0200 Subject: [PATCH 127/282] PHPCS 3.x compat: Fix all references to upstream PHPCS classes * Add use statements for all PHPCS class references. * Where possible use the PHPCS 3.x class name as a use alias to make the future change of dropping 2.x support easier. --- .../AbstractFunctionRestrictionsSniff.php | 5 +- WordPress/Sniff.php | 50 ++++++++++--------- .../Sniffs/Arrays/ArrayDeclarationSniff.php | 8 +-- .../Arrays/ArrayDeclarationSpacingSniff.php | 3 +- .../Sniffs/Arrays/ArrayIndentationSniff.php | 3 +- .../Arrays/CommaAfterArrayItemSniff.php | 5 +- .../Classes/ClassInstantiationSniff.php | 7 +-- .../CodeAnalysis/EmptyStatementSniff.php | 3 +- WordPress/Sniffs/Files/FileNameSniff.php | 6 +-- .../FunctionCallSignatureNoParamsSniff.php | 7 +-- .../PrefixAllGlobalsSniff.php | 25 +++++----- .../ValidFunctionNameSniff.php | 19 +++---- .../ValidVariableNameSniff.php | 29 +++++------ .../Sniffs/PHP/DiscouragedFunctionsSniff.php | 8 +-- WordPress/Sniffs/PHP/YodaConditionsSniff.php | 15 +++--- WordPress/Sniffs/VIP/AdminBarRemovalSniff.php | 5 +- WordPress/Sniffs/VIP/CronIntervalSniff.php | 3 +- .../Sniffs/VIP/DirectDatabaseQuerySniff.php | 3 +- .../Sniffs/Variables/GlobalVariablesSniff.php | 5 +- WordPress/Sniffs/WP/CapitalPDangitSniff.php | 5 +- .../Sniffs/WP/EnqueuedResourcesSniff.php | 3 +- WordPress/Sniffs/WP/I18nSniff.php | 7 +-- .../WhiteSpace/CastStructureSpacingSniff.php | 3 +- .../ControlStructureSpacingSniff.php | 15 +++--- .../WhiteSpace/OperatorSpacingSniff.php | 3 +- WordPress/Sniffs/XSS/EscapeOutputSniff.php | 9 ++-- 26 files changed, 142 insertions(+), 112 deletions(-) diff --git a/WordPress/AbstractFunctionRestrictionsSniff.php b/WordPress/AbstractFunctionRestrictionsSniff.php index a607d21e..cba5f6bb 100644 --- a/WordPress/AbstractFunctionRestrictionsSniff.php +++ b/WordPress/AbstractFunctionRestrictionsSniff.php @@ -10,6 +10,7 @@ namespace WordPress; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Restricts usage of some functions. @@ -210,7 +211,7 @@ public function is_targetted_token( $stackPtr ) { // Exclude function definitions, class methods, and namespaced calls. if ( T_STRING === $this->tokens[ $stackPtr ]['code'] && isset( $this->tokens[ ( $stackPtr - 1 ) ] ) ) { - $prev = $this->phpcsFile->findPrevious( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr - 1 ), null, true ); + $prev = $this->phpcsFile->findPrevious( Tokens::$emptyTokens, ( $stackPtr - 1 ), null, true ); if ( false !== $prev ) { // Skip sniffing if calling a same-named method, or on function definitions. @@ -226,7 +227,7 @@ public function is_targetted_token( $stackPtr ) { // Skip namespaced functions, ie: \foo\bar() not \bar(). if ( T_NS_SEPARATOR === $this->tokens[ $prev ]['code'] ) { - $pprev = $this->phpcsFile->findPrevious( PHP_CodeSniffer_Tokens::$emptyTokens, ( $prev - 1 ), null, true ); + $pprev = $this->phpcsFile->findPrevious( Tokens::$emptyTokens, ( $prev - 1 ), null, true ); if ( false !== $pprev && T_STRING === $this->tokens[ $pprev ]['code'] ) { return false; } diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index ec47c6dd..5cb01112 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -9,6 +9,10 @@ namespace WordPress; +use PHP_CodeSniffer_Sniff as PHPCS_Sniff; +use PHP_CodeSniffer_File as File; +use PHP_CodeSniffer_Tokens as Tokens; + /** * Represents a PHP_CodeSniffer sniff for sniffing WordPress coding standards. * @@ -28,7 +32,7 @@ * In the rare few cases where the array values *do* have meaning, this * is documented in the property documentation.}} */ -abstract class Sniff implements PHP_CodeSniffer_Sniff { +abstract class Sniff implements PHPCS_Sniff { /** * List of the functions which verify nonces. @@ -798,7 +802,7 @@ abstract class Sniff implements PHP_CodeSniffer_Sniff { * * @since 0.4.0 * - * @var PHP_CodeSniffer_File + * @var \PHP_CodeSniffer\Files\File */ protected $phpcsFile; @@ -816,14 +820,14 @@ abstract class Sniff implements PHP_CodeSniffer_Sniff { * * @since 0.11.0 * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token + * in the stack passed in $tokens. * * @return int|void Integer stack pointer to skip forward or void to continue * normal file processing. */ - public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { + public function process( File $phpcsFile, $stackPtr ) { $this->init( $phpcsFile ); return $this->process_token( $stackPtr ); } @@ -848,9 +852,9 @@ abstract public function process_token( $stackPtr ); * * @since 0.4.0 * - * @param PHP_CodeSniffer_File $phpcsFile The file currently being processed. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file currently being processed. */ - protected function init( PHP_CodeSniffer_File $phpcsFile ) { + protected function init( File $phpcsFile ) { $this->phpcsFile = $phpcsFile; $this->tokens = $phpcsFile->getTokens(); } @@ -1200,7 +1204,7 @@ protected function is_assignment( $stackPtr ) { } $next_non_empty = $this->phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens + Tokens::$emptyTokens , ( $stackPtr + 1 ) , null , true @@ -1214,7 +1218,7 @@ protected function is_assignment( $stackPtr ) { } // If the next token is an assignment, that's all we need to know. - if ( isset( PHP_CodeSniffer_Tokens::$assignmentTokens[ $this->tokens[ $next_non_empty ]['code'] ] ) ) { + if ( isset( Tokens::$assignmentTokens[ $this->tokens[ $next_non_empty ]['code'] ] ) ) { return true; } @@ -1394,7 +1398,7 @@ protected function is_safe_casted( $stackPtr ) { // Get the last non-empty token. $prev = $this->phpcsFile->findPrevious( - PHP_CodeSniffer_Tokens::$emptyTokens + Tokens::$emptyTokens , ( $stackPtr - 1 ) , null , true @@ -1481,7 +1485,7 @@ protected function is_sanitized( $stackPtr, $require_unslash = false ) { * to resolve the function name, do so. */ $first_non_empty = $this->phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens, + Tokens::$emptyTokens, $callback['start'], ( $callback['end'] + 1 ), true @@ -1538,7 +1542,7 @@ protected function get_array_access_key( $stackPtr ) { // Find the next non-empty token. $open_bracket = $this->phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens, + Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true @@ -1704,19 +1708,19 @@ protected function is_comparison( $stackPtr ) { // Find the previous non-empty token. We check before the var first because // yoda conditions are usually expected. $previous_token = $this->phpcsFile->findPrevious( - PHP_CodeSniffer_Tokens::$emptyTokens, + Tokens::$emptyTokens, ( $stackPtr - 1 ), null, true ); - if ( isset( PHP_CodeSniffer_Tokens::$comparisonTokens[ $this->tokens[ $previous_token ]['code'] ] ) ) { + if ( isset( Tokens::$comparisonTokens[ $this->tokens[ $previous_token ]['code'] ] ) ) { return true; } // Maybe the comparison operator is after this. $next_token = $this->phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens, + Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true @@ -1726,14 +1730,14 @@ protected function is_comparison( $stackPtr ) { while ( T_OPEN_SQUARE_BRACKET === $this->tokens[ $next_token ]['code'] ) { $next_token = $this->phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens, + Tokens::$emptyTokens, ( $this->tokens[ $next_token ]['bracket_closer'] + 1 ), null, true ); } - if ( isset( PHP_CodeSniffer_Tokens::$comparisonTokens[ $this->tokens[ $next_token ]['code'] ] ) ) { + if ( isset( Tokens::$comparisonTokens[ $this->tokens[ $next_token ]['code'] ] ) ) { return true; } @@ -1829,7 +1833,7 @@ public function does_function_call_have_parameters( $stackPtr ) { return false; } - $next_non_empty = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true, null, true ); + $next_non_empty = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true, null, true ); // Deal with short array syntax. if ( 'T_OPEN_SHORT_ARRAY' === $this->tokens[ $stackPtr ]['type'] ) { @@ -1856,7 +1860,7 @@ public function does_function_call_have_parameters( $stackPtr ) { } $close_parenthesis = $this->tokens[ $next_non_empty ]['parenthesis_closer']; - $next_next_non_empty = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $next_non_empty + 1 ), ( $close_parenthesis + 1 ), true ); + $next_next_non_empty = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $next_non_empty + 1 ), ( $close_parenthesis + 1 ), true ); if ( $next_next_non_empty === $close_parenthesis ) { // No parameters. @@ -1932,7 +1936,7 @@ public function get_function_call_parameters( $stackPtr ) { $nestedParenthesisCount = 0; } else { - $opener = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true, null, true ); + $opener = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true, null, true ); $closer = $this->tokens[ $opener ]['parenthesis_closer']; $nestedParenthesisCount = 1; @@ -1982,7 +1986,7 @@ public function get_function_call_parameters( $stackPtr ) { * Prevents code like the following from setting a third parameter: * functionCall( $param1, $param2, ); */ - $has_next_param = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $next_comma + 1 ), $closer, true, null, true ); + $has_next_param = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $next_comma + 1 ), $closer, true, null, true ); if ( false === $has_next_param ) { break; } @@ -2154,7 +2158,7 @@ public function get_declared_namespace_name( $stackPtr ) { return false; } - $nextToken = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true, null, true ); + $nextToken = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true, null, true ); if ( T_OPEN_CURLY_BRACKET === $this->tokens[ $nextToken ]['code'] ) { // Declaration for global namespace when using multiple namespaces in a file. // I.e.: `namespace {}`. diff --git a/WordPress/Sniffs/Arrays/ArrayDeclarationSniff.php b/WordPress/Sniffs/Arrays/ArrayDeclarationSniff.php index 9f3e593d..2f9899f1 100644 --- a/WordPress/Sniffs/Arrays/ArrayDeclarationSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayDeclarationSniff.php @@ -9,6 +9,8 @@ namespace WordPress\Sniffs\Arrays; +use PHP_CodeSniffer_File as File; + /** * Enforces WordPress array format, based upon Squiz code. * @@ -49,11 +51,11 @@ public function register() { * * @deprecated 0.13.0 * - * @param PHP_CodeSniffer_File $phpcsFile A PHP_CodeSniffer file. - * @param int $stackPtr The position of the token. + * @param \PHP_CodeSniffer\Files\File $phpcsFile A PHP_CodeSniffer file. + * @param int $stackPtr The position of the token. * * @return void */ - public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) {} + public function process( File $phpcsFile, $stackPtr ) {} } // End class. diff --git a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php index 36c075e1..95b1c167 100644 --- a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\Arrays; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Enforces WordPress array spacing format. @@ -219,7 +220,7 @@ protected function process_single_line_array( $stackPtr, $opener, $closer ) { * interpreted as alignment whitespace. */ $first_non_empty = $this->phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens, + Tokens::$emptyTokens, $item['start'], ( $item['end'] + 1 ), true diff --git a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php index 9a679487..b9de09f5 100644 --- a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\Arrays; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Enforces WordPress array indentation for multi-line arrays. @@ -69,7 +70,7 @@ public function register() { * * Existing heredoc, nowdoc and inline HTML indentation should be respected at all times. */ - $this->ignore_tokens = PHP_CodeSniffer_Tokens::$heredocTokens; + $this->ignore_tokens = Tokens::$heredocTokens; unset( $this->ignore_tokens[ T_START_HEREDOC ], $this->ignore_tokens[ T_START_NOWDOC ] ); $this->ignore_tokens[ T_INLINE_HTML ] = T_INLINE_HTML; diff --git a/WordPress/Sniffs/Arrays/CommaAfterArrayItemSniff.php b/WordPress/Sniffs/Arrays/CommaAfterArrayItemSniff.php index f2ef8252..16614102 100644 --- a/WordPress/Sniffs/Arrays/CommaAfterArrayItemSniff.php +++ b/WordPress/Sniffs/Arrays/CommaAfterArrayItemSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\Arrays; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Enforces a comma after each array item and the spacing around it. @@ -114,7 +115,7 @@ public function process_token( $stackPtr ) { } $last_content = $this->phpcsFile->findPrevious( - PHP_CodeSniffer_Tokens::$emptyTokens, + Tokens::$emptyTokens, $item['end'], $item['start'], true @@ -155,7 +156,7 @@ public function process_token( $stackPtr ) { if ( $last_content !== $item['end'] // Ignore whitespace at the end of a multi-line item if it is the end of a heredoc/nowdoc. && ( true === $single_line - || ! isset( PHP_CodeSniffer_Tokens::$heredocTokens[ $this->tokens[ $last_content ]['code'] ] ) ) + || ! isset( Tokens::$heredocTokens[ $this->tokens[ $last_content ]['code'] ] ) ) ) { $newlines = 0; $spaces = 0; diff --git a/WordPress/Sniffs/Classes/ClassInstantiationSniff.php b/WordPress/Sniffs/Classes/ClassInstantiationSniff.php index 2465a66c..85a7d2ca 100644 --- a/WordPress/Sniffs/Classes/ClassInstantiationSniff.php +++ b/WordPress/Sniffs/Classes/ClassInstantiationSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\Classes; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Verifies object instantiation statements. @@ -58,7 +59,7 @@ public function register() { * * Currently does not account for classnames passed as a variable variable. */ - $this->classname_tokens = PHP_CodeSniffer_Tokens::$emptyTokens; + $this->classname_tokens = Tokens::$emptyTokens; $this->classname_tokens[ T_NS_SEPARATOR ] = T_NS_SEPARATOR; $this->classname_tokens[ T_STRING ] = T_STRING; $this->classname_tokens[ T_SELF ] = T_SELF; @@ -100,7 +101,7 @@ public function process_token( $stackPtr ) { */ if ( 'PHP' === $this->phpcsFile->tokenizerType ) { $prev_non_empty = $this->phpcsFile->findPrevious( - PHP_CodeSniffer_Tokens::$emptyTokens, + Tokens::$emptyTokens, ($stackPtr - 1), null, true @@ -139,7 +140,7 @@ public function process_token( $stackPtr ) { // Walk back to the last part of the class name. $has_comment = false; for ( $classname_ptr = ( $next_non_empty_after_class_name - 1 ); $classname_ptr >= $stackPtr; $classname_ptr-- ) { - if ( ! isset( PHP_CodeSniffer_Tokens::$emptyTokens[ $this->tokens[ $classname_ptr ]['code'] ] ) ) { + if ( ! isset( Tokens::$emptyTokens[ $this->tokens[ $classname_ptr ]['code'] ] ) ) { // Prevent a false positive on variable variables, disregard them for now. if ( $stackPtr === $classname_ptr ) { return; diff --git a/WordPress/Sniffs/CodeAnalysis/EmptyStatementSniff.php b/WordPress/Sniffs/CodeAnalysis/EmptyStatementSniff.php index 3778fd03..c79f3f08 100644 --- a/WordPress/Sniffs/CodeAnalysis/EmptyStatementSniff.php +++ b/WordPress/Sniffs/CodeAnalysis/EmptyStatementSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\CodeAnalysis; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Checks against empty statements. @@ -57,7 +58,7 @@ public function process_token( $stackPtr ) { */ case 'T_SEMICOLON': $prevNonEmpty = $this->phpcsFile->findPrevious( - PHP_CodeSniffer_Tokens::$emptyTokens, + Tokens::$emptyTokens, ( $stackPtr - 1 ), null, true diff --git a/WordPress/Sniffs/Files/FileNameSniff.php b/WordPress/Sniffs/Files/FileNameSniff.php index 624edc49..a0328c1a 100644 --- a/WordPress/Sniffs/Files/FileNameSniff.php +++ b/WordPress/Sniffs/Files/FileNameSniff.php @@ -118,7 +118,7 @@ class FileNameSniff extends Sniff { * @return array */ public function register() { - if ( defined( 'PHP_CODESNIFFER_IN_TESTS' ) ) { + if ( defined( '\PHP_CODESNIFFER_IN_TESTS' ) ) { $this->class_exceptions = array_merge( $this->class_exceptions, $this->unittest_class_exceptions ); } @@ -195,8 +195,8 @@ public function process_token( $stackPtr ) { if ( ( 'Template' === trim( $this->tokens[ $subpackage ]['content'] ) && $this->tokens[ $subpackage_tag ]['line'] === $this->tokens[ $subpackage ]['line'] ) - && ( ( ! defined( 'PHP_CODESNIFFER_IN_TESTS' ) && '-template.php' !== $fileName_end ) - || ( defined( 'PHP_CODESNIFFER_IN_TESTS' ) && '-template.inc' !== $fileName_end ) ) + && ( ( ! defined( '\PHP_CODESNIFFER_IN_TESTS' ) && '-template.php' !== $fileName_end ) + || ( defined( '\PHP_CODESNIFFER_IN_TESTS' ) && '-template.inc' !== $fileName_end ) ) && false === $has_class ) { $this->phpcsFile->addError( diff --git a/WordPress/Sniffs/Functions/FunctionCallSignatureNoParamsSniff.php b/WordPress/Sniffs/Functions/FunctionCallSignatureNoParamsSniff.php index 0f94a1f1..cb321a0c 100644 --- a/WordPress/Sniffs/Functions/FunctionCallSignatureNoParamsSniff.php +++ b/WordPress/Sniffs/Functions/FunctionCallSignatureNoParamsSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\Functions; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Enforces no whitespace between the parenthesis of a function call without parameters. @@ -29,7 +30,7 @@ class FunctionCallSignatureNoParamsSniff extends Sniff { * @return array */ public function register() { - return PHP_CodeSniffer_Tokens::$functionNameTokens; + return Tokens::$functionNameTokens; } /** @@ -42,7 +43,7 @@ public function register() { public function process_token( $stackPtr ) { // Find the next non-empty token. - $openParenthesis = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true ); + $openParenthesis = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true ); if ( T_OPEN_PARENTHESIS !== $this->tokens[ $openParenthesis ]['code'] ) { // Not a function call. @@ -55,7 +56,7 @@ public function process_token( $stackPtr ) { } // Find the previous non-empty token. - $search = PHP_CodeSniffer_Tokens::$emptyTokens; + $search = Tokens::$emptyTokens; $search[] = T_BITWISE_AND; $previous = $this->phpcsFile->findPrevious( $search, ( $stackPtr - 1 ), null, true ); if ( T_FUNCTION === $this->tokens[ $previous ]['code'] ) { diff --git a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php index fecbac87..ad0ec984 100644 --- a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php +++ b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\NamingConventions; use WordPress\AbstractFunctionParameterSniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Verify that everything defined in the global namespace is prefixed with a theme/plugin specific prefix. @@ -272,7 +273,7 @@ public function process_token( $stackPtr ) { return; } - $constant_name_ptr = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true, null, true ); + $constant_name_ptr = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true, null, true ); if ( false === $constant_name_ptr ) { // Live coding. return; @@ -329,7 +330,7 @@ protected function process_variable_variable( $stackPtr ) { // Is this a variable variable ? // Not concerned with nested ones as those will be recognized on their own token. - $next_non_empty = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true, null, true ); + $next_non_empty = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true, null, true ); if ( false === $next_non_empty || ! isset( $indicators[ $this->tokens[ $next_non_empty ]['code'] ] ) ) { return; } @@ -341,14 +342,14 @@ protected function process_variable_variable( $stackPtr ) { $next_non_empty = $this->tokens[ $next_non_empty ]['bracket_closer']; } - $maybe_assignment = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $next_non_empty + 1 ), null, true, null, true ); + $maybe_assignment = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $next_non_empty + 1 ), null, true, null, true ); while ( false !== $maybe_assignment && T_OPEN_SQUARE_BRACKET === $this->tokens[ $maybe_assignment ]['code'] && isset( $this->tokens[ $maybe_assignment ]['bracket_closer'] ) ) { $maybe_assignment = $this->phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens, + Tokens::$emptyTokens, ( $this->tokens[ $maybe_assignment ]['bracket_closer'] + 1 ), null, true, @@ -361,7 +362,7 @@ protected function process_variable_variable( $stackPtr ) { return; } - if ( ! isset( PHP_CodeSniffer_Tokens::$assignmentTokens[ $this->tokens[ $maybe_assignment ]['code'] ] ) ) { + if ( ! isset( Tokens::$assignmentTokens[ $this->tokens[ $maybe_assignment ]['code'] ] ) ) { // Not an assignment. return; } @@ -435,13 +436,13 @@ protected function process_variable_assignment( $stackPtr ) { } if ( 'GLOBALS' === $variable_name ) { - $array_open = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true, null, true ); + $array_open = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true, null, true ); if ( false === $array_open || T_OPEN_SQUARE_BRACKET !== $this->tokens[ $array_open ]['code'] ) { // Live coding or something very silly. return; } - $array_key = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $array_open + 1 ), null, true, null, true ); + $array_key = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $array_open + 1 ), null, true, null, true ); if ( false === $array_key ) { // No key found, nothing to do. return; @@ -451,7 +452,7 @@ protected function process_variable_assignment( $stackPtr ) { $variable_name = $this->strip_quotes( $this->tokens[ $array_key ]['content'] ); // Check whether a prefix is needed. - if ( isset( PHP_CodeSniffer_Tokens::$stringTokens[ $this->tokens[ $array_key ]['code'] ] ) + if ( isset( Tokens::$stringTokens[ $this->tokens[ $array_key ]['code'] ] ) && $this->variable_prefixed_or_whitelisted( $variable_name ) === true ) { return; @@ -470,7 +471,7 @@ protected function process_variable_assignment( $stackPtr ) { // If the first part was dynamic, throw a warning. $is_error = false; } - } elseif ( ! isset( PHP_CodeSniffer_Tokens::$stringTokens[ $this->tokens[ $array_key ]['code'] ] ) ) { + } elseif ( ! isset( Tokens::$stringTokens[ $this->tokens[ $array_key ]['code'] ] ) ) { // Dynamic array key, throw a warning. $is_error = false; } @@ -580,7 +581,7 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p } else { // This may be a dynamic hook/constant name. $first_non_empty = $this->phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens, + Tokens::$emptyTokens, $parameters[1]['start'], ( $parameters[1]['end'] + 1 ), true @@ -593,7 +594,7 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p $first_non_empty_content = $this->strip_quotes( $this->tokens[ $first_non_empty ]['content'] ); // Try again with just the first token if it's a text string. - if ( isset( PHP_CodeSniffer_Tokens::$stringTokens[ $this->tokens[ $first_non_empty ]['code'] ] ) + if ( isset( Tokens::$stringTokens[ $this->tokens[ $first_non_empty ]['code'] ] ) && $this->is_prefixed( $first_non_empty_content ) === true ) { return; @@ -612,7 +613,7 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p // Start of hook/constant name is dynamic, throw a warning. $is_error = false; } - } elseif ( ! isset( PHP_CodeSniffer_Tokens::$stringTokens[ $this->tokens[ $first_non_empty ]['code'] ] ) ) { + } elseif ( ! isset( Tokens::$stringTokens[ $this->tokens[ $first_non_empty ]['code'] ] ) ) { // Dynamic hook/constant name, throw a warning. $is_error = false; } diff --git a/WordPress/Sniffs/NamingConventions/ValidFunctionNameSniff.php b/WordPress/Sniffs/NamingConventions/ValidFunctionNameSniff.php index e9960b4e..4f27b7d9 100644 --- a/WordPress/Sniffs/NamingConventions/ValidFunctionNameSniff.php +++ b/WordPress/Sniffs/NamingConventions/ValidFunctionNameSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\NamingConventions; use PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff as PHPCS_PEAR_ValidFunctionNameSniff; +use PHP_CodeSniffer_File as File; /** * Enforces WordPress function name and method name format, based upon Squiz code. @@ -55,13 +56,13 @@ class ValidFunctionNameSniff extends PHPCS_PEAR_ValidFunctionNameSniff { /** * Processes the tokens outside the scope. * - * @param PHP_CodeSniffer_File $phpcsFile The file being processed. - * @param int $stackPtr The position where this token was - * found. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being processed. + * @param int $stackPtr The position where this token was + * found. * * @return void */ - protected function processTokenOutsideScope( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { + protected function processTokenOutsideScope( File $phpcsFile, $stackPtr ) { $functionName = $phpcsFile->getDeclarationName( $stackPtr ); if ( ! isset( $functionName ) ) { @@ -101,14 +102,14 @@ protected function processTokenOutsideScope( PHP_CodeSniffer_File $phpcsFile, $s /** * Processes the tokens within the scope. * - * @param PHP_CodeSniffer_File $phpcsFile The file being processed. - * @param int $stackPtr The position where this token was - * found. - * @param int $currScope The position of the current scope. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being processed. + * @param int $stackPtr The position where this token was + * found. + * @param int $currScope The position of the current scope. * * @return void */ - protected function processTokenWithinScope( PHP_CodeSniffer_File $phpcsFile, $stackPtr, $currScope ) { + protected function processTokenWithinScope( File $phpcsFile, $stackPtr, $currScope ) { $methodName = $phpcsFile->getDeclarationName( $stackPtr ); if ( ! isset( $methodName ) ) { diff --git a/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php b/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php index 5b950885..3a10912b 100644 --- a/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php +++ b/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\NamingConventions; use PHP_CodeSniffer_Standards_AbstractVariableSniff as PHPCS_AbstractVariableSniff; +use PHP_CodeSniffer_File as File; use WordPress\Sniff; /** @@ -122,13 +123,13 @@ class ValidVariableNameSniff extends PHPCS_AbstractVariableSniff { /** * Processes this test, when one of its tokens is encountered. * - * @param PHP_CodeSniffer_File $phpcs_file The file being scanned. - * @param int $stack_ptr The position of the current token in the - * stack passed in $tokens. + * @param \PHP_CodeSniffer\Files\File $phpcs_file The file being scanned. + * @param int $stack_ptr The position of the current token in the + * stack passed in $tokens. * * @return void */ - protected function processVariable( PHP_CodeSniffer_File $phpcs_file, $stack_ptr ) { + protected function processVariable( File $phpcs_file, $stack_ptr ) { $tokens = $phpcs_file->getTokens(); $var_name = ltrim( $tokens[ $stack_ptr ]['content'], '$' ); @@ -208,13 +209,13 @@ protected function processVariable( PHP_CodeSniffer_File $phpcs_file, $stack_ptr /** * Processes class member variables. * - * @param PHP_CodeSniffer_File $phpcs_file The file being scanned. - * @param int $stack_ptr The position of the current token in the - * stack passed in $tokens. + * @param \PHP_CodeSniffer\Files\File $phpcs_file The file being scanned. + * @param int $stack_ptr The position of the current token in the + * stack passed in $tokens. * * @return void */ - protected function processMemberVar( PHP_CodeSniffer_File $phpcs_file, $stack_ptr ) { + protected function processMemberVar( File $phpcs_file, $stack_ptr ) { $tokens = $phpcs_file->getTokens(); @@ -242,13 +243,13 @@ protected function processMemberVar( PHP_CodeSniffer_File $phpcs_file, $stack_pt /** * Processes the variable found within a double quoted string. * - * @param PHP_CodeSniffer_File $phpcs_file The file being scanned. - * @param int $stack_ptr The position of the double quoted - * string. + * @param \PHP_CodeSniffer\Files\File $phpcs_file The file being scanned. + * @param int $stack_ptr The position of the double quoted + * string. * * @return void */ - protected function processVariableInString( PHP_CodeSniffer_File $phpcs_file, $stack_ptr ) { + protected function processVariableInString( File $phpcs_file, $stack_ptr ) { $tokens = $phpcs_file->getTokens(); @@ -294,11 +295,11 @@ public static function isSnakeCase( $var_name ) { * * @since 0.10.0 * - * @param PHP_CodeSniffer_File $phpcs_file The file being scanned. + * @param \PHP_CodeSniffer\Files\File $phpcs_file The file being scanned. * * @return void */ - protected function mergeWhiteList( $phpcs_file ) { + protected function mergeWhiteList( File $phpcs_file ) { if ( $this->customPropertiesWhitelist !== $this->addedCustomProperties['properties'] || $this->customVariablesWhitelist !== $this->addedCustomProperties['variables'] ) { diff --git a/WordPress/Sniffs/PHP/DiscouragedFunctionsSniff.php b/WordPress/Sniffs/PHP/DiscouragedFunctionsSniff.php index cef9e831..763ab86b 100644 --- a/WordPress/Sniffs/PHP/DiscouragedFunctionsSniff.php +++ b/WordPress/Sniffs/PHP/DiscouragedFunctionsSniff.php @@ -9,6 +9,8 @@ namespace WordPress\Sniffs\PHP; +use PHP_CodeSniffer_File as File; + /** * Discourages the use of various native PHP functions and suggests alternatives. * @@ -51,11 +53,11 @@ public function register() { * * @deprecated 0.11.0 * - * @param PHP_CodeSniffer_File $phpcsFile A PHP_CodeSniffer file. - * @param int $stackPtr The position of the token. + * @param \PHP_CodeSniffer\Files\File $phpcsFile A PHP_CodeSniffer file. + * @param int $stackPtr The position of the token. * * @return void */ - public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) {} + public function process( File $phpcsFile, $stackPtr ) {} } diff --git a/WordPress/Sniffs/PHP/YodaConditionsSniff.php b/WordPress/Sniffs/PHP/YodaConditionsSniff.php index dda70d79..6da38d9a 100644 --- a/WordPress/Sniffs/PHP/YodaConditionsSniff.php +++ b/WordPress/Sniffs/PHP/YodaConditionsSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\PHP; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Enforces Yoda conditional statements. @@ -40,8 +41,8 @@ class YodaConditionsSniff extends Sniff { */ public function register() { - $starters = PHP_CodeSniffer_Tokens::$booleanOperators; - $starters += PHP_CodeSniffer_Tokens::$assignmentTokens; + $starters = Tokens::$booleanOperators; + $starters += Tokens::$assignmentTokens; $starters[ T_CASE ] = T_CASE; $starters[ T_RETURN ] = T_RETURN; $starters[ T_SEMICOLON ] = T_SEMICOLON; @@ -75,7 +76,7 @@ public function process_token( $stackPtr ) { for ( $i = $stackPtr; $i > $start; $i-- ) { // Ignore whitespace. - if ( isset( PHP_CodeSniffer_Tokens::$emptyTokens[ $this->tokens[ $i ]['code'] ] ) ) { + if ( isset( Tokens::$emptyTokens[ $this->tokens[ $i ]['code'] ] ) ) { continue; } @@ -98,15 +99,15 @@ public function process_token( $stackPtr ) { } // Check if this is a var to var comparison, e.g.: if ( $var1 == $var2 ). - $next_non_empty = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true ); + $next_non_empty = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true ); - if ( isset( PHP_CodeSniffer_Tokens::$castTokens[ $this->tokens[ $next_non_empty ]['code'] ] ) ) { - $next_non_empty = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $next_non_empty + 1 ), null, true ); + if ( isset( Tokens::$castTokens[ $this->tokens[ $next_non_empty ]['code'] ] ) ) { + $next_non_empty = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $next_non_empty + 1 ), null, true ); } if ( in_array( $this->tokens[ $next_non_empty ]['code'], array( T_SELF, T_PARENT, T_STATIC ), true ) ) { $next_non_empty = $this->phpcsFile->findNext( - array_merge( PHP_CodeSniffer_Tokens::$emptyTokens, array( T_DOUBLE_COLON ) ) + array_merge( Tokens::$emptyTokens, array( T_DOUBLE_COLON ) ) , ( $next_non_empty + 1 ) , null , true diff --git a/WordPress/Sniffs/VIP/AdminBarRemovalSniff.php b/WordPress/Sniffs/VIP/AdminBarRemovalSniff.php index a9343d62..0dbdb508 100644 --- a/WordPress/Sniffs/VIP/AdminBarRemovalSniff.php +++ b/WordPress/Sniffs/VIP/AdminBarRemovalSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\VIP; use WordPress\AbstractFunctionParameterSniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Discourages removal of the admin bar. @@ -140,7 +141,7 @@ class AdminBarRemovalSniff extends AbstractFunctionParameterSniff { */ public function register() { // Set up all string targets. - $this->string_tokens = PHP_CodeSniffer_Tokens::$textStringTokens; + $this->string_tokens = Tokens::$textStringTokens; $targets = $this->string_tokens; @@ -361,7 +362,7 @@ protected function process_css_style( $stackPtr ) { $opener = $this->phpcsFile->findPrevious( T_OPEN_CURLY_BRACKET, $stackPtr ); if ( false !== $opener ) { for ( $i = ( $opener - 1 ); $i >= 0; $i-- ) { - if ( isset( PHP_CodeSniffer_Tokens::$commentTokens[ $this->tokens[ $i ]['code'] ] ) + if ( isset( Tokens::$commentTokens[ $this->tokens[ $i ]['code'] ] ) || T_CLOSE_CURLY_BRACKET === $this->tokens[ $i ]['code'] ) { break; diff --git a/WordPress/Sniffs/VIP/CronIntervalSniff.php b/WordPress/Sniffs/VIP/CronIntervalSniff.php index 1c30f478..aa6309fa 100644 --- a/WordPress/Sniffs/VIP/CronIntervalSniff.php +++ b/WordPress/Sniffs/VIP/CronIntervalSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\VIP; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Flag cron schedules less than 15 minutes. @@ -78,7 +79,7 @@ public function process_token( $stackPtr ) { } // Detect callback function name. - $callbackArrayPtr = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, $callback['start'], ( $callback['end'] + 1 ), true ); + $callbackArrayPtr = $this->phpcsFile->findNext( Tokens::$emptyTokens, $callback['start'], ( $callback['end'] + 1 ), true ); // If callback is array, get second element. if ( false !== $callbackArrayPtr diff --git a/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php b/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php index a7aa8444..c5d1e7c3 100644 --- a/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php +++ b/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\VIP; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Flag Database direct queries. @@ -152,7 +153,7 @@ public function process_token( $stackPtr ) { // Check for Database Schema Changes. $_pos = $stackPtr; - while ( $_pos = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$textStringTokens, ( $_pos + 1 ), $endOfStatement, false, null, true ) ) { + while ( $_pos = $this->phpcsFile->findNext( Tokens::$textStringTokens, ( $_pos + 1 ), $endOfStatement, false, null, true ) ) { if ( preg_match( '#\b(?:ALTER|CREATE|DROP)\b#i', $this->tokens[ $_pos ]['content'] ) > 0 ) { $this->phpcsFile->addError( 'Attempting a database schema change is highly discouraged.', $_pos, 'SchemaChange' ); } diff --git a/WordPress/Sniffs/Variables/GlobalVariablesSniff.php b/WordPress/Sniffs/Variables/GlobalVariablesSniff.php index 68386b7c..9ec1db80 100644 --- a/WordPress/Sniffs/Variables/GlobalVariablesSniff.php +++ b/WordPress/Sniffs/Variables/GlobalVariablesSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\Variables; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Warns about overwriting WordPress native global variables. @@ -48,7 +49,7 @@ public function process_token( $stackPtr ) { $token = $this->tokens[ $stackPtr ]; if ( T_VARIABLE === $token['code'] && '$GLOBALS' === $token['content'] ) { - $bracketPtr = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true ); + $bracketPtr = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true ); if ( false === $bracketPtr || T_OPEN_SQUARE_BRACKET !== $this->tokens[ $bracketPtr ]['code'] || ! isset( $this->tokens[ $bracketPtr ]['bracket_closer'] ) ) { return; @@ -145,7 +146,7 @@ public function process_token( $stackPtr ) { && in_array( $this->tokens[ $ptr ]['content'], $search, true ) ) { // Don't throw false positives for static class properties. - $previous = $this->phpcsFile->findPrevious( PHP_CodeSniffer_Tokens::$emptyTokens, ( $ptr - 1 ), null, true, null, true ); + $previous = $this->phpcsFile->findPrevious( Tokens::$emptyTokens, ( $ptr - 1 ), null, true, null, true ); if ( false !== $previous && T_DOUBLE_COLON === $this->tokens[ $previous ]['code'] ) { continue; } diff --git a/WordPress/Sniffs/WP/CapitalPDangitSniff.php b/WordPress/Sniffs/WP/CapitalPDangitSniff.php index b2ead93d..ca42817f 100644 --- a/WordPress/Sniffs/WP/CapitalPDangitSniff.php +++ b/WordPress/Sniffs/WP/CapitalPDangitSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\WP; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Capital P Dangit! @@ -191,9 +192,9 @@ public function process_token( $stackPtr ) { // Ignore any text strings which are array keys `$var['key']` as this is a false positive in 80% of all cases. if ( T_CONSTANT_ENCAPSED_STRING === $this->tokens[ $stackPtr ]['code'] ) { - $prevToken = $this->phpcsFile->findPrevious( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr - 1 ), null, true, null, true ); + $prevToken = $this->phpcsFile->findPrevious( Tokens::$emptyTokens, ( $stackPtr - 1 ), null, true, null, true ); if ( false !== $prevToken && T_OPEN_SQUARE_BRACKET === $this->tokens[ $prevToken ]['code'] ) { - $nextToken = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true, null, true ); + $nextToken = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true, null, true ); if ( false !== $nextToken && T_CLOSE_SQUARE_BRACKET === $this->tokens[ $nextToken ]['code'] ) { return; } diff --git a/WordPress/Sniffs/WP/EnqueuedResourcesSniff.php b/WordPress/Sniffs/WP/EnqueuedResourcesSniff.php index ea9af15b..965a28ab 100644 --- a/WordPress/Sniffs/WP/EnqueuedResourcesSniff.php +++ b/WordPress/Sniffs/WP/EnqueuedResourcesSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\WP; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Makes sure scripts and styles are enqueued and not explicitly echo'd. @@ -30,7 +31,7 @@ class EnqueuedResourcesSniff extends Sniff { * @return array */ public function register() { - return PHP_CodeSniffer_Tokens::$textStringTokens; + return Tokens::$textStringTokens; } /** diff --git a/WordPress/Sniffs/WP/I18nSniff.php b/WordPress/Sniffs/WP/I18nSniff.php index 06536475..64e21027 100644 --- a/WordPress/Sniffs/WP/I18nSniff.php +++ b/WordPress/Sniffs/WP/I18nSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\WP; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Makes sure WP internationalization functions are used properly. @@ -178,7 +179,7 @@ public function process_token( $stack_ptr ) { for ( $i = ( $func_open_paren_token + 1 ); $i < $this->tokens[ $func_open_paren_token ]['parenthesis_closer']; $i++ ) { $this_token = $this->tokens[ $i ]; $this_token['token_index'] = $i; - if ( isset( PHP_CodeSniffer_Tokens::$emptyTokens[ $this_token['code'] ] ) ) { + if ( isset( Tokens::$emptyTokens[ $this_token['code'] ] ) ) { continue; } if ( T_COMMA === $this_token['code'] ) { @@ -188,7 +189,7 @@ public function process_token( $stack_ptr ) { } // Merge consecutive single or double quoted strings (when they span multiple lines). - if ( isset( PHP_CodeSniffer_Tokens::$textStringTokens[ $this_token['code'] ] ) ) { + if ( isset( Tokens::$textStringTokens[ $this_token['code'] ] ) ) { for ( $j = ( $i + 1 ); $j < $this->tokens[ $func_open_paren_token ]['parenthesis_closer']; $j++ ) { if ( $this_token['code'] === $this->tokens[ $j ]['code'] ) { $this_token['content'] .= $this->tokens[ $j ]['content']; @@ -526,7 +527,7 @@ protected function check_for_translator_comment( $stack_ptr, $args ) { continue; } - $previous_comment = $this->phpcsFile->findPrevious( PHP_CodeSniffer_Tokens::$commentTokens, ( $stack_ptr - 1 ) ); + $previous_comment = $this->phpcsFile->findPrevious( Tokens::$commentTokens, ( $stack_ptr - 1 ) ); if ( false !== $previous_comment ) { /* diff --git a/WordPress/Sniffs/WhiteSpace/CastStructureSpacingSniff.php b/WordPress/Sniffs/WhiteSpace/CastStructureSpacingSniff.php index f5c34669..75b42014 100755 --- a/WordPress/Sniffs/WhiteSpace/CastStructureSpacingSniff.php +++ b/WordPress/Sniffs/WhiteSpace/CastStructureSpacingSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\WhiteSpace; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Ensure cast statements don't contain whitespace, but *are* surrounded by whitespace, based upon Squiz code. @@ -32,7 +33,7 @@ class CastStructureSpacingSniff extends Sniff { * @return array */ public function register() { - return PHP_CodeSniffer_Tokens::$castTokens; + return Tokens::$castTokens; } /** diff --git a/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php b/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php index 88ad2be2..e923fd38 100644 --- a/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php +++ b/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\WhiteSpace; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Enforces spacing around logical operators and assignments, based upon Squiz code. @@ -165,7 +166,7 @@ public function process_token( $stackPtr ) { } } - $parenthesisOpener = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true ); + $parenthesisOpener = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true ); // If this is a function declaration. if ( T_FUNCTION === $this->tokens[ $stackPtr ]['code'] ) { @@ -178,7 +179,7 @@ public function process_token( $stackPtr ) { // This function returns by reference (function &function_name() {}). $parenthesisOpener = $this->phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens, + Tokens::$emptyTokens, ( $parenthesisOpener + 1 ), null, true @@ -188,7 +189,7 @@ public function process_token( $stackPtr ) { if ( isset( $function_name_ptr ) ) { $parenthesisOpener = $this->phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens, + Tokens::$emptyTokens, ( $parenthesisOpener + 1 ), null, true @@ -216,7 +217,7 @@ public function process_token( $stackPtr ) { if ( isset( $this->tokens[ $parenthesisOpener ]['parenthesis_closer'] ) ) { $usePtr = $this->phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens, + Tokens::$emptyTokens, ( $this->tokens[ $parenthesisOpener ]['parenthesis_closer'] + 1 ), null, true, @@ -330,7 +331,7 @@ public function process_token( $stackPtr ) { $this->phpcsFile->fixer->addContentBefore( $parenthesisCloser, ' ' ); } } elseif ( ' ' !== $this->tokens[ ( $parenthesisCloser - 1 ) ]['content'] ) { - $prevNonEmpty = $this->phpcsFile->findPrevious( PHP_CodeSniffer_Tokens::$emptyTokens, ( $parenthesisCloser - 1 ), null, true ); + $prevNonEmpty = $this->phpcsFile->findPrevious( Tokens::$emptyTokens, ( $parenthesisCloser - 1 ), null, true ); if ( $this->tokens[ ( $parenthesisCloser ) ]['line'] === $this->tokens[ ( $prevNonEmpty + 1 ) ]['line'] ) { $error = 'Expected exactly one space before closing parenthesis; "%s" found.'; $fix = $this->phpcsFile->addFixableError( @@ -435,7 +436,7 @@ public function process_token( $stackPtr ) { if ( $firstContent !== $scopeCloser ) { $lastContent = $this->phpcsFile->findPrevious( T_WHITESPACE, ( $scopeCloser - 1 ), null, true ); - $lastNonEmptyContent = $this->phpcsFile->findPrevious( PHP_CodeSniffer_Tokens::$emptyTokens, ( $scopeCloser - 1 ), null, true ); + $lastNonEmptyContent = $this->phpcsFile->findPrevious( Tokens::$emptyTokens, ( $scopeCloser - 1 ), null, true ); $checkToken = $lastContent; if ( isset( $this->tokens[ $lastNonEmptyContent ]['scope_condition'] ) ) { @@ -485,7 +486,7 @@ public function process_token( $stackPtr ) { if ( T_COMMENT === $this->tokens[ $trailingContent ]['code'] ) { // Special exception for code where the comment about // an ELSE or ELSEIF is written between the control structures. - $nextCode = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $scopeCloser + 1 ), null, true ); + $nextCode = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $scopeCloser + 1 ), null, true ); if ( T_ELSE === $this->tokens[ $nextCode ]['code'] || T_ELSEIF === $this->tokens[ $nextCode ]['code'] ) { $trailingContent = $nextCode; diff --git a/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php b/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php index 9f537635..25cc4c39 100644 --- a/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php +++ b/WordPress/Sniffs/WhiteSpace/OperatorSpacingSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\WhiteSpace; use Squiz_Sniffs_WhiteSpace_OperatorSpacingSniff as PHPCS_Squiz_OperatorSpacingSniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Verify operator spacing, uses the Squiz sniff, but additionally also sniffs for the `!` (boolean not) operator. @@ -53,7 +54,7 @@ class OperatorSpacingSniff extends PHPCS_Squiz_OperatorSpacingSniff { public function register() { $tokens = parent::register(); $tokens[ T_BOOLEAN_NOT ] = T_BOOLEAN_NOT; - $logical_operators = PHP_CodeSniffer_Tokens::$booleanOperators; + $logical_operators = Tokens::$booleanOperators; // Using array union to auto-dedup. return $tokens + $logical_operators; diff --git a/WordPress/Sniffs/XSS/EscapeOutputSniff.php b/WordPress/Sniffs/XSS/EscapeOutputSniff.php index 7af4d77f..eb6ac8fe 100644 --- a/WordPress/Sniffs/XSS/EscapeOutputSniff.php +++ b/WordPress/Sniffs/XSS/EscapeOutputSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\XSS; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Verifies that all outputted strings are escaped. @@ -198,7 +199,7 @@ public function process_token( $stackPtr ) { $function = $this->tokens[ $stackPtr ]['content']; // Find the opening parenthesis (if present; T_ECHO might not have it). - $open_paren = $this->phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true ); + $open_paren = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true ); // If function, not T_ECHO nor T_PRINT. if ( T_STRING === $this->tokens[ $stackPtr ]['code'] ) { @@ -260,7 +261,7 @@ public function process_token( $stackPtr ) { if ( ! isset( $end_of_statement ) ) { $end_of_statement = $this->phpcsFile->findNext( array( T_SEMICOLON, T_CLOSE_TAG ), $stackPtr ); - $last_token = $this->phpcsFile->findPrevious( PHP_CodeSniffer_Tokens::$emptyTokens, ( $end_of_statement - 1 ), null, true ); + $last_token = $this->phpcsFile->findPrevious( Tokens::$emptyTokens, ( $end_of_statement - 1 ), null, true ); // Check for the ternary operator. We only need to do this here if this // echo is lacking parenthesis. Otherwise it will be handled below. @@ -286,7 +287,7 @@ public function process_token( $stackPtr ) { for ( $i = $stackPtr; $i < $end_of_statement; $i++ ) { // Ignore whitespaces and comments. - if ( isset( PHP_CodeSniffer_Tokens::$emptyTokens[ $this->tokens[ $i ]['code'] ] ) ) { + if ( isset( Tokens::$emptyTokens[ $this->tokens[ $i ]['code'] ] ) ) { continue; } @@ -388,7 +389,7 @@ public function process_token( $stackPtr ) { // Get the first parameter (name of function being used on the array). $mapped_function = $this->phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens, + Tokens::$emptyTokens, ( $function_opener + 1 ), $this->tokens[ $function_opener ]['parenthesis_closer'], true From 744fc5907ae110261dfc264aee33963583012f60 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 20 Jul 2017 12:16:36 +0200 Subject: [PATCH 128/282] PHPCS 3.x compat: Make sure checks for PHP native functions/etc are done in the global namespace --- .../NamingConventions/PrefixAllGlobalsSniff.php | 12 ++++++------ .../NamingConventions/PrefixAllGlobalsUnitTest.php | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php index ad0ec984..c16a9a21 100644 --- a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php +++ b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php @@ -207,7 +207,7 @@ public function process_token( $stackPtr ) { } $item_name = $this->phpcsFile->getDeclarationName( $stackPtr ); - if ( function_exists( $item_name ) ) { + if ( function_exists( '\\' . $item_name ) ) { // Backfill for PHP native function. return; } @@ -234,14 +234,14 @@ public function process_token( $stackPtr ) { switch ( $this->tokens[ $stackPtr ]['type'] ) { case 'T_CLASS': - if ( class_exists( $item_name ) ) { + if ( class_exists( '\\' . $item_name ) ) { // Backfill for PHP native class. return; } break; case 'T_INTERFACE': - if ( interface_exists( $item_name ) ) { + if ( interface_exists( '\\' . $item_name ) ) { // Backfill for PHP native interface. return; } @@ -251,7 +251,7 @@ public function process_token( $stackPtr ) { break; case 'T_TRAIT': - if ( function_exists( 'trait_exists' ) && trait_exists( $item_name ) ) { + if ( function_exists( '\trait_exists' ) && trait_exists( '\\' . $item_name ) ) { // Backfill for PHP native trait. return; } @@ -280,7 +280,7 @@ public function process_token( $stackPtr ) { } $item_name = $this->tokens[ $constant_name_ptr ]['content']; - if ( defined( $item_name ) ) { + if ( defined( '\\' . $item_name ) ) { // Backfill for PHP native constant. return; } @@ -620,7 +620,7 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p } if ( 'define' === $matched_content ) { - if ( defined( $raw_content ) ) { + if ( defined( '\\' . $raw_content ) ) { // Backfill for PHP native constant. return; } diff --git a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php index 48433e66..3d24c481 100644 --- a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php +++ b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php @@ -53,10 +53,10 @@ public function getErrorList( $testFile = 'PrefixAllGlobalsUnitTest.inc' ) { 154 => ( PHP_VERSION_ID >= 50300 ) ? 0 : 1, // PHPCS on PHP 5.2 does not recognize namespaces. 155 => ( PHP_VERSION_ID >= 50300 ) ? 0 : 1, // PHPCS on PHP 5.2 does not recognize namespaces. // Backfills. - 225 => ( function_exists( 'mb_strpos' ) ) ? 0 : 1, - 230 => ( function_exists( 'array_column' ) ) ? 0 : 1, - 234 => ( defined( 'E_DEPRECATED' ) ) ? 0 : 1, - 238 => ( class_exists( 'IntlTimeZone' ) ) ? 0 : 1, + 225 => ( function_exists( '\mb_strpos' ) ) ? 0 : 1, + 230 => ( function_exists( '\array_column' ) ) ? 0 : 1, + 234 => ( defined( '\E_DEPRECATED' ) ) ? 0 : 1, + 238 => ( class_exists( '\IntlTimeZone' ) ) ? 0 : 1, ); case 'PrefixAllGlobalsUnitTest.1.inc': From 51cdbb3fc67fc02553ee28d209e8311adebf5518 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 21 Jul 2017 00:26:47 +0200 Subject: [PATCH 129/282] PHPCS 3.x compat: Add helper class & implement use A number of PHPCS 2.x classes have been split out over several classes in PHPCS 3.x. Aliasing the new classname to the old would therefore not be a good idea. This helper class acts as a compatibility layer for these cases. The helper class only addresses the most common functionality needed and is by no means exhaustive. The helper class contains one function which is currently not (yet) used `get_version()`. This method was added in anticipation of continuing support for both PHPCS 3.x as well as 2.x for another year. PHPCS 3.x is likely to bring functionality which will not be available in PHPCS 2.x, so being able to retrieve the PHPCS version will, at some point, probably be helpful. N.B. The class name for this class has to be in CamelCaps (without underscore) as otherwise the PHPCS 2.x autoloader can not find it. --- WordPress/PHPCSHelper.php | 115 ++++++++++++++++++ .../Sniffs/Arrays/ArrayIndentationSniff.php | 9 +- .../PrefixAllGlobalsSniff.php | 3 +- WordPress/Sniffs/WP/I18nSniff.php | 3 +- .../WhiteSpace/DisallowInlineTabsSniff.php | 9 +- WordPress/Tests/WP/I18nUnitTest.php | 6 +- 6 files changed, 127 insertions(+), 18 deletions(-) create mode 100644 WordPress/PHPCSHelper.php diff --git a/WordPress/PHPCSHelper.php b/WordPress/PHPCSHelper.php new file mode 100644 index 00000000..88179006 --- /dev/null +++ b/WordPress/PHPCSHelper.php @@ -0,0 +1,115 @@ +config->tabWidth ) && $phpcsFile->config->tabWidth > 0 ) { + $tab_width = $phpcsFile->config->tabWidth; + } + } else { + // PHPCS 2.x. + $cli_values = $phpcsFile->phpcs->cli->getCommandLineValues(); + if ( isset( $cli_values['tabWidth'] ) && $cli_values['tabWidth'] > 0 ) { + $tab_width = $cli_values['tabWidth']; + } + } + + return $tab_width; + } + +} diff --git a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php index b9de09f5..e8c04b14 100644 --- a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\Arrays; use WordPress\Sniff; +use WordPress\PHPCSHelper; use PHP_CodeSniffer_Tokens as Tokens; /** @@ -89,13 +90,7 @@ public function register() { */ public function process_token( $stackPtr ) { if ( ! isset( $this->tab_width ) ) { - $cli_values = $this->phpcsFile->phpcs->cli->getCommandLineValues(); - if ( ! isset( $cli_values['tabWidth'] ) || 0 === $cli_values['tabWidth'] ) { - // We have no idea how wide tabs are, so assume 4 spaces for fixing. - $this->tab_width = 4; - } else { - $this->tab_width = $cli_values['tabWidth']; - } + $this->tab_width = PHPCSHelper::get_tab_width( $this->phpcsFile ); } /* diff --git a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php index c16a9a21..0cb22692 100644 --- a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php +++ b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\NamingConventions; use WordPress\AbstractFunctionParameterSniff; +use WordPress\PHPCSHelper; use PHP_CodeSniffer_Tokens as Tokens; /** @@ -156,7 +157,7 @@ public function process_token( $stackPtr ) { } // Allow overruling the prefixes set in a ruleset via the command line. - $cl_prefixes = trim( PHP_CodeSniffer::getConfigData( 'prefixes' ) ); + $cl_prefixes = trim( PHPCSHelper::get_config_data( 'prefixes' ) ); if ( ! empty( $cl_prefixes ) ) { $this->prefixes = $cl_prefixes; } diff --git a/WordPress/Sniffs/WP/I18nSniff.php b/WordPress/Sniffs/WP/I18nSniff.php index 64e21027..d33714ba 100644 --- a/WordPress/Sniffs/WP/I18nSniff.php +++ b/WordPress/Sniffs/WP/I18nSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\WP; use WordPress\Sniff; +use WordPress\PHPCSHelper; use PHP_CodeSniffer_Tokens as Tokens; /** @@ -146,7 +147,7 @@ public function process_token( $stack_ptr ) { $token = $this->tokens[ $stack_ptr ]; // Allow overruling the text_domain set in a ruleset via the command line. - $cl_text_domain = trim( PHP_CodeSniffer::getConfigData( 'text_domain' ) ); + $cl_text_domain = trim( PHPCSHelper::get_config_data( 'text_domain' ) ); if ( ! empty( $cl_text_domain ) ) { $this->text_domain = $cl_text_domain; } diff --git a/WordPress/Sniffs/WhiteSpace/DisallowInlineTabsSniff.php b/WordPress/Sniffs/WhiteSpace/DisallowInlineTabsSniff.php index f8555e55..cf19c318 100644 --- a/WordPress/Sniffs/WhiteSpace/DisallowInlineTabsSniff.php +++ b/WordPress/Sniffs/WhiteSpace/DisallowInlineTabsSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\WhiteSpace; use WordPress\Sniff; +use WordPress\PHPCSHelper; /** * Enforces using spaces for mid-line alignment. @@ -50,13 +51,7 @@ public function register() { */ public function process_token( $stackPtr ) { if ( ! isset( $this->tab_width ) ) { - $cli_values = $this->phpcsFile->phpcs->cli->getCommandLineValues(); - if ( ! isset( $cli_values['tabWidth'] ) || 0 === $cli_values['tabWidth'] ) { - // We have no idea how wide tabs are, so assume 4 spaces for fixing. - $this->tab_width = 4; - } else { - $this->tab_width = $cli_values['tabWidth']; - } + $this->tab_width = PHPCSHelper::get_tab_width( $this->phpcsFile ); } $check_tokens = array( diff --git a/WordPress/Tests/WP/I18nUnitTest.php b/WordPress/Tests/WP/I18nUnitTest.php index a2de4531..edfc318a 100644 --- a/WordPress/Tests/WP/I18nUnitTest.php +++ b/WordPress/Tests/WP/I18nUnitTest.php @@ -7,6 +7,8 @@ * @license https://opensource.org/licenses/MIT MIT */ +use WordPress\PHPCSHelper; + /** * Unit test class for the I18n sniff. * @@ -20,14 +22,14 @@ class WordPress_Tests_WP_I18nUnitTest extends AbstractSniffUnitTest { */ protected function setUp() { parent::setUp(); - PHP_CodeSniffer::setConfigData( 'text_domain', 'my-slug,default', true ); + PHPCSHelper::set_config_data( 'text_domain', 'my-slug,default', true ); } /** * Reset the $groups property. */ protected function tearDown() { - PHP_CodeSniffer::setConfigData( 'text_domain', null, true ); + PHPCSHelper::set_config_data( 'text_domain', null, true ); parent::tearDown(); } From 3112d5a16598afe7ee25bd667a088a464a5ea651 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 22 Jul 2017 20:37:32 +0200 Subject: [PATCH 130/282] PHPCS 3.x compat: Alias PHPCS 3.x classes to their PHPCS 2.x counterparts Notes: * The file is automatically loaded by PHPCS using the new `` option. This option, when encountered in the ruleset, is ignored by previous PHPCS versions, so can be used safely and will automatically make sure the file is only loaded for PHPCS 3.x. * The file is loaded after the PHPCS native autoloader has started, but before any sniffs are loaded making for a clean way to add the aliases and prevent fatal 'class not found' errors. * Each class alias statement has to be wrapped in a `class_exists` condition to prevent fatal `class already declared` errors when this ruleset is used in combination with other external ruleset(s) which use the same/similar methodology to create PHPCS cross-version compatibility. The `` ruleset directive was added in PHPCS 3.0.1 in response to issue squizlabs/PHP_CodeSniffer#1469 --- WordPress-Core/ruleset.xml | 2 ++ WordPress-Extra/ruleset.xml | 2 ++ WordPress-VIP/ruleset.xml | 2 ++ WordPress/PHPCSAliases.php | 50 +++++++++++++++++++++++++++++++++++++ WordPress/ruleset.xml | 4 ++- 5 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 WordPress/PHPCSAliases.php diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index f31faff8..d763d610 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -2,6 +2,8 @@ Non-controversial generally-agreed upon WordPress Coding Standards + ./../WordPress/PHPCSAliases.php + diff --git a/WordPress-Extra/ruleset.xml b/WordPress-Extra/ruleset.xml index 59cb2686..370dc23a 100644 --- a/WordPress-Extra/ruleset.xml +++ b/WordPress-Extra/ruleset.xml @@ -2,6 +2,8 @@ Best practices beyond core WordPress Coding Standards + ./../WordPress/PHPCSAliases.php + diff --git a/WordPress-VIP/ruleset.xml b/WordPress-VIP/ruleset.xml index bbe5c823..23c386b6 100644 --- a/WordPress-VIP/ruleset.xml +++ b/WordPress-VIP/ruleset.xml @@ -2,6 +2,8 @@ WordPress VIP Coding Standards + ./../WordPress/PHPCSAliases.php + + /Test/AllTests.php + /Test/Standards/*.php + diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 00000000..f5c2cf0c --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,8 @@ + + + From 3070fb27f4fa59c3cc097a2524bd57d6733c8d71 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Mon, 24 Jul 2017 17:57:20 +0200 Subject: [PATCH 134/282] PHPCS 3.x compat: Update readme, build script and config files Travis: * No longer test the build against PHP 5.2. * Only test against PHP 5.3 icw PHPCS 2.x. * Test all other PHP versions against both PHPCS 2.x as well as `master` (3.x). * Test the build against PHPCS 3.x using the `master` branch. * Removed allowance for build failures against `master`. * Adjusted phpunit command to allow for testing on both PHPCS 2.x as well as 3.x. Composer: * Add the minimum required PHP version. * Make the PHPCS requirement more specific and allow for PHPCS 3.x. "Own" PHPCS custom ruleset: * Enforce PSR1 namespaces. Readme: * Adjusted (minimum) requirements information. * Updated installation instructions. * Updated travis example code. Contributing * Updated unit test instructions. * Updated example sniff code. * Removed reference to potentially upstreaming WPCS to PHPCS as reason for using the PHPCS unit test suite. Let's be fair: the sniffs ought to be unit tested anyway, no matter what. * Update unit testing conventions example. The example was referring to a now deprecated sniff, so selected another sniff for the example code. --- .travis.yml | 44 +++++-------- CONTRIBUTING.md | 172 +++++++++++++++++++++++++++++++----------------- README.md | 15 +++-- bin/phpcs.xml | 3 + composer.json | 3 +- 5 files changed, 144 insertions(+), 93 deletions(-) diff --git a/.travis.yml b/.travis.yml index b31d43db..0ab146b8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ dist: trusty cache: apt: true - + language: - php @@ -14,11 +14,12 @@ php: - 5.6 - 7.0 - 7.1 + - nightly env: - # Branch for patches against 2.x. `master` is now 3.x which WPCS is not (yet) compatible with. - - PHPCS_BRANCH=2.9 LINT=1 - # Tagged release + # `master` is now 3.x. + - PHPCS_BRANCH=master LINT=1 + # Lowest tagged release in the 2.x series with which WPCS is compatible. - PHPCS_BRANCH=2.9.0 matrix: @@ -31,38 +32,27 @@ matrix: apt: packages: - libxml2-utils - # Run against PHPCS 3.0. I just picked to run it against 5.6. - - php: 5.6 - env: PHPCS_BRANCH=master + # Run against HHVM and PHP nightly. - php: hhvm sudo: required - dist: trusty + dist: trusty group: edge - env: PHPCS_BRANCH=2.9 LINT=1 - - php: nightly - env: PHPCS_BRANCH=2.9 LINT=1 - # Test PHP 5.3 with short_open_tags set to On (is Off by default) - - php: 5.3 - env: PHPCS_BRANCH=2.9 SHORT_OPEN_TAGS=true - dist: precise + env: PHPCS_BRANCH=master LINT=1 + + # Test PHP 5.3 only against PHPCS 2.x as PHPCS 3.x has a minimum requirement of PHP 5.4. - php: 5.3 - env: PHPCS_BRANCH=2.9 + env: PHPCS_BRANCH=2.9 LINT=1 dist: precise + # Test PHP 5.3 with short_open_tags set to On (is Off by default) - php: 5.3 - env: PHPCS_BRANCH=2.9.0 - dist: precise - - php: 5.2 - env: PHPCS_BRANCH=2.9 - dist: precise - - php: 5.2 - env: PHPCS_BRANCH=2.9.0 + env: PHPCS_BRANCH=2.9.0 SHORT_OPEN_TAGS=true dist: precise + allow_failures: # Allow failures for unstable builds. - php: nightly - php: hhvm - - env: PHPCS_BRANCH=master before_install: - export XMLLINT_INDENT=" " @@ -82,8 +72,10 @@ script: # Lint the PHP files against parse errors. - if [[ "$LINT" == "1" ]]; then if find . -name "*.php" -exec php -l {} \; | grep "^[Parse error|Fatal error]"; then exit 1; fi; fi # Run the unit tests. - - if [[ ${TRAVIS_PHP_VERSION:0:2} == "5." ]]; then phpunit --filter WordPress /tmp/phpcs/tests/AllTests.php; fi - - if [[ ${TRAVIS_PHP_VERSION:0:2} != "5." ]]; then php $PHPUNIT_DIR/phpunit-5.7.17.phar --filter WordPress /tmp/phpcs/tests/AllTests.php; fi + - if [[ ${TRAVIS_PHP_VERSION:0:2} == "5." && ${PHPCS_BRANCH:0:2} == "2." ]]; then phpunit --filter WordPress $(pwd)/Test/AllTests.php; fi + - if [[ ${TRAVIS_PHP_VERSION:0:2} == "5." && ${PHPCS_BRANCH:0:2} != "2." ]]; then phpunit --filter WordPress $PHPCS_DIR/tests/AllTests.php; fi + - if [[ ${TRAVIS_PHP_VERSION:0:2} != "5." && ${PHPCS_BRANCH:0:2} == "2." ]]; then php $PHPUNIT_DIR/phpunit-5.7.17.phar --filter WordPress $(pwd)/Test/AllTests.php; fi + - if [[ ${TRAVIS_PHP_VERSION:0:2} != "5." && ${PHPCS_BRANCH:0:2} != "2." ]]; then php $PHPUNIT_DIR/phpunit-5.7.17.phar --filter WordPress $PHPCS_DIR/tests/AllTests.php; fi # WordPress Coding Standards. # @link https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards # @link http://pear.php.net/package/PHP_CodeSniffer/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 30093967..ac4c14a7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,11 +24,15 @@ When you introduce new `public` sniff properties, or your sniff extends a class Sometimes, a sniff will flag code which upon further inspection by a human turns out to be OK. If the sniff you are writing is susceptible to this, please consider adding the ability to [whitelist lines of code](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Whitelisting-code-which-flags-errors). -To this end, the `WordPress_Sniff::has_whitelist_comment()` method was introduced. +To this end, the `WordPress\Sniff::has_whitelist_comment()` method was introduced. Example usage: ```php -class WordPress_Sniffs_CSRF_NonceVerificationSniff extends WordPress_Sniff { +namespace WordPress\Sniffs\CSRF; + +use WordPress\Sniff; + +class NonceVerificationSniff extends Sniff { public function process_token( $stackPtr ) { @@ -48,92 +52,140 @@ When you introduce a new whitelist comment, please don't forget to update the [w # Unit Testing -TL;DR +## Pre-requisites +* WordPress-Coding-Standards +* PHP CodeSniffer 2.9.x or 3.x +* PHPUnit 4.x or 5.x -If you have installed `phpcs` and the WordPress-Coding-Standards as [noted in the README](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards#how-to-use-this), then you can navigate to the directory where the `phpcs` repo is checked out and do: +The WordPress Coding Standards use the PHP CodeSniffer native unit test suite for unit testing the sniffs. -```sh -composer install -vendor/bin/phpunit --filter WordPress tests/AllTests.php +Presuming you have installed PHP CodeSniffer and the WordPress-Coding-Standards as [noted in the README](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards#how-to-use-this), all you need now is `PHPUnit`. + +If you already have PHPUnit installed on your system: Congrats, you're all set. + +If not, you can navigate to the directory where the `PHP_CodeSniffer` repo is checked out and do `composer install` to install the `dev` dependencies. +Alternatively, you can [install PHPUnit](https://phpunit.de/manual/5.7/en/installation.html) as a PHAR file. + +## Before running the unit tests + +N.B.: _If you used Composer to install the WordPress Coding Standards, you can skip this step._ + +For the unit tests to work, you need to make sure PHPUnit can find your `PHP_CodeSniffer` install. + +The easiest way to do this is to add a `phpunit.xml` file to the root of your WPCS installation and set a `PHPCS_DIR` environment variable from within this file. Make sure to adjust the path to reflect your local setup. +```xml + + + + + ``` +## Running the unit tests + +The WordPress Coding Standards are compatible with both PHPCS 2.x as well as 3.x. This has some implications for running the unit tests. + +* Navigate to the directory in which you installed WPCS. +* To run the unit tests with PHPCS 3.x: + ```sh + phpunit --bootstrap="./Test/phpcs3-bootstrap.php" --filter WordPress /path/to/PHP_CodeSniffer/tests/AllTests.php + ``` +* To run the unit tests with PHPCS 2.x: + ```sh + phpunit --bootstrap="./Test/phpcs2-bootstrap.php" --filter WordPress ./Test/AllTests.php + ``` + Expected output: +``` +PHPUnit 4.8.19 by Sebastian Bergmann and contributors. -[![asciicast](https://asciinema.org/a/98078.png)](https://asciinema.org/a/98078) +Runtime: PHP 7.1.3 with Xdebug 2.5.1 +Configuration: /WordPressCS/phpunit.xml + +...................................................... -You can ignore any skipped tests as these are for `PHP_CodeSniffer` external tools. +Tests generated 558 unique error codes; 48 were fixable (8.6%) -The reason why we need to checkout from `PHP_CodeSniffer` git repo to run the tests is because -PEAR installation is intended for ready-to-use not for development. At some point `WordPress-Coding-Standards` -might be submitted to `PHP_CodeSniffer` repo and using their existing convention for unit tests -will eventually help them to test the code before merging in. +Time: 12.25 seconds, Memory: 24.00Mb + +OK (54 tests, 0 assertions) +``` + +[![asciicast](https://asciinema.org/a/98078.png)](https://asciinema.org/a/98078) ## Unit Testing conventions -If you see inside the `WordPress/Tests`, the structure mimics the `WordPress/Sniffs`. For example, -the `WordPress/Sniffs/Arrays/ArrayDeclarationSniff.php` sniff has unit test class defined in -`WordPress/Tests/Arrays/ArrayDeclarationUnitTest.php` that check `WordPress/Tests/Arrays/ArrayDeclarationUnitTest.inc` -file. See the file naming convention? Lets take a look what inside `ArrayDeclarationUnitTest.php`: +If you look inside the `WordPress/Tests` subdirectory, you'll see the structure mimics the `WordPress/Sniffs` subdirectory structure. For example, the `WordPress/Sniffs/PHP/POSIXFunctionsSniff.php` sniff has its unit test class defined in `WordPress/Tests/PHP/POSIXFunctionsUnitTest.php` which checks the `WordPress/Tests/PHP/POSIXFunctionsUnitTest.inc` test case file. See the file naming convention? + +Lets take a look at what's inside `POSIXFunctionsUnitTest.php`: ```php ... -class WordPress_Tests_Arrays_ArrayDeclarationUnitTest extends AbstractSniffUnitTest -{ - public function getErrorList() - { - return array( - 3 => 1, - 7 => 1, - 9 => 1, - 16 => 1, - 31 => 2, - ); - - }//end getErrorList() -} +namespace WordPress\Tests\PHP; + +use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; + +class POSIXFunctionsUnitTest extends AbstractSniffUnitTest { + + /** + * Returns the lines where errors should occur. + * + * @return array => + */ + public function getErrorList() { + return array( + 13 => 1, + 16 => 1, + 18 => 1, + 20 => 1, + 22 => 1, + 24 => 1, + 26 => 1, + ); + + } ... ``` -Also note the class name convention. The method `getErrorList` MUST return an array of line numbers -indicating errors (when running `phpcs`) found in `WordPress/Tests/Arrays/ArrayDeclarationUnitTest.inc`. +Also note the class name convention. The method `getErrorList()` MUST return an array of line numbers indicating errors (when running `phpcs`) found in `WordPress/Tests/PHP/POSIXFunctionsUnitTest.inc`. If you run: ```sh $ cd /path-to-cloned/phpcs -$ ./scripts/phpcs --standard=Wordpress -s CodeSniffer/Standards/WordPress/Tests/Arrays/ArrayDeclarationUnitTest.inc +$ ./bin/phpcs --standard=Wordpress -s /path/to/WordPress/Tests/PHP/POSIXFunctionsUnitTest.inc --sniffs=WordPress.PHP.POSIXFunctions ... -------------------------------------------------------------------------------- -FOUND 8 ERROR(S) AND 2 WARNING(S) AFFECTING 6 LINE(S) +FOUND 7 ERRORS AFFECTING 7 LINES -------------------------------------------------------------------------------- - 3 | ERROR | Array keyword should be lower case; expected "array" but found - | | "Array" (WordPress.Arrays.ArrayDeclaration) - 7 | ERROR | There must be no space between the Array keyword and the - | | opening parenthesis (WordPress.Arrays.ArrayDeclaration) - 9 | ERROR | Empty array declaration must have no space between the - | | parentheses (WordPress.Arrays.ArrayDeclaration) - 12 | WARNING | No space after opening parenthesis of array is bad style - | | (WordPress.Arrays.ArrayDeclaration) - 12 | WARNING | No space before closing parenthesis of array is bad style - | | (WordPress.Arrays.ArrayDeclaration) - 16 | ERROR | Each line in an array declaration must end in a comma - | | (WordPress.Arrays.ArrayDeclaration) - 31 | ERROR | Expected 1 space between "'type'" and double arrow; 0 found - | | (WordPress.Arrays.ArrayDeclaration) - 31 | ERROR | Expected 1 space between double arrow and "'post'"; 0 found - | | (WordPress.Arrays.ArrayDeclaration) - 31 | ERROR | Expected 1 space before "=>"; 0 found - | | (WordPress.WhiteSpace.OperatorSpacing) - 31 | ERROR | Expected 1 space after "=>"; 0 found - | | (WordPress.WhiteSpace.OperatorSpacing) + 13 | ERROR | ereg() has been deprecated since PHP 5.3 and removed in PHP 7.0, + | | please use preg_match() instead. + | | (WordPress.PHP.POSIXFunctions.ereg_ereg) + 16 | ERROR | eregi() has been deprecated since PHP 5.3 and removed in PHP 7.0, + | | please use preg_match() instead. + | | (WordPress.PHP.POSIXFunctions.ereg_eregi) + 18 | ERROR | ereg_replace() has been deprecated since PHP 5.3 and removed in PHP + | | 7.0, please use preg_replace() instead. + | | (WordPress.PHP.POSIXFunctions.ereg_replace_ereg_replace) + 20 | ERROR | eregi_replace() has been deprecated since PHP 5.3 and removed in PHP + | | 7.0, please use preg_replace() instead. + | | (WordPress.PHP.POSIXFunctions.ereg_replace_eregi_replace) + 22 | ERROR | split() has been deprecated since PHP 5.3 and removed in PHP 7.0, + | | please use explode(), str_split() or preg_split() instead. + | | (WordPress.PHP.POSIXFunctions.split_split) + 24 | ERROR | spliti() has been deprecated since PHP 5.3 and removed in PHP 7.0, + | | please use explode(), str_split() or preg_split() instead. + | | (WordPress.PHP.POSIXFunctions.split_spliti) + 26 | ERROR | sql_regcase() has been deprecated since PHP 5.3 and removed in PHP + | | 7.0, please use preg_match() instead. + | | (WordPress.PHP.POSIXFunctions.ereg_sql_regcase) -------------------------------------------------------------------------------- .... ``` +You'll see the line number and number of ERRORs we need to return in the `getErrorList()` method. -You'll see the line number and number of ERRORs we need to return in `getErrorList` method. -In line #31 there are two ERRORs belong to `WordPress.WhiteSpace.OperatorSpacing` sniff and -it MUST not included in `ArrayDeclarationUnitTest` (that's why we only return 2 errros for line #31). -Also there's `getWarningList` method in unit test class that returns an array of line numbers -indicating WARNINGs. +The `--sniffs=...` directive limits the output to the sniff you are testing. ## Sniff Code Standards diff --git a/README.md b/README.md index b8b701db..d131ad2c 100644 --- a/README.md +++ b/README.md @@ -42,8 +42,8 @@ This project is a collection of [PHP_CodeSniffer](https://github.com/squizlabs/P ### Requirements -The WordPress Coding Standards require PHP 5.2 or higher and the [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) version **2.9.0** or higher. -The WordPress Coding Standards are currently [not compatible with the upcoming PHPCS 3 release](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/718). +The WordPress Coding Standards require PHP 5.3 or higher and [PHP CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) version **2.9.0** or higher. +As of version 0.13.0, the WordPress Coding Standards are compatible with PHPCS 3.0.2+. In that case, the minimum PHP requirement is PHP 5.4. ### Composer @@ -58,7 +58,7 @@ Running this command will: 3. Register WordPress standards in PHP_CodeSniffer configuration. 4. Make `phpcs` command available from `wpcs/vendor/bin`. -For the convenience of using `phpcs` as a global command, you may want to add the `wpcs/vendor/bin` path to a PATH environment in your operating system. +For the convenience of using `phpcs` as a global command, you may want to add the path to the `wpcs/vendor/scripts` (PHPCS 2.x) and/or `wpcs/vendor/bin` (PHPCS 3.x) directories to a `PATH` environment variable for your operating system. #### Installing WPCS as a dependency @@ -96,10 +96,13 @@ cd ~/projects git clone https://github.com/squizlabs/PHP_CodeSniffer.git phpcs git clone -b master https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git wpcs cd phpcs +#PHPCS 2.x ./scripts/phpcs --config-set installed_paths ../wpcs +#PHPCS 3.x +./bin/phpcs --config-set installed_paths ../wpcs ``` -And then add the `~/projects/phpcs/scripts` directory to your `PATH` environment variable via your `.bashrc`. +And then add the `~/projects/phpcs/scripts` (PHPCS 2.x) or `~/projects/phpcs/bin` (PHPCS 3.x) directory to your `PATH` environment variable via your `.bashrc`. You should then see `WordPress-Core` et al listed when you run `phpcs -i`. @@ -241,7 +244,7 @@ before_install: # Install WordPress Coding Standards. - if [[ "$SNIFF" == "1" ]]; then git clone -b master --depth 1 https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git $SNIFFS_DIR; fi # Set install path for WordPress Coding Standards. - - if [[ "$SNIFF" == "1" ]]; then $PHPCS_DIR/scripts/phpcs --config-set installed_paths $SNIFFS_DIR; fi + - if [[ "$SNIFF" == "1" ]]; then $PHPCS_DIR/bin/phpcs --config-set installed_paths $SNIFFS_DIR; fi # After CodeSniffer install you should refresh your path. - if [[ "$SNIFF" == "1" ]]; then phpenv rehash; fi @@ -251,7 +254,7 @@ script: # for example: `--standard=wpcs.xml`. # You can use any of the normal PHPCS command line arguments in the command: # https://github.com/squizlabs/PHP_CodeSniffer/wiki/Usage - - if [[ "$SNIFF" == "1" ]]; then $PHPCS_DIR/scripts/phpcs -p . --standard=WordPress; fi + - if [[ "$SNIFF" == "1" ]]; then $PHPCS_DIR/bin/phpcs -p . --standard=WordPress; fi ``` diff --git a/bin/phpcs.xml b/bin/phpcs.xml index b39b2cf4..904cec2b 100644 --- a/bin/phpcs.xml +++ b/bin/phpcs.xml @@ -13,4 +13,7 @@ + + + diff --git a/composer.json b/composer.json index a26ee8b5..1b5e513a 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,8 @@ } ], "require" : { - "squizlabs/php_codesniffer": "^2.9.0" + "php" : ">=5.3", + "squizlabs/php_codesniffer": "^2.9.0 || ^3.0.2" }, "suggest" : { "dealerdirect/phpcodesniffer-composer-installer": "*" From ab7cbd91aec8d3c13aa61bb5aa422459619d8e0e Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 20 Jul 2017 13:11:16 +0200 Subject: [PATCH 135/282] PHPCS 3.x compat: remove work-around for how PHP 5.2 tokenizes code --- WordPress/Sniff.php | 51 +++++++++++---------------------------------- 1 file changed, 12 insertions(+), 39 deletions(-) diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index 5cb01112..914ee899 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -2184,30 +2184,18 @@ public function get_declared_namespace_name( $stackPtr ) { /** * Check if a content string contains a specific html open tag. * - * {@internal For PHP 5.3+ this is straightforward, just check if $content - * contains the tag. - * PHP 5.2 however, creates a separate token for `text text` as: - * - T_INLINE_HTML 'text' - * - T_INLINE_HTML 'text text' - * - * We don't need to worry about checking the rest of the content of the next - * token as sniffs using this function will be sniffing for all text string - * tokens, so the next token will be passed to the sniff in the next iteration - * and checked then. - * Similarly, no need to check content before the ' open tag, false otherwise. */ - public function has_html_open_tag( $tag_name, $stackPtr, $content = false ) { - if ( false === $content ) { + public function has_html_open_tag( $tag_name, $stackPtr = null, $content = false ) { + if ( false === $content && isset( $stackPtr ) ) { $content = $this->tokens[ $stackPtr ]['content']; } - // Check for the open tag in normal string tokens and T_INLINE_HTML for PHP 5.3+. - if ( 's' !== $tag_name[0] || PHP_VERSION_ID >= 50300 || T_INLINE_HTML !== $this->tokens[ $stackPtr ]['code'] ) { - if ( false !== strpos( $content, '<' . $tag_name ) ) { - return true; - } - } elseif ( 'tokens[ $next_ptr ] ) - && T_INLINE_HTML === $this->tokens[ $next_ptr ]['code'] - && 0 === strpos( $this->tokens[ $next_ptr ]['content'], $rest_tag_name ) - ) { - return true; - } + if ( ! empty( $content ) && false !== strpos( $content, '<' . $tag_name ) ) { + return true; } return false; From c60ab46f8502ec54aaba4f9694fbde099932ebc7 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 25 Jul 2017 02:19:10 +0200 Subject: [PATCH 136/282] :green_heart: Build: improve our own codestyle checking * Run the sniffs using a higher PHP and PHPCS version. * Minor simplification in the command to call phpcs. * Show warnings, but do not break the build for it. Previously warnings wouldn't be shown at all. * Move a number of command line options to the ruleset. * Exclude the Composer `vendor` directory if it exists. * Update the section in the `Contributing.md` regarding code style --- .travis.yml | 8 ++++---- CONTRIBUTING.md | 5 ++--- bin/phpcs.xml | 6 ++++++ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0ab146b8..08f69892 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,9 +25,9 @@ env: matrix: fast_finish: true include: - # Run PHPCS against WPCS. I just picked to run it against 5.5. - - php: 5.5 - env: PHPCS_BRANCH=2.9 SNIFF=1 + # Run PHPCS against WPCS. I just picked to run it against 7.0. + - php: 7.0 + env: PHPCS_BRANCH=master SNIFF=1 addons: apt: packages: @@ -85,7 +85,7 @@ script: # -n flag: Do not print warnings. (shortcut for --warning-severity=0) # --standard: Use WordPress as the standard. # --extensions: Only sniff PHP files. - - if [[ "$SNIFF" == "1" ]]; then $PHPCS_DIR/scripts/phpcs -p -s -n . --standard=./bin/phpcs.xml --extensions=php; fi + - if [[ "$SNIFF" == "1" ]]; then $PHPCS_BIN . --standard=./bin/phpcs.xml --runtime-set ignore_warnings_on_exit 1; fi # Validate the xml files. # @link http://xmlsoft.org/xmllint.html - if [[ "$SNIFF" == "1" ]]; then xmllint --noout ./*/ruleset.xml; fi diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ac4c14a7..0612aec8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -187,7 +187,6 @@ You'll see the line number and number of ERRORs we need to return in the `getErr The `--sniffs=...` directive limits the output to the sniff you are testing. -## Sniff Code Standards - -The sniffs for WPCS should be written such that they pass the `WordPress-Core` code standards. +## Code Standards for this project +The sniffs and test files - not test _case_ files! - for WPCS should be written such that they pass the `WordPress-Extra` and the `WordPress-Docs` code standards using the custom ruleset as found in `/bin/phpcs.xml`. diff --git a/bin/phpcs.xml b/bin/phpcs.xml index 904cec2b..7c03fbda 100644 --- a/bin/phpcs.xml +++ b/bin/phpcs.xml @@ -2,10 +2,16 @@ The Coding standard for the WordPress Coding Standards itself. + + + /Test/AllTests.php /Test/Standards/*.php + + */vendor/* + From 6f42270e1b8131d507e3f4a68419895988c1a159 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 25 Jul 2017 02:22:13 +0200 Subject: [PATCH 137/282] :books: Readme: Update the example output ... to reflect the current state of the `wp-load.php` file in combination with the current WPCS sniffs. --- README.md | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index d131ad2c..9b951e8e 100644 --- a/README.md +++ b/README.md @@ -155,25 +155,32 @@ Run the `phpcs` command line tool on a given file or directory, for example: Will result in following output: -------------------------------------------------------------------------------- - FOUND 8 ERRORS AND 2 WARNINGS AFFECTING 7 LINES + FOUND 10 ERRORS AND 5 WARNINGS AFFECTING 8 LINES -------------------------------------------------------------------------------- - 1 | ERROR | [x] End of line character is invalid; expected "\n" but found "\r\n" - 36 | ERROR | [x] Expected 1 spaces before closing bracket; 0 found - 41 | WARNING | [ ] Silencing errors is discouraged - 41 | WARNING | [ ] Silencing errors is discouraged - 48 | ERROR | [ ] Inline comments must end in full-stops, exclamation marks, or - | | question marks - 48 | ERROR | [x] There must be no blank line following an inline comment - 76 | ERROR | [ ] Inline comments must end in full-stops, exclamation marks, or - | | question marks - 92 | ERROR | [x] String "Create a Configuration File" does not require double - | | quotes; use single quotes instead - 94 | ERROR | [ ] Expected next thing to be an escaping function (see Codex for - | | 'Data Validation'), not '$die' - 94 | ERROR | [ ] Expected next thing to be an escaping function (see Codex for - | | 'Data Validation'), not '__' + 24 | WARNING | [ ] error_reporting() can lead to full path disclosure. + 24 | WARNING | [ ] error_reporting() found. Changing configuration at runtime + | | is rarely necessary. + 34 | ERROR | [x] Expected 1 spaces before closing bracket; 0 found + 39 | WARNING | [ ] Silencing errors is discouraged + 39 | WARNING | [ ] Silencing errors is discouraged + 46 | ERROR | [ ] Inline comments must end in full-stops, exclamation marks, + | | or question marks + 46 | ERROR | [x] There must be no blank line following an inline comment + 63 | WARNING | [ ] Detected access of super global var $_SERVER, probably + | | needs manual inspection. + 63 | ERROR | [ ] Detected usage of a non-validated input variable: $_SERVER + 63 | ERROR | [ ] Missing wp_unslash() before sanitization. + 63 | ERROR | [ ] Detected usage of a non-sanitized input variable: $_SERVER + 74 | ERROR | [ ] Inline comments must end in full-stops, exclamation marks, + | | or question marks + 90 | ERROR | [x] String "Create a Configuration File" does not require + | | double quotes; use single quotes instead + 92 | ERROR | [ ] Expected next thing to be an escaping function (see Codex + | | for 'Data Validation'), not '$die' + 92 | ERROR | [ ] Expected next thing to be an escaping function (see Codex + | | for 'Data Validation'), not '__' -------------------------------------------------------------------------------- - PHPCBF CAN FIX THE 4 MARKED SNIFF VIOLATIONS AUTOMATICALLY + PHPCBF CAN FIX THE 3 MARKED SNIFF VIOLATIONS AUTOMATICALLY -------------------------------------------------------------------------------- ### PhpStorm From 94c4d4016747589464fc4ba557051e16afca2590 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 25 Jul 2017 03:10:30 +0200 Subject: [PATCH 138/282] :books: Minor textual improvements to the Contributing.md document While rewriting the text in the `Contributing.md` document regarding the unit tests, I noticed some more room for improvement. --- CONTRIBUTING.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ac4c14a7..19445f14 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,14 +1,25 @@ -# Upstream Issues +Hi, thank you for your interest in contributing to the WordPress Coding Standards! We look forward to working with you. -Since WPCS employs many sniffs that are part of PHPCS, sometimes an issue will be caused by a bug in PHPCS and not in WPCS itself. Before reporting a bug, you should check what sniff an error is coming from. Running `phpcs` with the `-s` flag, which will show the names of the sniffs with each error. If the error message in question doesn't come from a sniff whose name starts with `WordPress`, the issue is probably a bug in PHPCS itself, and should be [reported there](https://github.com/squizlabs/PHP_CodeSniffer/issues). +# Reporting Bugs -# Branches +Before reporting a bug, you should check what sniff an error is coming from. +Running `phpcs` with the `-s` flag will show the name of the sniff with each error. + +Bug reports containing a minimal code sample which can be used to reproduce the issue are highly appreciated as those are most easily actionable. + +## Upstream Issues + +Since WPCS employs many sniffs that are part of PHPCS, sometimes an issue will be caused by a bug in PHPCS and not in WPCS itself. If the error message in question doesn't come from a sniff whose name starts with `WordPress`, the issue is probably a bug in PHPCS itself, and should be [reported there](https://github.com/squizlabs/PHP_CodeSniffer/issues). + +# Contributing patches and new features + +## Branches Ongoing development will be done in the `develop` with merges done into `master` once considered stable. To contribute an improvement to this project, fork the repo and open a pull request to the `develop` branch. Alternatively, if you have push access to this repo, create a feature branch prefixed by `feature/` and then open an intra-repo PR from that branch to `develop`. -Once a commit is made to `develop`, a PR should be opened from `develop` into `master` and named "Next release". This PR will then serve provide a second round of Travis CI checks (especially for any hotfixes pushed directly to the `develop` branch), and provide collaborators with a forum to discuss the upcoming stable release. +Once a commit is made to `develop`, a PR should be opened from `develop` into `master` and named "Next release". This PR will provide collaborators with a forum to discuss the upcoming stable release. # Considerations when writing sniffs From 96dc7d0c1c4dad972298be2c72be1c15f29ab458 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 25 Jul 2017 03:14:41 +0200 Subject: [PATCH 139/282] :books: Minor textual improvements to the Readme.md document While updating the text in the `Readme.md` document regarding the PHPCS 3.x compatibility, I noticed some more room for improvement. --- README.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index d131ad2c..0879a9fe 100644 --- a/README.md +++ b/README.md @@ -72,11 +72,11 @@ It is strongly suggested to `require` one of these plugins in your project to ha ### Standalone -1. Install PHP_CodeSniffer by following its [installation instructions](https://github.com/squizlabs/PHP_CodeSniffer#installation) (via Composer, PEAR, or Git checkout). +1. Install PHP_CodeSniffer by following its [installation instructions](https://github.com/squizlabs/PHP_CodeSniffer#installation) (via Composer, Phar file, PEAR, or Git checkout). Do ensure that PHP_CodeSniffer's version matches our requirements(#requirements), if, for example, you're using VVV(https://github.com/Varying-Vagrant-Vagrants/VVV). -2. Clone WordPress standards repository: +2. Clone the WordPress standards repository: git clone -b master https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git wpcs @@ -110,25 +110,25 @@ You should then see `WordPress-Core` et al listed when you run `phpcs -i`. ### Standards subsets -The project encompasses a super–set of the sniffs that the WordPress community may need. If you use the `WordPress` standard you will get all the checks. Some of them might be unnecessary for your environment, for example, those specific to WordPress VIP coding requirements. +The project encompasses a super-set of the sniffs that the WordPress community may need. If you use the `WordPress` standard you will get all the checks. Some of them might be unnecessary for your environment, for example, those specific to WordPress VIP coding requirements. You can use the following as standard names when invoking `phpcs` to select sniffs, fitting your needs: -* `WordPress` — complete set with all of the sniffs in the project - - `WordPress-Core` — main ruleset for [WordPress core coding standards](http://make.wordpress.org/core/handbook/coding-standards/) - - `WordPress-Docs` — additional ruleset for [WordPress inline documentation standards](https://make.wordpress.org/core/handbook/best-practices/inline-documentation-standards/) - - `WordPress-Extra` — extended ruleset for recommended best practices, not sufficiently covered in the WordPress core coding standards +* `WordPress` - complete set with all of the sniffs in the project + - `WordPress-Core` - main ruleset for [WordPress core coding standards](http://make.wordpress.org/core/handbook/coding-standards/) + - `WordPress-Docs` - additional ruleset for [WordPress inline documentation standards](https://make.wordpress.org/core/handbook/best-practices/inline-documentation-standards/) + - `WordPress-Extra` - extended ruleset for recommended best practices, not sufficiently covered in the WordPress core coding standards - includes `WordPress-Core` - - `WordPress-VIP` — extended ruleset for [WordPress VIP coding requirements](http://vip.wordpress.com/documentation/code-review-what-we-look-for/) + - `WordPress-VIP` - extended ruleset for [WordPress VIP coding requirements](http://vip.wordpress.com/documentation/code-review-what-we-look-for/) - includes `WordPress-Core` ### Using a custom ruleset -If you need to further customize the selection of sniffs for your project — you can create a custom ruleset file. When you name this file either `phpcs.xml` or `phpcs.xml.dist`, PHP_CodeSniffer will automatically locate it as long as it is placed in the directory from which you run the CodeSniffer or in a directory above it. If you follow these naming conventions you don't have to supply a `--standard` arg. For more info, read about [using a default configuration file](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage#using-a-default-configuration-file). See also provided [`phpcs.xml.dist.sample`](phpcs.xml.dist.sample) file and [fully annotated example](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Annotated-ruleset.xml) in PHP_CodeSniffer documentation. +If you need to further customize the selection of sniffs for your project - you can create a custom ruleset file. When you name this file either `phpcs.xml` or `phpcs.xml.dist`, PHP_CodeSniffer will automatically locate it as long as it is placed in the directory from which you run the CodeSniffer or in a directory above it. If you follow these naming conventions you don't have to supply a `--standard` arg. For more info, read about [using a default configuration file](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage#using-a-default-configuration-file). See also provided [`phpcs.xml.dist.sample`](phpcs.xml.dist.sample) file and [fully annotated example](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Annotated-ruleset.xml) in the PHP CodeSniffer documentation. ### Customizing sniff behaviour -The WordPress Coding Standard contains a number of sniffs which are configurable. This means that you can turn parts of the sniff on or off, or change the behaviour by setting a property for the sniff in your custom `ruleset.xml` file. +The WordPress Coding Standard contains a number of sniffs which are configurable. This means that you can turn parts of the sniff on or off, or change the behaviour by setting a property for the sniff in your custom `phpcs.xml` file. You can find a complete list of all the properties you can change in the [wiki](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties). @@ -178,7 +178,7 @@ Will result in following output: ### PhpStorm -Please see “[PHP Code Sniffer with WordPress Coding Standards Integration](https://confluence.jetbrains.com/display/PhpStorm/WordPress+Development+using+PhpStorm#WordPressDevelopmentusingPhpStorm-PHPCodeSnifferwithWordPressCodingStandardsIntegrationinPhpStorm)” in PhpStorm documentation. +Please see "[PHP Code Sniffer with WordPress Coding Standards Integration](https://confluence.jetbrains.com/display/PhpStorm/WordPress+Development+using+PhpStorm#WordPressDevelopmentusingPhpStorm-PHPCodeSnifferwithWordPressCodingStandardsIntegrationinPhpStorm)" in the PhpStorm documentation. ### Sublime Text @@ -213,7 +213,7 @@ sublime-phpcs is insanely powerful, but if you'd prefer automatic linting, [Subl ### Visual Studio -Please see “[Setting up PHP CodeSniffer in Visual Studio Code](https://tommcfarlin.com/php-codesniffer-in-visual-studio-code/)”, a tutorial by Tom McFarlin. +Please see "[Setting up PHP CodeSniffer in Visual Studio Code](https://tommcfarlin.com/php-codesniffer-in-visual-studio-code/)", a tutorial by Tom McFarlin. ## Running your code through WPCS automatically using CI tools @@ -265,7 +265,7 @@ You can find information on how to deal with some of the more frequent issues in ## Contributing -See [CONTRIBUTING](CONTRIBUTING.md), including information about [unit testing](CONTRIBUTING.md#unit-testing). +See [CONTRIBUTING](CONTRIBUTING.md), including information about [unit testing](CONTRIBUTING.md#unit-testing) the standard. ## License From ea76a402679ac0caa2c4242e69717d80ebbe3e38 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 20 Jul 2017 13:13:19 +0200 Subject: [PATCH 140/282] PHPCS 3.x compat: remove test skipping for PHP 5.2 Includes removal of two secondary test case files which were a work-around for unrecognized syntaxes in PHP 5.2. --- .../Classes/ClassInstantiationUnitTest.2.inc | 17 ----- .../ClassInstantiationUnitTest.2.inc.fixed | 17 ----- ...t.1.inc => ClassInstantiationUnitTest.inc} | 8 +++ ...d => ClassInstantiationUnitTest.inc.fixed} | 8 +++ .../Classes/ClassInstantiationUnitTest.php | 27 +------- .../Tests/DB/RestrictedClassesUnitTest.php | 9 --- WordPress/Tests/Files/FileNameUnitTest.php | 5 -- .../PrefixAllGlobalsUnitTest.php | 21 +------ .../Tests/VIP/AdminBarRemovalUnitTest.php | 8 +-- .../Tests/VIP/DirectDatabaseQueryUnitTest.php | 2 +- .../Tests/VIP/PluginMenuSlugUnitTest.php | 7 +-- .../Tests/VIP/RestrictedFunctionsUnitTest.php | 1 - .../Tests/WP/CapitalPDangitUnitTest.1.inc | 10 --- WordPress/Tests/WP/CapitalPDangitUnitTest.inc | 6 ++ .../Tests/WP/CapitalPDangitUnitTest.inc.fixed | 6 ++ WordPress/Tests/WP/CapitalPDangitUnitTest.php | 63 ++++++++----------- .../Tests/WP/EnqueuedResourcesUnitTest.php | 12 ++-- WordPress/Tests/WP/I18nUnitTest.php | 2 +- WordPress/Tests/WP/PreparedSQLUnitTest.php | 19 +----- .../ControlStructureSpacingUnitTest.php | 11 ---- WordPress/Tests/XSS/EscapeOutputUnitTest.php | 1 - 21 files changed, 74 insertions(+), 186 deletions(-) delete mode 100644 WordPress/Tests/Classes/ClassInstantiationUnitTest.2.inc delete mode 100644 WordPress/Tests/Classes/ClassInstantiationUnitTest.2.inc.fixed rename WordPress/Tests/Classes/{ClassInstantiationUnitTest.1.inc => ClassInstantiationUnitTest.inc} (92%) rename WordPress/Tests/Classes/{ClassInstantiationUnitTest.1.inc.fixed => ClassInstantiationUnitTest.inc.fixed} (92%) delete mode 100644 WordPress/Tests/WP/CapitalPDangitUnitTest.1.inc diff --git a/WordPress/Tests/Classes/ClassInstantiationUnitTest.2.inc b/WordPress/Tests/Classes/ClassInstantiationUnitTest.2.inc deleted file mode 100644 index 7b3038a5..00000000 --- a/WordPress/Tests/Classes/ClassInstantiationUnitTest.2.inc +++ /dev/null @@ -1,17 +0,0 @@ - 1, 38 => 1, @@ -70,12 +53,8 @@ public function getErrorList( $testFile = '' ) { 80 => 1, 84 => 1, 85 => 1, - ); - - case 'ClassInstantiationUnitTest.2.inc': - return array( - 16 => 1, - 17 => 1, + 97 => 1, + 98 => 1, ); case 'ClassInstantiationUnitTest.js': diff --git a/WordPress/Tests/DB/RestrictedClassesUnitTest.php b/WordPress/Tests/DB/RestrictedClassesUnitTest.php index 75e22341..4bf68b6c 100644 --- a/WordPress/Tests/DB/RestrictedClassesUnitTest.php +++ b/WordPress/Tests/DB/RestrictedClassesUnitTest.php @@ -52,15 +52,6 @@ protected function tearDown() { parent::tearDown(); } - /** - * Skip this test on PHP 5.2 as otherwise testing the namespace resolving would fail. - * - * @return bool Whether to skip this test. - */ - protected function shouldSkipTest() { - return ( PHP_VERSION_ID < 50300 ); - } - /** * Returns the lines where errors should occur. * diff --git a/WordPress/Tests/Files/FileNameUnitTest.php b/WordPress/Tests/Files/FileNameUnitTest.php index edd38737..85a1f87a 100644 --- a/WordPress/Tests/Files/FileNameUnitTest.php +++ b/WordPress/Tests/Files/FileNameUnitTest.php @@ -97,11 +97,6 @@ protected function getTestFiles( $testFileBase ) { $sep = DIRECTORY_SEPARATOR; $test_files = glob( dirname( $testFileBase ) . $sep . 'FileNameUnitTests{' . $sep . ',' . $sep . '*' . $sep . '}*.inc', GLOB_BRACE ); - // Adjust the expected results array for PHP 5.2 as PHP 5.2 does not recognize namespaces. - if ( PHP_VERSION_ID < 50300 ) { - $this->expected_results['test-sample-phpunit6.inc'] = 1; - } - if ( ! empty( $test_files ) ) { return $test_files; } diff --git a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php index 352f333a..10847157 100644 --- a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php +++ b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php @@ -52,12 +52,6 @@ public function getErrorList( $testFile = 'PrefixAllGlobalsUnitTest.inc' ) { 40 => 1, 90 => 1, 91 => 1, - // Scoped. - 149 => ( PHP_VERSION_ID >= 50300 ) ? 0 : 1, // PHPCS on PHP 5.2 does not recognize namespaces. - 151 => ( PHP_VERSION_ID >= 50300 ) ? 0 : 1, // PHPCS on PHP 5.2 does not recognize namespaces. - 153 => ( PHP_VERSION_ID >= 50300 ) ? 0 : 1, // PHPCS on PHP 5.2 does not recognize namespaces. - 154 => ( PHP_VERSION_ID >= 50300 ) ? 0 : 1, // PHPCS on PHP 5.2 does not recognize namespaces. - 155 => ( PHP_VERSION_ID >= 50300 ) ? 0 : 1, // PHPCS on PHP 5.2 does not recognize namespaces. // Backfills. 225 => ( function_exists( '\mb_strpos' ) ) ? 0 : 1, 230 => ( function_exists( '\array_column' ) ) ? 0 : 1, @@ -66,20 +60,7 @@ public function getErrorList( $testFile = 'PrefixAllGlobalsUnitTest.inc' ) { ); case 'PrefixAllGlobalsUnitTest.1.inc': - // Namespaced - all OK. - if ( PHP_VERSION_ID >= 50300 ) { - return array(); - } - - // PHPCS on PHP 5.2 does not recognize namespaces. - return array( - 9 => 1, - 11 => 1, - 13 => 1, - 14 => 1, - 15 => 1, - ); - + // Namespaced - all OK, fall through to the default case. default: return array(); diff --git a/WordPress/Tests/VIP/AdminBarRemovalUnitTest.php b/WordPress/Tests/VIP/AdminBarRemovalUnitTest.php index 3e07aa63..7adbae60 100644 --- a/WordPress/Tests/VIP/AdminBarRemovalUnitTest.php +++ b/WordPress/Tests/VIP/AdminBarRemovalUnitTest.php @@ -43,9 +43,9 @@ public function getErrorList( $testFile = '' ) { 21 => 1, 26 => 1, 32 => 1, - 56 => ( PHP_VERSION_ID >= 50300 ) ? 1 : 0, // PHPCS on PHP 5.2 does not recognize T_NOWDOC. - 57 => ( PHP_VERSION_ID >= 50300 ) ? 1 : 0, // PHPCS on PHP 5.2 does not recognize T_NOWDOC. - 58 => ( PHP_VERSION_ID >= 50300 ) ? 1 : 0, // PHPCS on PHP 5.2 does not recognize T_NOWDOC. + 56 => 1, + 57 => 1, + 58 => 1, 68 => 1, 69 => 1, 70 => 1, @@ -60,7 +60,7 @@ public function getErrorList( $testFile = '' ) { case 'AdminBarRemovalUnitTest.css': return array( - 15 => 1, + 15 => 1, 16 => 1, 17 => 1, 22 => 1, diff --git a/WordPress/Tests/VIP/DirectDatabaseQueryUnitTest.php b/WordPress/Tests/VIP/DirectDatabaseQueryUnitTest.php index 0a45e117..41a8d786 100644 --- a/WordPress/Tests/VIP/DirectDatabaseQueryUnitTest.php +++ b/WordPress/Tests/VIP/DirectDatabaseQueryUnitTest.php @@ -41,7 +41,7 @@ public function getErrorList() { 190 => 1, 250 => 1, 257 => 1, - 274 => ( PHP_VERSION_ID >= 50300 ) ? 1 : 0, // PHPCS on PHP 5.2 does not recognize T_NOWDOC. + 274 => 1, ); } diff --git a/WordPress/Tests/VIP/PluginMenuSlugUnitTest.php b/WordPress/Tests/VIP/PluginMenuSlugUnitTest.php index e8b14271..5a8307c2 100644 --- a/WordPress/Tests/VIP/PluginMenuSlugUnitTest.php +++ b/WordPress/Tests/VIP/PluginMenuSlugUnitTest.php @@ -28,10 +28,9 @@ class PluginMenuSlugUnitTest extends AbstractSniffUnitTest { */ public function getErrorList() { return array( - 3 => 1, - 5 => 1, - 9 => 2, - 14 => ( PHP_VERSION_ID < 50300 ) ? 1 : 0, // PHPCS on PHP 5.2 does not recognize T_NS_SEPARATOR. + 3 => 1, + 5 => 1, + 9 => 2, ); } diff --git a/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.php b/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.php index 33d09b3f..341e85e9 100644 --- a/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.php +++ b/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.php @@ -30,7 +30,6 @@ public function getErrorList() { return array( 3 => 1, 17 => 1, - 30 => ( PHP_VERSION_ID >= 50300 ) ? 0 : 1, 32 => 1, 34 => 1, 36 => 1, diff --git a/WordPress/Tests/WP/CapitalPDangitUnitTest.1.inc b/WordPress/Tests/WP/CapitalPDangitUnitTest.1.inc deleted file mode 100644 index 62e82673..00000000 --- a/WordPress/Tests/WP/CapitalPDangitUnitTest.1.inc +++ /dev/null @@ -1,10 +0,0 @@ - wordpress.pot + + wordpress.pot + + => */ - public function getWarningList( $testFile = 'CapitalPDangitUnitTest.inc' ) { + public function getWarningList() { - switch ( $testFile ) { - case 'CapitalPDangitUnitTest.inc': - return array( - 3 => 1, - 5 => 1, - 8 => 1, - 26 => 1, - 28 => 1, - 34 => 1, - 35 => 1, - 36 => 1, - 40 => 1, - 41 => 1, - 45 => 1, - 53 => 1, - 60 => 1, - 61 => 1, - 62 => 1, - 65 => 1, - 66 => 1, - 68 => ( PHP_VERSION_ID >= 50300 ) ? 1 : 2, // PHPCS on PHP 5.2 apparently breaks the token up into two tokens. - 101 => 1, - 139 => 1, - 146 => 0, // False negative. - 173 => 1, - ); + return array( + 3 => 1, + 5 => 1, + 8 => 1, + 26 => 1, + 28 => 1, + 34 => 1, + 35 => 1, + 36 => 1, + 40 => 1, + 41 => 1, + 45 => 1, + 53 => 1, + 60 => 1, + 61 => 1, + 62 => 1, + 65 => 1, + 66 => 1, + 68 => 1, + 101 => 1, + 139 => 1, + 146 => 0, // False negative. + 173 => 1, + 181 => 1, + ); - case 'CapitalPDangitUnitTest.1.inc': - return array( - 9 => ( PHP_VERSION_ID >= 50300 ) ? 1 : 0, // PHPCS on PHP 5.2 does not recognize nowdocs. - ); - - default: - return array(); - - } // End switch(). } } // End class. diff --git a/WordPress/Tests/WP/EnqueuedResourcesUnitTest.php b/WordPress/Tests/WP/EnqueuedResourcesUnitTest.php index d36bb6aa..dd19200c 100644 --- a/WordPress/Tests/WP/EnqueuedResourcesUnitTest.php +++ b/WordPress/Tests/WP/EnqueuedResourcesUnitTest.php @@ -29,9 +29,9 @@ class EnqueuedResourcesUnitTest extends AbstractSniffUnitTest { public function getErrorList() { return array( 1 => 1, - 2 => ( PHP_VERSION_ID >= 50300 ) ? 1 : 0, // PHPCS on PHP 5.2 has a bug tokenizing inline HTML / ` 1, 6 => 1, - 7 => ( PHP_VERSION_ID >= 50300 ) ? 1 : 0, // PHPCS on PHP 5.2 has a bug tokenizing inline HTML / ` 1, 10 => 1, 11 => 1, 13 => 1, @@ -40,10 +40,10 @@ public function getErrorList() { 17 => 1, 20 => 1, 21 => 1, - 25 => ( PHP_VERSION_ID >= 50300 ) ? 1 : 0, // PHPCS on PHP 5.2 does not recognize double quoted T_HEREDOC. - 26 => ( PHP_VERSION_ID >= 50300 ) ? 1 : 0, // PHPCS on PHP 5.2 does not recognize double quoted T_HEREDOC. - 30 => 1, // PHPCS on PHP 5.2 does not recognize T_NOWDOC, but sees this as a literal string anyway. - 31 => ( PHP_VERSION_ID >= 50300 ) ? 1 : 0, // PHPCS on PHP 5.2 does not recognize T_NOWDOC. + 25 => 1, + 26 => 1, + 30 => 1, + 31 => 1, ); } diff --git a/WordPress/Tests/WP/I18nUnitTest.php b/WordPress/Tests/WP/I18nUnitTest.php index 7a44bebd..0083094b 100644 --- a/WordPress/Tests/WP/I18nUnitTest.php +++ b/WordPress/Tests/WP/I18nUnitTest.php @@ -106,7 +106,7 @@ public function getErrorList( $testFile = 'I18nUnitTest.inc' ) { 125 => 1, 128 => 1, 129 => 1, - 132 => ( PHP_VERSION_ID >= 50300 ) ? 1 : 2, // PHPCS on PHP 5.2 does not recognize T_NOWDOC. + 132 => 1, 138 => 1, 143 => 1, 148 => 1, diff --git a/WordPress/Tests/WP/PreparedSQLUnitTest.php b/WordPress/Tests/WP/PreparedSQLUnitTest.php index 2b061966..bccc30f1 100644 --- a/WordPress/Tests/WP/PreparedSQLUnitTest.php +++ b/WordPress/Tests/WP/PreparedSQLUnitTest.php @@ -29,7 +29,7 @@ class PreparedSQLUnitTest extends AbstractSniffUnitTest { * @return array => */ public function getErrorList() { - $errors = array( + return array( 3 => 1, 4 => 1, 5 => 1, @@ -44,23 +44,6 @@ public function getErrorList() { 64 => 1, 71 => 1, ); - - // Deal with PHP 5.2 not recognizing quoted heredoc openers, nor nowdoc syntax. - // These are all false positives! - if ( PHP_VERSION_ID < 50300 ) { - $errors[68] = 2; - $errors[69] = 2; - $errors[70] = 2; - $errors[71] = 4; - $errors[75] = 2; - $errors[76] = 7; - $errors[77] = 4; - $errors[78] = 5; - $errors[79] = 7; - $errors[80] = 1; - } - - return $errors; } /** diff --git a/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.php b/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.php index 7c63a07c..642f69c4 100644 --- a/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.php +++ b/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.php @@ -21,17 +21,6 @@ */ class ControlStructureSpacingUnitTest extends AbstractSniffUnitTest { - /** - * Skip this test on PHP 5.2. - * - * @since 0.9.0 - * - * @return bool Whether to skip this test. - */ - protected function shouldSkipTest() { - return ( PHP_VERSION_ID < 50300 ); - } - /** * Returns the lines where errors should occur. * diff --git a/WordPress/Tests/XSS/EscapeOutputUnitTest.php b/WordPress/Tests/XSS/EscapeOutputUnitTest.php index b5560247..0be554aa 100644 --- a/WordPress/Tests/XSS/EscapeOutputUnitTest.php +++ b/WordPress/Tests/XSS/EscapeOutputUnitTest.php @@ -69,7 +69,6 @@ public function getErrorList() { 205 => 1, 206 => 1, 207 => 1, - 212 => ( PHP_VERSION_ID < 50300 ) ? 1 : 0, // PHPCS on PHP 5.2 does not recognize T_NOWDOC. 223 => 1, 225 => 1, 226 => 1, From 15307be48025c52bd0e10c473a2d9e39f8a72dd3 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Mon, 15 May 2017 15:23:34 +0200 Subject: [PATCH 141/282] PHPCS 3.x compat: remove work-arounds for compatibility with PHP 5.2 This should also allow the unit tests to pass against on PHP nightly. --- WordPress/Sniffs/VIP/ValidatedSanitizedInputSniff.php | 4 +++- WordPress/Sniffs/WP/PreparedSQLSniff.php | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/WordPress/Sniffs/VIP/ValidatedSanitizedInputSniff.php b/WordPress/Sniffs/VIP/ValidatedSanitizedInputSniff.php index 04a5e870..704a16eb 100644 --- a/WordPress/Sniffs/VIP/ValidatedSanitizedInputSniff.php +++ b/WordPress/Sniffs/VIP/ValidatedSanitizedInputSniff.php @@ -95,7 +95,9 @@ public function process_token( $stackPtr ) { || T_HEREDOC === $this->tokens[ $stackPtr ]['code'] ) { $interpolated_variables = array_map( - create_function( '$symbol', 'return "$" . $symbol;' ), // Replace with closure when 5.3 is minimum requirement for PHPCS. + function ( $symbol ) { + return '$' . $symbol; + }, $this->get_interpolated_variables( $this->tokens[ $stackPtr ]['content'] ) ); foreach ( array_intersect( $interpolated_variables, $superglobals ) as $bad_variable ) { diff --git a/WordPress/Sniffs/WP/PreparedSQLSniff.php b/WordPress/Sniffs/WP/PreparedSQLSniff.php index e9fef1af..b695d29e 100644 --- a/WordPress/Sniffs/WP/PreparedSQLSniff.php +++ b/WordPress/Sniffs/WP/PreparedSQLSniff.php @@ -139,7 +139,9 @@ public function process_token( $stackPtr ) { $bad_variables = array_filter( $this->get_interpolated_variables( $this->tokens[ $this->i ]['content'] ), - create_function( '$symbol', 'return ( $symbol !== "wpdb" );' ) // Replace this with closure once 5.3 is minimum requirement. + function ( $symbol ) { + return ( 'wpdb' !== $symbol ); + } ); foreach ( $bad_variables as $bad_variable ) { From cdd8a7e0e043aced139fb0ca8f5e867b43bd1a9e Mon Sep 17 00:00:00 2001 From: Barry Ceelen Date: Tue, 25 Jul 2017 12:34:00 +0200 Subject: [PATCH 142/282] Update .travis.yml example --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d345b28b..49453cc5 100644 --- a/README.md +++ b/README.md @@ -244,8 +244,8 @@ matrix: env: SNIFF=1 before_install: - - if [[ "$SNIFF" == "1" ]]; export PHPCS_DIR=/tmp/phpcs; fi - - if [[ "$SNIFF" == "1" ]]; export SNIFFS_DIR=/tmp/sniffs; fi + - if [[ "$SNIFF" == "1" ]]; then export PHPCS_DIR=/tmp/phpcs; fi + - if [[ "$SNIFF" == "1" ]]; then export SNIFFS_DIR=/tmp/sniffs; fi # Install PHP CodeSniffer. - if [[ "$SNIFF" == "1" ]]; then git clone -b master --depth 1 https://github.com/squizlabs/PHP_CodeSniffer.git $PHPCS_DIR; fi # Install WordPress Coding Standards. From 857ba9b4e8008a620b33571b9bc79d5dc6722c29 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 25 Jul 2017 14:50:51 +0200 Subject: [PATCH 143/282] PHPCS 3.x compat: prevent conflicts with other standards. Fix a mixup between `class_exists()` and `interface_exists()`: * `PHP_CodeSniffer_Sniff` is the interface. * `PHP_CodeSniffer_File` is a class. --- WordPress/PHPCSAliases.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/WordPress/PHPCSAliases.php b/WordPress/PHPCSAliases.php index 052a0663..9a4fdaf2 100644 --- a/WordPress/PHPCSAliases.php +++ b/WordPress/PHPCSAliases.php @@ -25,15 +25,15 @@ */ if ( ! defined( 'WPCS_PHPCS_ALIASES_SET' ) ) { // PHPCS base classes/interface. - if ( ! interface_exists( '\PHP_CodeSniffer_File' ) ) { + if ( ! interface_exists( '\PHP_CodeSniffer_Sniff' ) ) { + class_alias( 'PHP_CodeSniffer\Sniffs\Sniff', '\PHP_CodeSniffer_Sniff' ); + } + if ( ! class_exists( '\PHP_CodeSniffer_File' ) ) { class_alias( 'PHP_CodeSniffer\Files\File', '\PHP_CodeSniffer_File' ); } if ( ! class_exists( '\PHP_CodeSniffer_Tokens' ) ) { class_alias( 'PHP_CodeSniffer\Util\Tokens', '\PHP_CodeSniffer_Tokens' ); } - if ( ! class_exists( '\PHP_CodeSniffer_Sniff' ) ) { - class_alias( 'PHP_CodeSniffer\Sniffs\Sniff', '\PHP_CodeSniffer_Sniff' ); - } // PHPCS classes which are being extended by WPCS sniffs. if ( ! class_exists( '\PHP_CodeSniffer_Standards_AbstractVariableSniff' ) ) { From 6dc72a5ccc4e9bc009f8deabcbac804a18083e56 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 22 Jul 2017 18:41:15 +0200 Subject: [PATCH 144/282] PHPCS 3.x compat: Implement recognition of the `--ignore-annotations` setting See issue 862 --- WordPress/PHPCSHelper.php | 26 ++++++++++++++++++++++++++ WordPress/Sniff.php | 5 +++++ 2 files changed, 31 insertions(+) diff --git a/WordPress/PHPCSHelper.php b/WordPress/PHPCSHelper.php index 88179006..96961837 100644 --- a/WordPress/PHPCSHelper.php +++ b/WordPress/PHPCSHelper.php @@ -112,4 +112,30 @@ public static function get_tab_width( File $phpcsFile ) { return $tab_width; } + /** + * Check whether the `--ignore-annotations` option has been used. + * + * @since 0.13.0 + * + * @param \PHP_CodeSniffer\Files\File $phpcsFile Optional. The current file being processed. + * + * @return bool True if annotations should be ignored, false otherwise. + */ + public static function ignore_annotations( File $phpcsFile = null ) { + if ( class_exists( '\PHP_CodeSniffer\Config' ) ) { + // PHPCS 3.x. + if ( isset( $phpcsFile, $phpcsFile->config->annotations ) ) { + return ! $phpcsFile->config->annotations; + } else { + $annotations = \PHP_CodeSniffer\Config::getConfigData( 'annotations' ); + if ( isset( $annotations ) ) { + return ! $annotations; + } + } + } + + // PHPCS 2.x does not support `--ignore-annotations`. + return false; + } + } diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index 5cb01112..c6ae1691 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -1066,6 +1066,11 @@ protected function get_last_ptr_on_line( $stackPtr ) { */ protected function has_whitelist_comment( $comment, $stackPtr ) { + // Respect the PHPCS 3.x --ignore-annotations setting. + if ( true === PHPCSHelper::ignore_annotations( $this->phpcsFile ) ) { + return false; + } + $lastPtr = $this->get_last_ptr_on_line( $stackPtr ); $end_of_line = $lastPtr; From e7f2af57f1d8dabb07d00395eca076b76f979310 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 26 Jul 2017 10:11:11 +0200 Subject: [PATCH 145/282] Update the pre-commit hook code This update presume that devs using this pre-commit hook will be using PHPCS 3.x. --- bin/pre-commit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/pre-commit b/bin/pre-commit index 24de124e..79e5b423 100755 --- a/bin/pre-commit +++ b/bin/pre-commit @@ -11,4 +11,4 @@ fi find . \( -name '*.php' \) -exec php -lf {} \; -phpunit --filter WordPress "$phpcs_root/tests/AllTests.php" +phpunit --bootstrap="./../Test/phpcs3-bootstrap.php" --filter WordPress "$phpcs_root/tests/AllTests.php" From eeee6cf27e805f168fd8f743f272d0838bff3595 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Wed, 26 Jul 2017 09:53:20 -0700 Subject: [PATCH 146/282] Update call to phpunit with required env var and fxed bootstrap path --- bin/pre-commit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/pre-commit b/bin/pre-commit index 79e5b423..4b3e665d 100755 --- a/bin/pre-commit +++ b/bin/pre-commit @@ -11,4 +11,4 @@ fi find . \( -name '*.php' \) -exec php -lf {} \; -phpunit --bootstrap="./../Test/phpcs3-bootstrap.php" --filter WordPress "$phpcs_root/tests/AllTests.php" +PHPCS_DIR=$phpcs_root phpunit --bootstrap="./Test/phpcs3-bootstrap.php" --filter WordPress "$phpcs_root/tests/AllTests.php" From be1cd3bc49d27430112a14bb1336c2dc068a4e77 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 27 Jul 2017 13:19:35 +0200 Subject: [PATCH 147/282] Move `CONTRIBUTING.MD` to `.github` Helps keep the root directory clean of GH specific files. --- CONTRIBUTING.md => .github/CONTRIBUTING.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename CONTRIBUTING.md => .github/CONTRIBUTING.md (100%) diff --git a/CONTRIBUTING.md b/.github/CONTRIBUTING.md similarity index 100% rename from CONTRIBUTING.md rename to .github/CONTRIBUTING.md From 45d841c7cef05175c319de8e2c2f97aa41af0a51 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 27 Jul 2017 14:27:00 +0200 Subject: [PATCH 148/282] Minor code style fix Old habits die hard ;-) --- Test/phpcs2-bootstrap.php | 2 +- Test/phpcs3-bootstrap.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Test/phpcs2-bootstrap.php b/Test/phpcs2-bootstrap.php index 2a0cb3c7..16da9abc 100644 --- a/Test/phpcs2-bootstrap.php +++ b/Test/phpcs2-bootstrap.php @@ -21,7 +21,7 @@ if ( false === $phpcsDir && is_dir( dirname( __DIR__ ) . $ds . 'vendor' . $ds . 'squizlabs' . $ds . 'php_codesniffer' ) ) { $phpcsDir = dirname( __DIR__ ) . $ds . 'vendor' . $ds . 'squizlabs' . $ds . 'php_codesniffer'; -} else if ( false !== $phpcsDir ) { +} elseif ( false !== $phpcsDir ) { $phpcsDir = realpath( $phpcsDir ); } diff --git a/Test/phpcs3-bootstrap.php b/Test/phpcs3-bootstrap.php index e01cf155..eb56399a 100644 --- a/Test/phpcs3-bootstrap.php +++ b/Test/phpcs3-bootstrap.php @@ -27,7 +27,7 @@ // This may be a Composer install. if ( false === $phpcsDir && is_dir( dirname( __DIR__ ) . $ds . 'vendor' . $ds . 'squizlabs' . $ds . 'php_codesniffer' ) ) { $phpcsDir = dirname( __DIR__ ) . $ds . 'vendor' . $ds . 'squizlabs' . $ds . 'php_codesniffer'; -} else if ( false !== $phpcsDir ) { +} elseif ( false !== $phpcsDir ) { $phpcsDir = realpath( $phpcsDir ); } From e4c86d718ca54b3e73ae89ee0fee2f734a131088 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 27 Jul 2017 15:39:54 +0200 Subject: [PATCH 149/282] Adjust the URL to the contributing file where relevant --- README.md | 2 +- Test/bootstrap.php | 2 +- Test/phpcs2-bootstrap.php | 2 +- Test/phpcs3-bootstrap.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 49453cc5..19ac9843 100644 --- a/README.md +++ b/README.md @@ -272,7 +272,7 @@ You can find information on how to deal with some of the more frequent issues in ## Contributing -See [CONTRIBUTING](CONTRIBUTING.md), including information about [unit testing](CONTRIBUTING.md#unit-testing) the standard. +See [CONTRIBUTING](.github/CONTRIBUTING.md), including information about [unit testing](.github/CONTRIBUTING.md#unit-testing) the standard. ## License diff --git a/Test/bootstrap.php b/Test/bootstrap.php index caceb954..996c887c 100644 --- a/Test/bootstrap.php +++ b/Test/bootstrap.php @@ -29,7 +29,7 @@ phpunit --bootstrap="./Test/phpcs2-bootstrap.php" --filter WordPress ./Test/AllTests.php Please read the contributors guidelines for more information: -https://is.gd/WPCScontributing +https://is.gd/contributing2WPCS '; die( 1 ); diff --git a/Test/phpcs2-bootstrap.php b/Test/phpcs2-bootstrap.php index 2a0cb3c7..694e221c 100644 --- a/Test/phpcs2-bootstrap.php +++ b/Test/phpcs2-bootstrap.php @@ -35,7 +35,7 @@ pointing to the PHPCS directory. Please read the contributors guidelines for more information: -https://is.gd/WPCScontributing +https://is.gd/contributing2WPCS '; die( 1 ); diff --git a/Test/phpcs3-bootstrap.php b/Test/phpcs3-bootstrap.php index e01cf155..ff489989 100644 --- a/Test/phpcs3-bootstrap.php +++ b/Test/phpcs3-bootstrap.php @@ -42,7 +42,7 @@ pointing to the PHPCS directory. Please read the contributors guidelines for more information: -https://is.gd/WPCScontributing +https://is.gd/contributing2WPCS '; die( 1 ); From c33af153d885b9f0e3a897c94f84856fec86f063 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 27 Jul 2017 13:17:10 +0200 Subject: [PATCH 150/282] Add a .gitattributes file This PR adds a `.gitattributes` file to keep the archives GH creates of the repo clean of development related files. People using Composer can still get these files in their setup if they really want to, by using `--prefer-source`. Refs: * [Reddit: I don't need your tests in my production](https://www.reddit.com/r/PHP/comments/2jzp6k/i_dont_need_your_tests_in_my_production) * [Blog: I don't need your tests in my production](https://blog.madewithlove.be/post/gitattributes/) --- .gitattributes | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..3fb449f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,25 @@ +# +# Exclude these files from release archives. +# This will also make them unavailable when using Composer with `--prefer-dist`. +# If you develop for WPCS using Composer, use `--prefer-source`. +# https://blog.madewithlove.be/post/gitattributes/ +# +/.travis.yml export-ignore +/phpunit.xml.dist export-ignore +/.github export-ignore +/bin export-ignore +/Test export-ignore +/WordPress/Tests export-ignore + +# +# Auto detect text files and perform LF normalization +# http://davidlaing.com/2012/09/19/customise-your-gitattributes-to-become-a-git-ninja/ +# +* text=auto + +# +# The above will handle all files NOT found below +# +*.md text +*.php text +*.inc text From 1450f419759794b6b55fcdbcf1203763e39e725d Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 27 Jul 2017 16:12:55 +0200 Subject: [PATCH 151/282] CONTRIBUTING: add note about using `--prefer-source` with Composer --- .github/CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index cc7eddf2..66e89a3a 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -72,6 +72,8 @@ The WordPress Coding Standards use the PHP CodeSniffer native unit test suite fo Presuming you have installed PHP CodeSniffer and the WordPress-Coding-Standards as [noted in the README](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards#how-to-use-this), all you need now is `PHPUnit`. +N.B.: If you installed WPCS using Composer, make sure you used `--prefer-source` or run `composer install --prefer-source` now to make sure the unit tests are available. + If you already have PHPUnit installed on your system: Congrats, you're all set. If not, you can navigate to the directory where the `PHP_CodeSniffer` repo is checked out and do `composer install` to install the `dev` dependencies. From 1b54c0930e7804151b94500666d95f0fd234cb39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20=C5=BDoljom?= Date: Fri, 28 Jul 2017 10:12:22 +0200 Subject: [PATCH 152/282] Add issue template (#1072) Add issue template --- .github/issue_template.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/issue_template.md diff --git a/.github/issue_template.md b/.github/issue_template.md new file mode 100644 index 00000000..f6e4f498 --- /dev/null +++ b/.github/issue_template.md @@ -0,0 +1,11 @@ + \ No newline at end of file From 4f41c4b2827e56bc5fa3949062fe0cccb75f3c48 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 1 Aug 2017 17:14:40 +0200 Subject: [PATCH 153/282] Explicitly recommend v0.4.1+ of the DealerDirect Composer plugin Version 0.4.0 of the DealerDirect Composer plugin registers each standard individually as if they were root-directory standards, not a collection of standards which exposes a bug in PHPCS 3.x. Refs: * squizlabs/PHP_CodeSniffer/pull/1581 * DealerDirect/phpcodesniffer-composer-installer/issues/33 --- README.md | 2 +- composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 19ac9843..9466fce0 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ For the convenience of using `phpcs` as a global command, you may want to add th When installing the WordPress Coding Standards as a dependency in a larger project, the above mentioned step 3 will not be executed automatically. There are two actively maintained Composer plugins which can handle the registration of standards with PHP_CodeSniffer for you: -* [composer-phpcodesniffer-standards-plugin](https://github.com/higidi/composer-phpcodesniffer-standards-plugin) +* [composer-phpcodesniffer-standards-plugin](https://github.com/higidi/composer-phpcodesniffer-standards-plugin):"^0.4.1" * [phpcodesniffer-composer-installer](https://github.com/DealerDirect/phpcodesniffer-composer-installer) It is strongly suggested to `require` one of these plugins in your project to handle the registration of external standards with PHPCS for you. diff --git a/composer.json b/composer.json index 1b5e513a..9a5568fd 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "squizlabs/php_codesniffer": "^2.9.0 || ^3.0.2" }, "suggest" : { - "dealerdirect/phpcodesniffer-composer-installer": "*" + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.1" }, "minimum-stability" : "RC", "support" : { From 76b4e1bb365d118f92f41b2b250cb5149464983e Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 2 Aug 2017 00:00:02 +0200 Subject: [PATCH 154/282] Fix the version recommendation --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9466fce0..92b076eb 100644 --- a/README.md +++ b/README.md @@ -65,8 +65,8 @@ For the convenience of using `phpcs` as a global command, you may want to add th When installing the WordPress Coding Standards as a dependency in a larger project, the above mentioned step 3 will not be executed automatically. There are two actively maintained Composer plugins which can handle the registration of standards with PHP_CodeSniffer for you: -* [composer-phpcodesniffer-standards-plugin](https://github.com/higidi/composer-phpcodesniffer-standards-plugin):"^0.4.1" -* [phpcodesniffer-composer-installer](https://github.com/DealerDirect/phpcodesniffer-composer-installer) +* [composer-phpcodesniffer-standards-plugin](https://github.com/higidi/composer-phpcodesniffer-standards-plugin) +* [phpcodesniffer-composer-installer](https://github.com/DealerDirect/phpcodesniffer-composer-installer):"^0.4.1" It is strongly suggested to `require` one of these plugins in your project to handle the registration of external standards with PHPCS for you. From aebfc8a87788e395c65d2d7f9721dcb48015b8a4 Mon Sep 17 00:00:00 2001 From: Juliette Date: Thu, 3 Aug 2017 03:51:21 +0200 Subject: [PATCH 155/282] Changelog for the 0.13.0 release. (#1058) Changelog for the 0.13.0 release. --- CHANGELOG.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e816e00..81b6d466 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,28 @@ This projects adheres to [Semantic Versioning](http://semver.org/) and [Keep a C _Nothing yet._ +## [0.13.0] - 2017-08-03 + +### Added +- Support for PHP CodeSniffer 3.0.2+. The minimum required PHPCS version (2.9.0) stays the same. +- Support for the PHPCS 3 `--ignore-annotations` command line option. If you pass this option, both PHPCS native `@ignore ...` annotations as well as the WPCS specific [whitelist flags](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Whitelisting-code-which-flags-errors) will be ignored. + +### Changed +- The minimum required PHP version is now 5.3 when used in combination with PHPCS 2.x and PHP 5.4 when used in combination with PHPCS 3.x. +- The way the unit tests can be run is now slightly different for PHPCS 2.x versus 3.x. For more details, please refer to the updated information in the [Contributing Guidelines](CONTRIBUTING.md). +- Release archives will no longer contain the unit tests and other typical development files. You can still get these by using Composer with `--prefer-source` or by checking out a git clone of the repository. +- Various textual improvements to the Readme. +- Various textual improvements to the Contributing Guidelines. +- Minor internal changes. + +### Removed +- The `WordPress.Arrays.ArrayDeclaration` sniff has been deprecated. The last remaining checks this sniff contained have been moved to the `WordPress.Arrays.ArrayDeclarationSpacing` sniff. +- Work-arounds which were in place to support PHP 5.2. + +### Fixed +- A minor bug where the auto-fixer could accidentally remove a comment near an array opener. + + ## [0.12.0] - 2017-07-21 ### Added @@ -436,6 +458,7 @@ See the comparison for full list. Initial tagged release. [Unreleased]: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/compare/master...HEAD +[0.13.0]: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/compare/0.12.0...0.13.0 [0.12.0]: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/compare/0.11.0...0.12.0 [0.11.0]: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/compare/0.10.0...0.11.0 [0.10.0]: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/compare/0.9.0...0.10.0 From bf465667368e98a52c26401641fcc07bf7248c8f Mon Sep 17 00:00:00 2001 From: Websupporter Date: Thu, 3 Aug 2017 05:05:35 +0300 Subject: [PATCH 156/282] Make comparision in StrictInArraySniff unaware of uppercase With using strtolower the check does not implicitly rely on constants being lowercase. Solves #1061 --- WordPress/Sniffs/PHP/StrictInArraySniff.php | 2 +- WordPress/Tests/PHP/StrictInArrayUnitTest.inc | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/WordPress/Sniffs/PHP/StrictInArraySniff.php b/WordPress/Sniffs/PHP/StrictInArraySniff.php index 45a68b9e..f81b0a11 100644 --- a/WordPress/Sniffs/PHP/StrictInArraySniff.php +++ b/WordPress/Sniffs/PHP/StrictInArraySniff.php @@ -80,7 +80,7 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p } // We're only interested in the third parameter. - if ( false === isset( $parameters[3] ) || 'true' !== $parameters[3]['raw'] ) { + if ( false === isset( $parameters[3] ) || 'true' !== strtolower( $parameters[3]['raw'] ) ) { $this->phpcsFile->addWarning( 'Not using strict comparison for %s; supply true for third argument.', ( isset( $parameters[3]['start'] ) ? $parameters[3]['start'] : $parameters[1]['start'] ), diff --git a/WordPress/Tests/PHP/StrictInArrayUnitTest.inc b/WordPress/Tests/PHP/StrictInArrayUnitTest.inc index df9372fa..76921436 100644 --- a/WordPress/Tests/PHP/StrictInArrayUnitTest.inc +++ b/WordPress/Tests/PHP/StrictInArrayUnitTest.inc @@ -34,4 +34,6 @@ array_keys( array( '1', 1, true ), 'my_key', true ); // Ok. array_keys( $testing, 'my_key' ); // Warning. array_keys( array( '1', 1, true ), 'my_key' ); // Warning. array_keys( $testing, 'my_key', false ); // Warning. -array_keys( array( '1', 1, true ), 'my_key', false ); // Warning. +array_keys( array( '1', 1, true ), 'my_key', false ); // Warning +in_array( 1, array( '1', 1 ), TRUE ); // Ok. + From f08e718092fca9e95b8132fe43394b0f8432f53a Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 26 Jul 2017 12:17:54 +0200 Subject: [PATCH 157/282] ArrayIndentation sniff: fix bug with multi-line strings as array value Subsequent lines in a multi-line text string should be ignored as the chosen indentation should be presumed intentional, like for HTML snippets. Includes additional unit tests. --- .../Sniffs/Arrays/ArrayIndentationSniff.php | 37 +++++++++++- .../Arrays/ArrayIndentationUnitTest.1.inc | 57 ++++++++++++++++++ .../ArrayIndentationUnitTest.1.inc.fixed | 57 ++++++++++++++++++ .../Arrays/ArrayIndentationUnitTest.2.inc | 59 ++++++++++++++++++- .../ArrayIndentationUnitTest.2.inc.fixed | 59 ++++++++++++++++++- .../Tests/Arrays/ArrayIndentationUnitTest.php | 3 + 6 files changed, 267 insertions(+), 5 deletions(-) diff --git a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php index e8c04b14..8262db0c 100644 --- a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php @@ -224,9 +224,11 @@ public function process_token( $stackPtr ) { // Find first token on second line of the array item. // If the second line is a heredoc/nowdoc, continue on until we find a line with a different token. + // Same for the second line of a multi-line text string. for ( $ptr = ( $first_content + 1 ); $ptr <= $item['end']; $ptr++ ) { if ( $this->tokens[ $first_content ]['line'] !== $this->tokens[ $ptr ]['line'] - && ! isset( $this->ignore_tokens[ $this->tokens[ $ptr ]['code'] ] ) + && 1 === $this->tokens[ $ptr ]['column'] + && false === $this->ignore_token( $ptr ) ) { break; } @@ -323,8 +325,8 @@ public function process_token( $stackPtr ) { break; } - // Ignore lines with heredoc and nowdoc tokens. - if ( isset( $this->ignore_tokens[ $this->tokens[ $first_content_on_line ]['code'] ] ) ) { + // Ignore lines with heredoc and nowdoc tokens and subsequent lines in multi-line strings. + if ( true === $this->ignore_token( $first_content_on_line ) ) { $i = $first_content_on_line; continue; } @@ -379,6 +381,35 @@ public function process_token( $stackPtr ) { } // End process_token(). + /** + * Should the token be ignored ? + * + * This method is only intended to be used with the first token on a line + * for subsequent lines in an multi-line array item. + * + * @param int $ptr Stack pointer to the first token on a line. + * + * @return bool + */ + protected function ignore_token( $ptr ) { + $token_code = $this->tokens[ $ptr ]['code']; + + if ( isset( $this->ignore_tokens[ $token_code ] ) ) { + return true; + } + + // If it's a subsequent line of a multi-line sting, it will not start with a quote character. + if ( ( T_CONSTANT_ENCAPSED_STRING === $token_code + || T_DOUBLE_QUOTED_STRING === $token_code ) + && "'" !== $this->tokens[ $ptr ]['content'][0] + && '"' !== $this->tokens[ $ptr ]['content'][0] + ) { + return true; + } + + return false; + } + /** * Determine the line indentation whitespace. * diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc index 3664f304..1cf6d43a 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc @@ -334,3 +334,60 @@ $my_array = [ */ apply_filters( '...', true ), ]; + +/* + * Test multi-line strings as the value for an array item. + */ +$test => array( + 'notes1' => '

      + Whether to use isset() or array_key_exists() depends on what you want to know: +

      ', + + 'notes1' => +'

      + Whether to use isset() or array_key_exists() depends on what you want to know: +

      ' . // The sniff should check & fix the next line as it is a new token. +'

      + This said, we can concluded that to avoid warnings and undesired results you will always have to use an is_array() first.
      + Also note that isset() is faster than array_key_exists(), but as said above, will return false if no value has been assigned. +

      ', + + 'notes1' => // Same, but now using double quotes. +"

      + Whether to use isset() or array_key_exists() depends on what you want to know: +

      " . // The sniff should check & fix the next line as it is a new token. +"

      + This said, we can concluded that to avoid warnings and undesired results you will always have to use an is_array() first.
      + Also note that isset() is faster than array_key_exists(), but as said above, will return false if no value has been assigned. +

      ", + + // Now using double quotes with a variable to force T_DOUBLE_QUOTED_STRING token. + 'notes1' => array( + "

      + Whether to use $abc or $def depends on what you want to know: +

      " . // The sniff should check & fix the next line as it is a new token. + "

      + This said, we can concluded that to avoid warnings and undesired results you will always have to use an is_array() first.
      + Also note that $abc is faster than $def, but as said above, will return false if no value has been assigned. +

      ", + ), + + 'notes2' => array( + '

      Important: Integers between -128 and 255 are interpreted as the ASCII value pointing to a character (negative values have 256 added in order to allow characters in the Extended ASCII range).
      + In any other case, integers are interpreted as a string containing the decimal digits of the integer.

      ', + ), + + 'tooltip' => ' +if( ! is_array( $x ) ) { + filter_var( $x, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ); +} +else { + filter_var_array( $x, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ); // = Simplified... see note +} + ', + 'notes3' => array( + '

      Please note: On some PHP versions filter_var( $x, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ) where $x = false will incorrectly return null.
      + Also: with the same parameters filter_var() will return false instead of null for most objects.

      ', + '

      The code snippet is simplified for brevity. Please refer to the source of this file on GitHub for full details on how to use filter_var_array().

      ', + ), +); diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc.fixed b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc.fixed index 82ae1228..8c557e8a 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc.fixed +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc.fixed @@ -334,3 +334,60 @@ $my_array = [ */ apply_filters( '...', true ), ]; + +/* + * Test multi-line strings as the value for an array item. + */ +$test => array( + 'notes1' => '

      + Whether to use isset() or array_key_exists() depends on what you want to know: +

      ', + + 'notes1' => + '

      + Whether to use isset() or array_key_exists() depends on what you want to know: +

      ' . // The sniff should check & fix the next line as it is a new token. + '

      + This said, we can concluded that to avoid warnings and undesired results you will always have to use an is_array() first.
      + Also note that isset() is faster than array_key_exists(), but as said above, will return false if no value has been assigned. +

      ', + + 'notes1' => // Same, but now using double quotes. + "

      + Whether to use isset() or array_key_exists() depends on what you want to know: +

      " . // The sniff should check & fix the next line as it is a new token. + "

      + This said, we can concluded that to avoid warnings and undesired results you will always have to use an is_array() first.
      + Also note that isset() is faster than array_key_exists(), but as said above, will return false if no value has been assigned. +

      ", + + // Now using double quotes with a variable to force T_DOUBLE_QUOTED_STRING token. + 'notes1' => array( + "

      + Whether to use $abc or $def depends on what you want to know: +

      " . // The sniff should check & fix the next line as it is a new token. + "

      + This said, we can concluded that to avoid warnings and undesired results you will always have to use an is_array() first.
      + Also note that $abc is faster than $def, but as said above, will return false if no value has been assigned. +

      ", + ), + + 'notes2' => array( + '

      Important: Integers between -128 and 255 are interpreted as the ASCII value pointing to a character (negative values have 256 added in order to allow characters in the Extended ASCII range).
      + In any other case, integers are interpreted as a string containing the decimal digits of the integer.

      ', + ), + + 'tooltip' => ' +if( ! is_array( $x ) ) { + filter_var( $x, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ); +} +else { + filter_var_array( $x, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ); // = Simplified... see note +} + ', + 'notes3' => array( + '

      Please note: On some PHP versions filter_var( $x, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ) where $x = false will incorrectly return null.
      + Also: with the same parameters filter_var() will return false instead of null for most objects.

      ', + '

      The code snippet is simplified for brevity. Please refer to the source of this file on GitHub for full details on how to use filter_var_array().

      ', + ), +); diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc index 497b308d..c54f893e 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc @@ -181,7 +181,7 @@ EOD // Should report the second line and fix the second line + the comma on the last line. get_current_screen()->add_help_tab( array( - 'id' => + 'id' => << array( + 'notes1' => '

      + Whether to use isset() or array_key_exists() depends on what you want to know: +

      ', + + 'notes1' => +'

      + Whether to use isset() or array_key_exists() depends on what you want to know: +

      ' . // The sniff should check & fix the next line as it is a new token. +'

      + This said, we can concluded that to avoid warnings and undesired results you will always have to use an is_array() first.
      + Also note that isset() is faster than array_key_exists(), but as said above, will return false if no value has been assigned. +

      ', + + 'notes1' => // Same, but now using double quotes. +"

      + Whether to use isset() or array_key_exists() depends on what you want to know: +

      " . // The sniff should check & fix the next line as it is a new token. +"

      + This said, we can concluded that to avoid warnings and undesired results you will always have to use an is_array() first.
      + Also note that isset() is faster than array_key_exists(), but as said above, will return false if no value has been assigned. +

      ", + + // Now using double quotes with a variable to force T_DOUBLE_QUOTED_STRING token. + 'notes1' => array( + "

      + Whether to use $abc or $def depends on what you want to know: +

      " . // The sniff should check & fix the next line as it is a new token. + "

      + This said, we can concluded that to avoid warnings and undesired results you will always have to use an is_array() first.
      + Also note that $abc is faster than $def, but as said above, will return false if no value has been assigned. +

      ", + ), + + 'notes2' => array( + '

      Important: Integers between -128 and 255 are interpreted as the ASCII value pointing to a character (negative values have 256 added in order to allow characters in the Extended ASCII range).
      + In any other case, integers are interpreted as a string containing the decimal digits of the integer.

      ', + ), + + 'tooltip' => ' +if( ! is_array( $x ) ) { + filter_var( $x, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ); +} +else { + filter_var_array( $x, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ); // = Simplified... see note +} + ', + 'notes3' => array( + '

      Please note: On some PHP versions filter_var( $x, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ) where $x = false will incorrectly return null.
      + Also: with the same parameters filter_var() will return false instead of null for most objects.

      ', + '

      The code snippet is simplified for brevity. Please refer to the source of this file on GitHub for full details on how to use filter_var_array().

      ', + ), +); + // @codingStandardsChangeSetting WordPress.Arrays.ArrayIndentation tabIndent true diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc.fixed b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc.fixed index 7bd7d39b..5be63e5a 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc.fixed +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc.fixed @@ -181,7 +181,7 @@ EOD // Should report the second line and fix the second line + the comma on the last line. get_current_screen()->add_help_tab( array( - 'id' => + 'id' => << array( + 'notes1' => '

      + Whether to use isset() or array_key_exists() depends on what you want to know: +

      ', + + 'notes1' => + '

      + Whether to use isset() or array_key_exists() depends on what you want to know: +

      ' . // The sniff should check & fix the next line as it is a new token. + '

      + This said, we can concluded that to avoid warnings and undesired results you will always have to use an is_array() first.
      + Also note that isset() is faster than array_key_exists(), but as said above, will return false if no value has been assigned. +

      ', + + 'notes1' => // Same, but now using double quotes. + "

      + Whether to use isset() or array_key_exists() depends on what you want to know: +

      " . // The sniff should check & fix the next line as it is a new token. + "

      + This said, we can concluded that to avoid warnings and undesired results you will always have to use an is_array() first.
      + Also note that isset() is faster than array_key_exists(), but as said above, will return false if no value has been assigned. +

      ", + + // Now using double quotes with a variable to force T_DOUBLE_QUOTED_STRING token. + 'notes1' => array( + "

      + Whether to use $abc or $def depends on what you want to know: +

      " . // The sniff should check & fix the next line as it is a new token. + "

      + This said, we can concluded that to avoid warnings and undesired results you will always have to use an is_array() first.
      + Also note that $abc is faster than $def, but as said above, will return false if no value has been assigned. +

      ", + ), + + 'notes2' => array( + '

      Important: Integers between -128 and 255 are interpreted as the ASCII value pointing to a character (negative values have 256 added in order to allow characters in the Extended ASCII range).
      + In any other case, integers are interpreted as a string containing the decimal digits of the integer.

      ', + ), + + 'tooltip' => ' +if( ! is_array( $x ) ) { + filter_var( $x, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ); +} +else { + filter_var_array( $x, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ); // = Simplified... see note +} + ', + 'notes3' => array( + '

      Please note: On some PHP versions filter_var( $x, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ) where $x = false will incorrectly return null.
      + Also: with the same parameters filter_var() will return false instead of null for most objects.

      ', + '

      The code snippet is simplified for brevity. Please refer to the source of this file on GitHub for full details on how to use filter_var_array().

      ', + ), +); + // @codingStandardsChangeSetting WordPress.Arrays.ArrayIndentation tabIndent true diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php index 73da54b5..b048c4b0 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php @@ -159,6 +159,9 @@ public function getErrorList() { 324 => 1, 331 => 1, 332 => 1, + 347 => 1, + 356 => 1, + 369 => 1, ); } From 06e57ef4b338d2caa870f6bb48e493922d3b1fdb Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 2 Aug 2017 17:50:37 +0200 Subject: [PATCH 158/282] PrefixAllGlobalsSniff: allow "prefix + non-word char" for improved support of hook names Words in hook names by default should be separated by underscores, however, this is checked by another sniff and not the concern of this sniff. As that sniff `ValidHookName` also allows for passing other separator characters, this sniff should allow for that. --- .../Sniffs/NamingConventions/PrefixAllGlobalsSniff.php | 10 ++++++++-- .../NamingConventions/PrefixAllGlobalsUnitTest.inc | 7 +++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php index 0cb22692..887d0408 100644 --- a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php +++ b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php @@ -643,10 +643,11 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p * Check if a function/class/constant/variable name is prefixed with one of the expected prefixes. * * @since 0.12.0 + * @since 0.14.0 Allows for other non-word characters as well as underscores to better support hook names. * * @param string $name Name to check for a prefix. * - * @return bool True when the name is the prefix or starts with the prefix + an underscore. + * @return bool True when the name is the prefix or starts with the prefix + a separator. * False otherwise. */ private function is_prefixed( $name ) { @@ -660,7 +661,12 @@ private function is_prefixed( $name ) { $prefix_found = stripos( $name, $prefix . '_' ); if ( 0 === $prefix_found ) { - // Ok, prefix found as start of hook/constant name. + // Ok, prefix found at start of hook/constant name. + return true; + } + + if ( preg_match( '`^' . preg_quote( $prefix, '`' ) . '\W`i', $name ) === 1 ) { + // Ok, prefix with other non-word character found at start of hook/constant name. return true; } } diff --git a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc index 4da7e2c0..cc258a13 100644 --- a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc +++ b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc @@ -299,3 +299,10 @@ class Acronym_Dynamic_Hooks { do_action( $this->parent_property ); // Warning. } } + +// Dashes and other non-word characters are ok as a hook name separator after the prefix. +// The rule that these should be underscores is handled by another sniff. +do_action( 'acronym-action' ); // OK. +apply_filters( 'acronym/filter', $var ); // OK. +do_action( "acronym-action-{$acronym_filter_var}" ); // OK. +apply_filters( 'acronym/filter-' . $acronym_filter_var ); // OK. From eb54d056e63f7489916e13f9275715f33d21e07c Mon Sep 17 00:00:00 2001 From: Alexis Kulash Date: Thu, 3 Aug 2017 09:18:19 -0400 Subject: [PATCH 159/282] Update the VIP.RestrictedFunctions sniff (#969) * As of WordPress 4.8, get_term_by() is cached so we're going to stop recommending the use of wpcom_vip_get_term_by() instead of the core function. The function wpcom_vip_get_term_by() will be deprecated. * Also revised the sniff for get_category_by_slug() because it uses get_term_by() which is now recommended over wpcom_vip_get_term_by(). * Removing get_term_link() as restricted/flagged functions Using get_term_link(), get_tag_link(), and get_category_link() is okay as of WP 4.8, so we no longer need to flag these instances. Revised VIP sniff and unit testing to flag wpcom_vip_get_term_link() as deprecated instead. --- .../Sniffs/VIP/RestrictedFunctionsSniff.php | 21 ++++++++----------- .../Tests/VIP/RestrictedFunctionsUnitTest.inc | 12 +++++------ .../Tests/VIP/RestrictedFunctionsUnitTest.php | 3 --- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php b/WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php index 41914ec2..c1b768b1 100644 --- a/WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php +++ b/WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php @@ -63,13 +63,11 @@ public function getGroups() { ), ), - 'get_term_link' => array( + 'wpcom_vip_get_term_link' => array( 'type' => 'error', - 'message' => '%s() is prohibited, please use wpcom_vip_get_term_link() instead.', + 'message' => '%s() is deprecated, please use get_term_link(), get_tag_link(), or get_category_link() instead.', 'functions' => array( - 'get_term_link', - 'get_tag_link', - 'get_category_link', + 'wpcom_vip_get_term_link', ), ), @@ -89,20 +87,19 @@ public function getGroups() { ), ), - 'get_term_by' => array( + 'wpcom_vip_get_term_by' => array( 'type' => 'error', - 'message' => '%s() is prohibited, please use wpcom_vip_get_term_by() instead.', + 'message' => '%s() is deprecated, please use get_term_by() or get_cat_ID() instead.', 'functions' => array( - 'get_term_by', - 'get_cat_ID', + 'wpcom_vip_get_term_by', ), ), - 'get_category_by_slug' => array( + 'wpcom_vip_get_category_by_slug' => array( 'type' => 'error', - 'message' => '%s() is prohibited, please use wpcom_vip_get_category_by_slug() instead.', + 'message' => '%s() is deprecated, please use get_category_by_slug() instead.', 'functions' => array( - 'get_category_by_slug', + 'wpcom_vip_get_category_by_slug', ), ), diff --git a/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.inc b/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.inc index 2d2982c4..8a8b2420 100644 --- a/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.inc +++ b/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.inc @@ -31,24 +31,24 @@ $y = Bar::add_role(); // Ok. \add_role(); // Error. -get_term_link( $term ); // Error. +wpcom_vip_get_term_link( $term ); // Error. get_page_by_path( $path ); // Error. get_page_by_title( $page_title ); // Error. -get_term_by( $field, $value, $taxonomy ); // Error. +wpcom_vip_get_term_by( $field, $value, $taxonomy ); // Error. -get_category_by_slug( $slug ); // Error. +wpcom_vip_get_category_by_slug( $slug ); // Error. url_to_postid( $url ); // Error. attachment_url_to_postid( $url ); // Error. wpcom_vip_attachment_url_to_postid( $url ); // Ok. -get_tag_link(); // Error. -get_category_link(); // Error. -get_cat_ID(); // Error. +get_tag_link(); // Ok. +get_category_link(); // Ok. +get_cat_ID(); // Ok. url_to_post_id(); // Error. get_posts(); // Warning. diff --git a/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.php b/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.php index 341e85e9..9853667b 100644 --- a/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.php +++ b/WordPress/Tests/VIP/RestrictedFunctionsUnitTest.php @@ -38,9 +38,6 @@ public function getErrorList() { 42 => 1, 44 => 1, 46 => 1, - 49 => 1, - 50 => 1, - 51 => 1, 52 => 1, 62 => 1, 63 => 1, From 3304604e5abdf635d189edb693f69b3a4fc1dd13 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 25 Jul 2017 11:29:08 +0200 Subject: [PATCH 160/282] PrefixAllGlobals: Improve recognition of namespaced constants using `define()` Notes: * Checking for the existance of a namespace separator should be enough here. * Using `__NAMESPACE__` outside of a namespace will result in an empty string, however, the `\` in the string following it will be part of the namespace name, making the constant effectively unreachable (which is not our concern). Fixes 1056 --- .../NamingConventions/PrefixAllGlobalsSniff.php | 5 +++++ .../NamingConventions/PrefixAllGlobalsUnitTest.1.inc | 3 +++ .../NamingConventions/PrefixAllGlobalsUnitTest.inc | 12 ++++++++++++ .../NamingConventions/PrefixAllGlobalsUnitTest.php | 1 + 4 files changed, 21 insertions(+) diff --git a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php index 887d0408..74191df8 100644 --- a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php +++ b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php @@ -626,6 +626,11 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p return; } + if ( strpos( $raw_content, '\\' ) !== false ) { + // Namespaced or unreachable constant. + return; + } + $data = array( 'Global constants defined' ); $error_code = 'NonPrefixedConstantFound'; } else { diff --git a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.1.inc b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.1.inc index d8562e2e..2c9ca83f 100644 --- a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.1.inc +++ b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.1.inc @@ -13,3 +13,6 @@ const SOME_CONSTANT = 'value'; class Example {} interface I_Example {} trait T_Example {} + +// Issue #1056. +define( __NAMESPACE__ . '\PLUGIN_FILE', __FILE__ ); diff --git a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc index cc258a13..44d8dbff 100644 --- a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc +++ b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc @@ -306,3 +306,15 @@ do_action( 'acronym-action' ); // OK. apply_filters( 'acronym/filter', $var ); // OK. do_action( "acronym-action-{$acronym_filter_var}" ); // OK. apply_filters( 'acronym/filter-' . $acronym_filter_var ); // OK. + +// Issue #1056. +define( 'SomeNameSpace\PLUGIN_FILE', __FILE__ ); // OK. +define( '\OtherNameSpace\PLUGIN_FILE', __FILE__ ); // OK. +// OK: unreachable constants. +define( __NAMESPACE__ . '\PLUGIN_FILE', __FILE__ ); +define( '\PLUGIN_FILE', __FILE__ ); + +namespace Testing { + define( 'MY' . __NAMESPACE__, __FILE__ ); // Error, not actually namespaced. + define( 'MY\\' . __NAMESPACE__, __FILE__ ); // OK, even though strangely setup, the constant is in a namespace. +} diff --git a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php index 10847157..d23bc645 100644 --- a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php +++ b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php @@ -57,6 +57,7 @@ public function getErrorList( $testFile = 'PrefixAllGlobalsUnitTest.inc' ) { 230 => ( function_exists( '\array_column' ) ) ? 0 : 1, 234 => ( defined( '\E_DEPRECATED' ) ) ? 0 : 1, 238 => ( class_exists( '\IntlTimeZone' ) ) ? 0 : 1, + 318 => 1, ); case 'PrefixAllGlobalsUnitTest.1.inc': From b5866034ef8b952aedb3c84901dd2f3a0d0e5374 Mon Sep 17 00:00:00 2001 From: Gary Jones Date: Fri, 4 Aug 2017 10:55:21 +0100 Subject: [PATCH 161/282] Docs: Fix ControlStructreSpacing typos --- WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php b/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php index e923fd38..2c70b77e 100644 --- a/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php +++ b/WordPress/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php @@ -24,7 +24,7 @@ * @since 0.13.0 Class name changed: this class is now namespaced. * * Last synced with base class 2017-01-15 at commit b024ad84656c37ef5733c6998ebc1e60957b2277. - * Note: This class has diverged quite far from the original. All the same, checking occassionally + * Note: This class has diverged quite far from the original. All the same, checking occasionally * to see if there are upstream fixes made from which this sniff can benefit, is warranted. * @link https://github.com/squizlabs/PHP_CodeSniffer/blob/master/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php */ @@ -47,7 +47,7 @@ class ControlStructureSpacingSniff extends Sniff { /** * Require for space before T_COLON when using the alternative syntax for control structures. * - * @var string one of 'required', 'forbidden', optional' + * @var string one of 'required', 'forbidden', 'optional' */ public $space_before_colon = 'required'; From 591290e48c8665b1ec5532842bb0a81fdd121bca Mon Sep 17 00:00:00 2001 From: Jared Atchison Date: Fri, 4 Aug 2017 09:10:57 -0500 Subject: [PATCH 162/282] Update README.md to include Atom setup tips Give readers a heads up that the tab width needs to be explicitly changed in the package settings and that certain config options may present problems. --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 92b076eb..0201cce0 100644 --- a/README.md +++ b/README.md @@ -213,11 +213,14 @@ sublime-phpcs is insanely powerful, but if you'd prefer automatic linting, [Subl - Install [linter-phpcs](https://atom.io/packages/linter-phpcs) via Atom's package manager. - Run `which phpcs` to get your `phpcs` executable path. - Enter your `phpcs` executable path and one of the coding standards specified above (e.g. `WordPress`, `WordPress-VIP`, etc.). +- Change the Tab Width setting to `4`. ![Atom Linter WordPress Coding Standards configuration](https://cloud.githubusercontent.com/assets/224636/12740504/ce4e97b8-c941-11e5-8d83-c77a2470d58e.png) ![Atom Linter in action using WordPress Coding Standards](https://cloud.githubusercontent.com/assets/224636/12740542/131c5894-c942-11e5-9e31-5e020c993224.png) +- Note that certain items within PHPCS config file can cause linting to fail, see [linter-phpcs #95](https://github.com/AtomLinter/linter-phpcs/issues/95#issuecomment-316133107) for more details. + ### Visual Studio Please see "[Setting up PHP CodeSniffer in Visual Studio Code](https://tommcfarlin.com/php-codesniffer-in-visual-studio-code/)", a tutorial by Tom McFarlin. From 1a18cfd3bb31809c9a64eaa7e23ab73786e3e6c9 Mon Sep 17 00:00:00 2001 From: Jared Atchison Date: Fri, 4 Aug 2017 10:27:41 -0500 Subject: [PATCH 163/282] Clarify Atom instructions --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0201cce0..a3da4a62 100644 --- a/README.md +++ b/README.md @@ -212,8 +212,8 @@ sublime-phpcs is insanely powerful, but if you'd prefer automatic linting, [Subl - Install PHP Sniffer and WordPress Coding Standards per above. - Install [linter-phpcs](https://atom.io/packages/linter-phpcs) via Atom's package manager. - Run `which phpcs` to get your `phpcs` executable path. -- Enter your `phpcs` executable path and one of the coding standards specified above (e.g. `WordPress`, `WordPress-VIP`, etc.). -- Change the Tab Width setting to `4`. +- Open the linter-phpcs package settings; enter your `phpcs` executable path and one of the coding standards specified above (e.g. `WordPress`, `WordPress-VIP`, etc.). +- Below these settings find the Tab Width setting and change it to `4`. ![Atom Linter WordPress Coding Standards configuration](https://cloud.githubusercontent.com/assets/224636/12740504/ce4e97b8-c941-11e5-8d83-c77a2470d58e.png) From 80faf1d4d1a7b46f747cb132712a9cb4a5c456a2 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 5 Aug 2017 03:48:06 +0200 Subject: [PATCH 164/282] :sparkles: New `WordPress.WP.DiscouragedConstants` sniff This sniff is based on a sniff previously pulled to the TRT fork of WPCS as `Theme.DeprecatedConstants`. Related issue: WPTRT/WordPress-Coding-Standards/issues/ 23 Original PR: WPTRT/WordPress-Coding-Standards/pull/ 30 Covers the list of constants found in: Otto42/theme-check/pull/ 162 Differences between that sniff and this one: * This sniff is a **_lot_** more comprehensive in preventing false positives. The original sniff was one of the first ones I wrote and it's kind of sweet to look back at that code which I wrote over a year ago and see how much I've learned about writing sniffs in the mean time. * The original sniff was called `Theme.DeprecatedConstants`, but in reality, most of these constants aren't officially deprecated, though their usage is discouraged and the constants being addressed are not 100% related to themes either. With that in mind, I've renamed the sniff to `WP.DiscouragedConstants` and changed the error level from Error to Warning. Also see: https://core.trac.wordpress.org/ticket/18298 * This version of the sniff also addresses the concerns raised in WPTRT/WordPress-Coding-Standards/issues/ 110 about themes `define`-ing any of these constants and leverages the `AbstractFunctionParameterSniff` to do so. Includes quite extensive unit tests. More are definitely welcome, especially to prevent false positives. I've added the sniff to the `WordPress-Extra` ruleset. Based on https://vip.wordpress.com/documentation/code-review-what-we-look-for/#using-theme-constants and https://core.trac.wordpress.org/ticket/18298#comment:2, I've also added the sniff to the `WordPress-VIP` ruleset. /cc @sboisvert @david-binda @ntwb Fixes 97 Will also fix WPTRT/WordPress-Coding-Standards/issues/ 110 once the original sniff gets removed from the TRT fork and this sniff is added to the TRT ruleset instead. --- WordPress-Extra/ruleset.xml | 1 + WordPress-VIP/ruleset.xml | 4 + .../Sniffs/WP/DiscouragedConstantsSniff.php | 214 ++++++++++++++++++ .../Tests/WP/DiscouragedConstantsUnitTest.inc | 73 ++++++ .../Tests/WP/DiscouragedConstantsUnitTest.php | 58 +++++ 5 files changed, 350 insertions(+) create mode 100644 WordPress/Sniffs/WP/DiscouragedConstantsSniff.php create mode 100644 WordPress/Tests/WP/DiscouragedConstantsUnitTest.inc create mode 100644 WordPress/Tests/WP/DiscouragedConstantsUnitTest.php diff --git a/WordPress-Extra/ruleset.xml b/WordPress-Extra/ruleset.xml index 370dc23a..6260d4fa 100644 --- a/WordPress-Extra/ruleset.xml +++ b/WordPress-Extra/ruleset.xml @@ -68,6 +68,7 @@ + diff --git a/WordPress-VIP/ruleset.xml b/WordPress-VIP/ruleset.xml index 23c386b6..33b75e58 100644 --- a/WordPress-VIP/ruleset.xml +++ b/WordPress-VIP/ruleset.xml @@ -88,4 +88,8 @@ %s() is highly discouraged, please use vip_safe_wp_remote_get() instead. + + + +
      diff --git a/WordPress/Sniffs/WP/DiscouragedConstantsSniff.php b/WordPress/Sniffs/WP/DiscouragedConstantsSniff.php new file mode 100644 index 00000000..c56aed06 --- /dev/null +++ b/WordPress/Sniffs/WP/DiscouragedConstantsSniff.php @@ -0,0 +1,214 @@ + 'get_stylesheet_directory()', + 'TEMPLATEPATH' => 'get_template_directory()', + 'PLUGINDIR' => 'WP_PLUGIN_DIR', + 'MUPLUGINDIR' => 'WPMU_PLUGIN_DIR', + 'HEADER_IMAGE' => 'add_theme_support( \'custom-header\' )', + 'NO_HEADER_TEXT' => 'add_theme_support( \'custom-header\' )', + 'HEADER_TEXTCOLOR' => 'add_theme_support( \'custom-header\' )', + 'HEADER_IMAGE_WIDTH' => 'add_theme_support( \'custom-header\' )', + 'HEADER_IMAGE_HEIGHT' => 'add_theme_support( \'custom-header\' )', + 'BACKGROUND_COLOR' => 'add_theme_support( \'custom-background\' )', + 'BACKGROUND_IMAGE' => 'add_theme_support( \'custom-background\' )', + ); + + /** + * Array of functions to check. + * + * @since 0.14.0 + * + * @var array => + */ + protected $target_functions = array( + 'define' => 1, + ); + + /** + * Array of tokens which if found preceding the $stackPtr indicate that a T_STRING is not a constant. + * + * @var array + */ + private $preceding_tokens_to_ignore = array( + T_NAMESPACE => true, + T_USE => true, + T_CLASS => true, + T_TRAIT => true, + T_INTERFACE => true, + T_EXTENDS => true, + T_IMPLEMENTS => true, + T_NEW => true, + T_FUNCTION => true, + T_CONST => true, + T_DOUBLE_COLON => true, + T_OBJECT_OPERATOR => true, + T_INSTANCEOF => true, + T_GOTO => true, + + ); + + /** + * Processes this test, when one of its tokens is encountered. + * + * @since 0.14.0 + * + * @param int $stackPtr The position of the current token in the stack. + * + * @return int|void Integer stack pointer to skip forward or void to continue + * normal file processing. + */ + public function process_token( $stackPtr ) { + if ( isset( $this->target_functions[ strtolower( $this->tokens[ $stackPtr ]['content'] ) ] ) ) { + // Disallow excluding function groups for this sniff. + $this->exclude = ''; + + return parent::process_token( $stackPtr ); + + } else { + return $this->process_arbitrary_tstring( $stackPtr ); + } + } + + /** + * Process an arbitrary T_STRING token to determine whether it is one of the target constants. + * + * @since 0.14.0 + * + * @param int $stackPtr The position of the current token in the stack. + * + * @return void + */ + public function process_arbitrary_tstring( $stackPtr ) { + $content = $this->tokens[ $stackPtr ]['content']; + + if ( ! isset( $this->discouraged_constants[ $content ] ) ) { + return; + } + + $next = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true ); + if ( false !== $next && T_OPEN_PARENTHESIS === $this->tokens[ $next ]['code'] ) { + // Function call or declaration. + return; + } + + $prev = $this->phpcsFile->findPrevious( Tokens::$emptyTokens, ( $stackPtr - 1 ), null, true ); + if ( false !== $prev && isset( $this->preceding_tokens_to_ignore[ $this->tokens[ $prev ]['code'] ] ) ) { + // Not the use of a constant. + return; + } + + if ( false !== $prev + && T_NS_SEPARATOR === $this->tokens[ $prev ]['code'] + && T_STRING === $this->tokens[ ( $prev - 1 ) ]['code'] + ) { + // Namespaced constant of the same name. + return; + } + + /* + * Deal with a number of variations of use statements. + */ + for ( $i = $stackPtr; $i > 0; $i-- ) { + if ( $this->tokens[ $i ]['line'] !== $this->tokens[ $stackPtr ]['line'] ) { + break; + } + } + + $first_on_line = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $i + 1 ), null, true ); + if ( false !== $first_on_line && T_USE === $this->tokens[ $first_on_line ]['code'] ) { + $next_on_line = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $first_on_line + 1 ), null, true ); + if ( false !== $next_on_line ) { + if ( ( T_STRING === $this->tokens[ $next_on_line ]['code'] + && 'const' === $this->tokens[ $next_on_line ]['content'] ) + || T_CONST === $this->tokens[ $next_on_line ]['code'] // Happens in some PHPCS versions. + ) { + $has_ns_sep = $this->phpcsFile->findNext( T_NS_SEPARATOR, ( $next_on_line + 1 ), $stackPtr ); + if ( false !== $has_ns_sep ) { + // Namespaced const (group) use statement. + return; + } + } else { + // Not a const use statement. + return; + } + } + } + + // Ok, this is really one of the discouraged constants. + $this->phpcsFile->addWarning( + 'Found usage of constant "%s". Use %s instead.', + $stackPtr, + 'UsageFound', + array( + $content, + $this->discouraged_constants[ $content ], + ) + ); + } + + /** + * Process the parameters of a matched `define` function call. + * + * @since 0.14.0 + * + * @param int $stackPtr The position of the current token in the stack. + * @param array $group_name The name of the group which was matched. + * @param string $matched_content The token content (function name) which was matched. + * @param array $parameters Array with information about the parameters. + * + * @return void + */ + public function process_parameters( $stackPtr, $group_name, $matched_content, $parameters ) { + $function_name = strtolower( $matched_content ); + $target_param = $this->target_functions[ $function_name ]; + + // Was the target parameter passed ? + if ( ! isset( $parameters[ $target_param ] ) ) { + return; + } + + $raw_content = $this->strip_quotes( $parameters[ $target_param ]['raw'] ); + + if ( isset( $this->discouraged_constants[ $raw_content ] ) ) { + $this->phpcsFile->addWarning( + 'Found declaration of constant "%s". Use %s instead.', + $stackPtr, + 'DeclarationFound', + array( + $raw_content, + $this->discouraged_constants[ $raw_content ], + ) + ); + } + } + +} // End class. diff --git a/WordPress/Tests/WP/DiscouragedConstantsUnitTest.inc b/WordPress/Tests/WP/DiscouragedConstantsUnitTest.inc new file mode 100644 index 00000000..0f691063 --- /dev/null +++ b/WordPress/Tests/WP/DiscouragedConstantsUnitTest.inc @@ -0,0 +1,73 @@ +STYLESHEETPATH; +use const SomeNamespace\STYLESHEETPATH as SSP; // PHP 5.6+ +use const SomeNamespace\{STYLESHEETPATH, TEMPLATEPATH}; // PHP 7.0+ +define( 'My\STYLESHEETPATH', 'something' ); + +// Ok, not usage of the constant as such. +if ( defined( 'STYLESHEETPATH' ) ) { // Ok. + // Do something unrelated. +} + + +/* + * These are all bad. + */ +echo STYLESHEETPATH; +echo \STYLESHEETPATH; // Global constant. +$folder = basename( TEMPLATEPATH ); +include PLUGINDIR . '/js/myfile.js'; +echo MUPLUGINDIR; +echo HEADER_IMAGE; +echo NO_HEADER_TEXT; +echo HEADER_TEXTCOLOR; +echo HEADER_IMAGE_WIDTH; +echo HEADER_IMAGE_HEIGHT; +echo BACKGROUND_COLOR; +echo BACKGROUND_IMAGE; + +use const STYLESHEETPATH as SSP; +use const ABC as STYLESHEETPATH; + +switch( STYLESHEETPATH ) { + case STYLESHEETPATH: + break; +} + +define( 'STYLESHEETPATH', 'something' ); diff --git a/WordPress/Tests/WP/DiscouragedConstantsUnitTest.php b/WordPress/Tests/WP/DiscouragedConstantsUnitTest.php new file mode 100644 index 00000000..94604a71 --- /dev/null +++ b/WordPress/Tests/WP/DiscouragedConstantsUnitTest.php @@ -0,0 +1,58 @@ + => + */ + public function getErrorList() { + return array(); + } + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array( + 52 => 1, + 53 => 1, + 54 => 1, + 55 => 1, + 56 => 1, + 57 => 1, + 58 => 1, + 59 => 1, + 60 => 1, + 61 => 1, + 62 => 1, + 63 => 1, + 65 => 1, + 66 => 1, + 68 => 1, + 69 => 1, + 73 => 1, + ); + } + +} // End class. From cc8e2e970bd2920d3e96abbdaf8c2e01583111f0 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 5 Aug 2017 14:17:59 +0200 Subject: [PATCH 165/282] WP.DiscouragedConstants: Trigger for `const` defined in the global namespace Distinguished between `const` defines in the global namespace and class constants. To this end, two more utility functions I previously write for PHPCompatibility have been ported over. --- WordPress/Sniff.php | 58 +++++++++++++++++++ .../Sniffs/WP/DiscouragedConstantsSniff.php | 9 ++- .../Tests/WP/DiscouragedConstantsUnitTest.inc | 5 +- .../Tests/WP/DiscouragedConstantsUnitTest.php | 11 ++-- 4 files changed, 74 insertions(+), 9 deletions(-) diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index 70f763ac..a397ec60 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -2220,4 +2220,62 @@ public function has_html_open_tag( $tag_name, $stackPtr = null, $content = false return false; } + /** + * Check whether a T_CONST token is a class constant declaration. + * + * @since 0.14.0 + * + * @param int $stackPtr The position in the stack of the T_CONST token to verify. + * + * @return bool + */ + public function is_class_constant( $stackPtr ) { + if ( ! isset( $this->tokens[ $stackPtr ] ) || T_CONST !== $this->tokens[ $stackPtr ]['code'] ) { + return false; + } + + // Note: traits can not declare constants. + $valid_scopes = array( + 'T_CLASS' => true, + 'T_ANON_CLASS' => true, + 'T_INTERFACE' => true, + ); + + return $this->valid_direct_scope( $stackPtr, $valid_scopes ); + } + + /** + * Check whether the direct wrapping scope of a token is within a limited set of + * acceptable tokens. + * + * Used to check, for instance, if a T_CONST is a class constant. + * + * @since 0.14.0 + * + * @param int $stackPtr The position in the stack of the token to verify. + * @param array $valid_scopes Array of token types. + * Keys should be the token types in string format + * to allow for newer token types. + * Value is irrelevant. + * + * @return bool + */ + protected function valid_direct_scope( $stackPtr, array $valid_scopes ) { + if ( empty( $this->tokens[ $stackPtr ]['conditions'] ) ) { + return false; + } + + /* + * Check only the direct wrapping scope of the token. + */ + $conditions = array_keys( $this->tokens[ $stackPtr ]['conditions'] ); + $ptr = array_pop( $conditions ); + + if ( ! isset( $this->tokens[ $ptr ] ) ) { + return false; + } + + return isset( $valid_scopes[ $this->tokens[ $ptr ]['type'] ] ); + } + } diff --git a/WordPress/Sniffs/WP/DiscouragedConstantsSniff.php b/WordPress/Sniffs/WP/DiscouragedConstantsSniff.php index c56aed06..7e47b042 100644 --- a/WordPress/Sniffs/WP/DiscouragedConstantsSniff.php +++ b/WordPress/Sniffs/WP/DiscouragedConstantsSniff.php @@ -68,7 +68,6 @@ class DiscouragedConstantsSniff extends AbstractFunctionParameterSniff { T_IMPLEMENTS => true, T_NEW => true, T_FUNCTION => true, - T_CONST => true, T_DOUBLE_COLON => true, T_OBJECT_OPERATOR => true, T_INSTANCEOF => true, @@ -134,6 +133,14 @@ public function process_arbitrary_tstring( $stackPtr ) { return; } + if ( false !== $prev + && T_CONST === $this->tokens[ $prev ]['code'] + && true === $this->is_class_constant( $prev ) + ) { + // Class constant of the same name. + return; + } + /* * Deal with a number of variations of use statements. */ diff --git a/WordPress/Tests/WP/DiscouragedConstantsUnitTest.inc b/WordPress/Tests/WP/DiscouragedConstantsUnitTest.inc index 0f691063..687705e7 100644 --- a/WordPress/Tests/WP/DiscouragedConstantsUnitTest.inc +++ b/WordPress/Tests/WP/DiscouragedConstantsUnitTest.inc @@ -5,7 +5,7 @@ * * The below are all ok. */ -// Ok, not a constant. +// Ok, not a (global) constant. namespace STYLESHEETPATH {} namespace MY\OTHER\STYLESHEETPATH\NAMESPACE {} use STYLESHEETPATH; @@ -18,7 +18,6 @@ class ABC extends STYLESHEETPATH {} class DEF implements STYLESHEETPATH {} interface STYLESHEETPATH {} trait STYLESHEETPATH {} -const STYLESHEETPATH = 'something'; $a = new STYLESHEETPATH; $a = new STYLESHEETPATH(); function STYLESHEETPATH() {} @@ -32,7 +31,6 @@ goto STYLESHEETPATH; STYLESHEETPATH: // Something. -// Ok, not a global constant. echo \mynamespace\STYLESHEETPATH; echo My_Class::STYLESHEETPATH; echo $this->STYLESHEETPATH; @@ -71,3 +69,4 @@ switch( STYLESHEETPATH ) { } define( 'STYLESHEETPATH', 'something' ); +const STYLESHEETPATH = 'something'; diff --git a/WordPress/Tests/WP/DiscouragedConstantsUnitTest.php b/WordPress/Tests/WP/DiscouragedConstantsUnitTest.php index 94604a71..3e60ba4b 100644 --- a/WordPress/Tests/WP/DiscouragedConstantsUnitTest.php +++ b/WordPress/Tests/WP/DiscouragedConstantsUnitTest.php @@ -35,6 +35,8 @@ public function getErrorList() { */ public function getWarningList() { return array( + 50 => 1, + 51 => 1, 52 => 1, 53 => 1, 54 => 1, @@ -45,13 +47,12 @@ public function getWarningList() { 59 => 1, 60 => 1, 61 => 1, - 62 => 1, 63 => 1, - 65 => 1, + 64 => 1, 66 => 1, - 68 => 1, - 69 => 1, - 73 => 1, + 67 => 1, + 71 => 1, + 72 => 1, ); } From 3b00b81989127aae6ad55d10bb892e56c0f0a0bc Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 5 Aug 2017 15:43:26 +0200 Subject: [PATCH 166/282] Hotfix: temporary plaster to fix issue 1087 The underlying issue has been reported upstream squizlabs/PHP_CodeSniffer/issues/ 1591 and should be fixed there. In the mean time, this will fix it for the time being. IMHO this should be released as WPCS 0.13.1 to make this hotfix available as soon as possible. --- .github/CONTRIBUTING.md | 4 ++++ CHANGELOG.md | 6 ++++++ Test/phpcs3-bootstrap.php | 26 -------------------------- WordPress/PHPCSAliases.php | 28 ++++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 26 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 66e89a3a..06922ce1 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -100,6 +100,10 @@ The easiest way to do this is to add a `phpunit.xml` file to the root of your WP The WordPress Coding Standards are compatible with both PHPCS 2.x as well as 3.x. This has some implications for running the unit tests. +* Make sure you have registered the directory in which you installed WPCS with PHPCS using; + ```sh + phpcs --config-set installed_path path/to/WPCS + ``` * Navigate to the directory in which you installed WPCS. * To run the unit tests with PHPCS 3.x: ```sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 81b6d466..6a8ed845 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ This projects adheres to [Semantic Versioning](http://semver.org/) and [Keep a C _Nothing yet._ +## [0.13.1] - 2017-08-07 + +### Fixed +- Fatal error when using PHPCS 3.x with the `installed_paths` config variable set via the ruleset. + ## [0.13.0] - 2017-08-03 ### Added @@ -458,6 +463,7 @@ See the comparison for full list. Initial tagged release. [Unreleased]: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/compare/master...HEAD +[0.13.1]: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/compare/0.13.0...0.13.1 [0.13.0]: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/compare/0.12.0...0.13.0 [0.12.0]: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/compare/0.11.0...0.12.0 [0.11.0]: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/compare/0.10.0...0.11.0 diff --git a/Test/phpcs3-bootstrap.php b/Test/phpcs3-bootstrap.php index 0932e2c0..8d12fce1 100644 --- a/Test/phpcs3-bootstrap.php +++ b/Test/phpcs3-bootstrap.php @@ -51,29 +51,3 @@ // Load our class aliases. include_once dirname( __DIR__ ) . $ds . 'WordPress' . $ds . 'PHPCSAliases.php'; unset( $ds, $phpcsDir ); - -/* - * Register our own autoloader for the WPCS abstract classes & the helper class. - * - * This can be removed once the minimum required version of WPCS for the - * PHPCS 3.x branch has gone up to 3.1.0 (unreleased as of yet). - * - * @link https://github.com/squizlabs/PHP_CodeSniffer/issues/1564 - */ -spl_autoload_register( function ( $class ) { - // Only try & load our own classes. - if ( stripos( $class, 'WordPress' ) !== 0 ) { - return; - } - - // PHPCS handles the Test and Sniff classes without problem. - if ( stripos( $class, '\Tests\\' ) !== false || stripos( $class, '\Sniffs\\' ) !== false ) { - return; - } - - $file = dirname( __DIR__ ) . DIRECTORY_SEPARATOR . strtr( $class, '\\', DIRECTORY_SEPARATOR ) . '.php'; - - if ( file_exists( $file ) ) { - include_once $file; - } -} ); diff --git a/WordPress/PHPCSAliases.php b/WordPress/PHPCSAliases.php index 9a4fdaf2..b7223b60 100644 --- a/WordPress/PHPCSAliases.php +++ b/WordPress/PHPCSAliases.php @@ -47,4 +47,32 @@ class_alias( 'PHP_CodeSniffer\Standards\Squiz\Sniffs\WhiteSpace\OperatorSpacingS } define( 'WPCS_PHPCS_ALIASES_SET', true ); + + /* + * Register our own autoloader for the WPCS abstract classes & the helper class. + * + * This can be removed once the minimum required version of WPCS for the + * PHPCS 3.x branch has gone up to 3.1.0 (unreleased as of yet) or + * whichever version contains the fix for upstream #1591. + * + * @link https://github.com/squizlabs/PHP_CodeSniffer/issues/1564 + * @link https://github.com/squizlabs/PHP_CodeSniffer/issues/1591 + */ + spl_autoload_register( function ( $class ) { + // Only try & load our own classes. + if ( stripos( $class, 'WordPress' ) !== 0 ) { + return; + } + + // PHPCS handles the Test and Sniff classes without problem. + if ( stripos( $class, '\Tests\\' ) !== false || stripos( $class, '\Sniffs\\' ) !== false ) { + return; + } + + $file = dirname( __DIR__ ) . DIRECTORY_SEPARATOR . strtr( $class, '\\', DIRECTORY_SEPARATOR ) . '.php'; + + if ( file_exists( $file ) ) { + include_once $file; + } + } ); } From 1686dd276725718f30c8512be3642b35233e9f0c Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 5 Aug 2017 14:48:38 +0200 Subject: [PATCH 167/282] Add `is_class_property()` utility method and implement use of this and the other two new utility methods. PR 1089 introduced two new utility methods to the `WordPress\Sniff` class: `is_class_constant()` and `valid_direct_scope()`. This PR introduces one additional utility method `is_class_property()` and implements the use of this and the other two methods in other places in the code where appropriate (other than where they were originally introduced for). --- WordPress/Sniff.php | 36 ++++++++++++++++++- .../PrefixAllGlobalsSniff.php | 8 ++--- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index a397ec60..f776a8f5 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -1777,7 +1777,12 @@ protected function get_use_type( $stackPtr ) { } // USE keywords for traits. - if ( $this->phpcsFile->hasCondition( $stackPtr, array( T_CLASS, T_ANON_CLASS, T_TRAIT ) ) ) { + $valid_scopes = array( + 'T_CLASS' => true, + 'T_ANON_CLASS' => true, + 'T_TRAIT' => true, + ); + if ( true === $this->valid_direct_scope( $stackPtr, $valid_scopes ) ) { return 'trait'; } @@ -2244,6 +2249,35 @@ public function is_class_constant( $stackPtr ) { return $this->valid_direct_scope( $stackPtr, $valid_scopes ); } + /** + * Check whether a T_VARIABLE token is a class property declaration. + * + * @param int $stackPtr The position in the stack of the T_VARIABLE token to verify. + * + * @return bool + */ + public function is_class_property( $stackPtr ) { + if ( ! isset( $this->tokens[ $stackPtr ] ) || T_VARIABLE !== $this->tokens[ $stackPtr ]['code'] ) { + return false; + } + + // Note: interfaces can not declare properties. + $valid_scopes = array( + 'T_CLASS' => true, + 'T_ANON_CLASS' => true, + 'T_TRAIT' => true, + ); + + if ( $this->valid_direct_scope( $stackPtr, $valid_scopes ) ) { + // Make sure it's not a method parameter. + if ( empty( $this->tokens[ $stackPtr ]['nested_parenthesis'] ) ) { + return true; + } + } + + return false; + } + /** * Check whether the direct wrapping scope of a token is within a limited set of * acceptable tokens. diff --git a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php index 74191df8..cce8305c 100644 --- a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php +++ b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php @@ -270,7 +270,7 @@ public function process_token( $stackPtr ) { case 'T_CONST': // Constants in a class do not need to be prefixed. - if ( $this->phpcsFile->hasCondition( $stackPtr, array( T_CLASS, T_ANON_CLASS, T_INTERFACE, T_TRAIT ) ) === true ) { + if ( true === $this->is_class_constant( $stackPtr ) ) { return; } @@ -488,11 +488,7 @@ protected function process_variable_assignment( $stackPtr ) { } // Properties in a class do not need to be prefixed. - $conditions = array_keys( $this->tokens[ $stackPtr ]['conditions'] ); - $ptr = array_pop( $conditions ); - if ( isset( $this->tokens[ $ptr ] ) - && in_array( $this->tokens[ $ptr ]['code'], array( T_CLASS, T_ANON_CLASS, T_TRAIT ), true ) - ) { + if ( true === $this->is_class_property( $stackPtr ) ) { return; } From b54c1795c70825977700f075c8a6d0ee2a17bf4b Mon Sep 17 00:00:00 2001 From: jrfnl Date: Mon, 7 Aug 2017 03:09:15 +0200 Subject: [PATCH 168/282] :sparkles: Add new `CodeAnalysis.AssignmentInCondition` sniff to `Extra` Most of the time variable assignments being made in conditions are unintentional and are in actual fact typos which were intended as a comparison. In those cases when it isn't a typo, this is a typical code smell which is a prime candidate for refactoring. This sniff will warn when any such a variable assignment is found in a condition. Note: the sniff does currently **not** detect variable assignments in the conditional part of ternaries. Includes extensive unit tests. Inspired by [this twitter thread](https://twitter.com/jrf_nl/status/893891839903838209), or rather: the responses I received to my tweet. Note: the fact that WP uses Yoda conditions does **not** invalidate the need for this sniff. The Yoda conditions sniff only checks comparison operators, not assignment operators. I've run this sniff over WP Core to: a) test the sniff and b) see what it would turn up And found 1004 cases in 847 files and visual verification of a sample of theses results showed no false positives. AFAICS the cases found are intentional assignments within conditions, however, as said above, that is an indicator that the code in question is due for some refactoring as this is definitely a code smell. This sniff is a duplicate of the same which I've pulled upstream: squizlabs/PHP_CodeSniffer/pull/ 1594 The upstream sniff has been merged and is due to be included in PHPCS 3.1.0. Once the minimum PHPCS requirement for WPCS has gone up beyond that version (i.e. after PHPCS 2.x support has been dropped), we can safely remove the WPCS version of the sniff. --- WordPress-Extra/ruleset.xml | 4 + .../AssignmentInConditionSniff.php | 184 ++++++++++++++++++ .../AssignmentInConditionUnitTest.inc | 94 +++++++++ .../AssignmentInConditionUnitTest.php | 77 ++++++++ 4 files changed, 359 insertions(+) create mode 100644 WordPress/Sniffs/CodeAnalysis/AssignmentInConditionSniff.php create mode 100644 WordPress/Tests/CodeAnalysis/AssignmentInConditionUnitTest.inc create mode 100644 WordPress/Tests/CodeAnalysis/AssignmentInConditionUnitTest.php diff --git a/WordPress-Extra/ruleset.xml b/WordPress-Extra/ruleset.xml index 6260d4fa..3b6c5c39 100644 --- a/WordPress-Extra/ruleset.xml +++ b/WordPress-Extra/ruleset.xml @@ -24,6 +24,10 @@
      + + + diff --git a/WordPress/Sniffs/CodeAnalysis/AssignmentInConditionSniff.php b/WordPress/Sniffs/CodeAnalysis/AssignmentInConditionSniff.php new file mode 100644 index 00000000..7dd5210a --- /dev/null +++ b/WordPress/Sniffs/CodeAnalysis/AssignmentInConditionSniff.php @@ -0,0 +1,184 @@ +assignment_tokens = Tokens::$assignmentTokens; + unset( $this->assignment_tokens[ T_DOUBLE_ARROW ] ); + + $starters = Tokens::$booleanOperators; + $starters[ T_SEMICOLON ] = T_SEMICOLON; + $starters[ T_OPEN_PARENTHESIS ] = T_OPEN_PARENTHESIS; + + $this->condition_start_tokens = $starters; + + return array( + T_IF, + T_ELSEIF, + T_FOR, + T_SWITCH, + T_CASE, + T_WHILE, + ); + + }//end register() + + /** + * Processes this test, when one of its tokens is encountered. + * + * @since 0.14.0 + * + * @param int $stackPtr The position of the current token in the stack. + * + * @return void + */ + public function process_token( $stackPtr ) { + + $token = $this->tokens[ $stackPtr ]; + + // Find the condition opener/closer. + if ( T_FOR === $token['code'] ) { + if ( isset( $token['parenthesis_opener'], $token['parenthesis_closer'] ) === false ) { + return; + } + + $semicolon = $this->phpcsFile->findNext( T_SEMICOLON, ( $token['parenthesis_opener'] + 1 ), $token['parenthesis_closer'] ); + if ( false === $semicolon ) { + return; + } + + $opener = $semicolon; + $semicolon = $this->phpcsFile->findNext( T_SEMICOLON, ( $opener + 1 ), $token['parenthesis_closer'] ); + if ( false === $semicolon ) { + return; + } + + $closer = $semicolon; + unset( $semicolon ); + + } elseif ( T_CASE === $token['code'] ) { + if ( isset( $token['scope_opener'] ) === false ) { + return; + } + + $opener = $stackPtr; + $closer = $token['scope_opener']; + + } else { + if ( isset( $token['parenthesis_opener'], $token['parenthesis_closer'] ) === false ) { + return; + } + + $opener = $token['parenthesis_opener']; + $closer = $token['parenthesis_closer']; + } + + $startPos = $opener; + + do { + $hasAssignment = $this->phpcsFile->findNext( $this->assignment_tokens, ( $startPos + 1 ), $closer ); + if ( false === $hasAssignment ) { + return; + } + + // Examine whether the left side is a variable. + $hasVariable = false; + $conditionStart = $startPos; + $altConditionStart = $this->phpcsFile->findPrevious( + $this->condition_start_tokens, + ( $hasAssignment - 1 ), + $startPos + ); + if ( false !== $altConditionStart ) { + $conditionStart = $altConditionStart; + } + + for ( $i = $hasAssignment; $i > $conditionStart; $i-- ) { + if ( isset( Tokens::$emptyTokens[ $this->tokens[ $i ]['code'] ] ) ) { + continue; + } + + // If this is a variable or array, we've seen all we need to see. + if ( T_VARIABLE === $this->tokens[ $i ]['code'] + || T_CLOSE_SQUARE_BRACKET === $this->tokens[ $i ]['code'] + ) { + $hasVariable = true; + break; + } + + // If this is a function call or something, we are OK. + if ( T_CLOSE_PARENTHESIS === $this->tokens[ $i ]['code'] ) { + break; + } + } + + if ( true === $hasVariable ) { + $this->phpcsFile->addWarning( + 'Variable assignment found within a condition. Did you mean to do a comparison ?', + $hasAssignment, + 'Found' + ); + } + + $startPos = $hasAssignment; + + } while ( $startPos < $closer ); + + } + +} // End class. diff --git a/WordPress/Tests/CodeAnalysis/AssignmentInConditionUnitTest.inc b/WordPress/Tests/CodeAnalysis/AssignmentInConditionUnitTest.inc new file mode 100644 index 00000000..b530b308 --- /dev/null +++ b/WordPress/Tests/CodeAnalysis/AssignmentInConditionUnitTest.inc @@ -0,0 +1,94 @@ + 'a', 2 => 'b' ) ) ) {} + +switch ( $a === $b ) {} +switch ( true ) { + case $sample == 'something': + break; +} + +for ( $i = 0; $i == 100; $i++ ) {} +for ( $i = 0; $i >= 100; $i++ ) {} +for ( $i = 0; ; $i++ ) {} +for (;;) {} + +do { +} while ( $sample == false ); + +while ( $sample === false ) {} +while (list($field_name, $file_names) = each($formfiles)) {} + + // Silly, but not an assignment. +if (123 = $a) {} +if (strtolower($b) = $b) {} +if (array( 1 => 'a', 2 => 'b' ) = $b) {} + +if (SOME_CONSTANT = 123) { +} else if(self::SOME_CONSTANT -= 10) {} + +if ( $a() = 123 ) { +} else if ( $b->something() = 123 ) { +} elseif ( $c::something() = 123 ) {} + +switch ( true ) { + case 'something' = $sample: + break; +} + +// Assignments in condition. +if ($a = 123) { +} elseif ($a = 'abc') { +} else if( $a += 10 ) { +} else if($a -= 10) { +} else if($a *= 10) { +} else if($a **= 10) { +} else if($a /= 10) { +} else if($a .= strtolower($b)) { +} else if($a %= SOME_CONSTANT) { +} else if($a &= 2) { +} else if($a |= 2) { +} else if($a ^= 2) { +} else if($a <<= 2) { +} else if($a >>= 2) { +} else if($a ??= $b) { +} elseif( $a = 'abc' && $b = 'def' ) { +} elseif( + $a = 'abc' + && $a .= 'def' +) {} + +if ($a[] = 123) { +} elseif ($a['something'] = 123) { +} elseif (self::$a = 123) { +} elseif (parent::$a *= 123) { +} elseif (static::$a = 123) { +} elseif (MyClass::$a .= 'abc') { +} else if( $this->something += 10 ) {} + +switch ( $a = $b ) {} +switch ( true ) { + case $sample = 'something': + break; + + case $sample = 'something' && $a = $b: + break; +} + +for ( $i = 0; $i = 100; $i++ ) {} +for ( $i = 0; $i = 100 && $b = false; $i++ ) {} + +do { +} while ( $sample = false ); + +while ( $sample = false ) {} + +if ($a = 123) : +endif; diff --git a/WordPress/Tests/CodeAnalysis/AssignmentInConditionUnitTest.php b/WordPress/Tests/CodeAnalysis/AssignmentInConditionUnitTest.php new file mode 100644 index 00000000..5bac100b --- /dev/null +++ b/WordPress/Tests/CodeAnalysis/AssignmentInConditionUnitTest.php @@ -0,0 +1,77 @@ + => + */ + public function getErrorList() { + return array(); + + } + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array( + 47 => 1, + 48 => 1, + 49 => 1, + 50 => 1, + 51 => 1, + 52 => 1, + 53 => 1, + 54 => 1, + 55 => 1, + 56 => 1, + 57 => 1, + 58 => 1, + 59 => 1, + 60 => 1, + 61 => 1, + 62 => 2, + 64 => 1, + 65 => 1, + 68 => 1, + 69 => 1, + 70 => 1, + 71 => 1, + 72 => 1, + 73 => 1, + 74 => 1, + 76 => 1, + 78 => 1, + 81 => 2, + 85 => 1, + 86 => 2, + 89 => 1, + 91 => 1, + 93 => 1, + ); + + } + +} // End class. From abfbd826622901a70ffd0319a38f3cd7425491cb Mon Sep 17 00:00:00 2001 From: jrfnl Date: Mon, 7 Aug 2017 03:44:47 +0200 Subject: [PATCH 169/282] Refactor one assignment in condition in current codebase. Still one more to do. --- WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php b/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php index c5d1e7c3..d3b095dc 100644 --- a/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php +++ b/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php @@ -152,8 +152,12 @@ public function process_token( $stackPtr ) { } // Check for Database Schema Changes. - $_pos = $stackPtr; - while ( $_pos = $this->phpcsFile->findNext( Tokens::$textStringTokens, ( $_pos + 1 ), $endOfStatement, false, null, true ) ) { + for ( $_pos = ( $stackPtr + 1 ); $_pos < $endOfStatement; $_pos++ ) { + $_pos = $this->phpcsFile->findNext( Tokens::$textStringTokens, $_pos, $endOfStatement, false, null, true ); + if ( false === $_pos ) { + break; + } + if ( preg_match( '#\b(?:ALTER|CREATE|DROP)\b#i', $this->tokens[ $_pos ]['content'] ) > 0 ) { $this->phpcsFile->addError( 'Attempting a database schema change is highly discouraged.', $_pos, 'SchemaChange' ); } From 80442d21264a9e540cd36d19992694c973b2a554 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Mon, 7 Aug 2017 08:34:38 +0200 Subject: [PATCH 170/282] Allow for setting the minimum supported WP version from the command line This change allows for setting the `minimum_supported_version` property for all three `WP.Deprecated...` sniffs in one go, either via the command-line or by setting a config variable in a custom ruleset. As this config variable is no longer directly related to a sniff, I've chosen to make the name slightly more specific/descriptive: `minimum_supported_wp_version` <= note the `_wp_`. Usage: ```bash phpcs . --standard=WordPress --runtime-set minimum_supported_wp_version 4.5 ``` or in a ruleset: ```xml ``` The above one liner can replace the custom property which would otherwise need to be set for all three sniffs individually. Overrule order: 1. Value passed via the command line 2. `` property in the ruleset 3. Individual sniff ``'s set via the ruleset 4. Default value Simplest way to test this is by running PHPCS over the `WP.DeprecatedParameters` sniff unit tests: ```bash phpcs -p -s ./WordPress/Tests/DeprecatedParametersUnitTest.inc --standard=WordPress --sniffs=WordPress.WP.DeprecatedParameters phpcs -p -s ./WordPress/Tests/DeprecatedParametersUnitTest.inc --standard=WordPress --sniffs=WordPress.WP.DeprecatedParameters --runtime-set minimum_supported_wp_version 4.8 phpcs -p -s ./WordPress/Tests/DeprecatedParametersUnitTest.inc --standard=WordPress --sniffs=WordPress.WP.DeprecatedParameters --runtime-set minimum_supported_wp_version 3.8 ``` Additional notes: * I've moved the `$custom_test_class_whitelist` property up in the `WordPress\Sniff` class, so both `public` properties are now at the top of the file. --- WordPress/Sniff.php | 100 ++++++++++++++---- .../Sniffs/WP/DeprecatedClassesSniff.php | 36 +++---- .../Sniffs/WP/DeprecatedFunctionsSniff.php | 36 +++---- .../Sniffs/WP/DeprecatedParametersSniff.php | 27 ++--- 4 files changed, 114 insertions(+), 85 deletions(-) diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index f776a8f5..de5f2369 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -12,6 +12,7 @@ use PHP_CodeSniffer_Sniff as PHPCS_Sniff; use PHP_CodeSniffer_File as File; use PHP_CodeSniffer_Tokens as Tokens; +use WordPress\PHPCSHelper; /** * Represents a PHP_CodeSniffer sniff for sniffing WordPress coding standards. @@ -34,6 +35,64 @@ */ abstract class Sniff implements PHPCS_Sniff { + /** + * Minimum supported WordPress version. + * + * Currently used by the `WordPress.WP.DeprecatedClasses`, + * `WordPress.WP.DeprecatedFunctions` and the `WordPress.WP.DeprecatedParameter` sniff. + * + * These sniffs will throw an error when usage of a deprecated class/function/parameter + * is detected if the class/function/parameter was deprecated before the minimum + * supported WP version; a warning otherwise. + * By default, it is set to presume that a project will support the current + * WP version and up to three releases before. + * + * This property allows changing the minimum supported WP version used by + * these sniffs by setting a property in a custom phpcs.xml ruleset. + * This property will need to be set for each sniff which uses it. + * + * Example usage: + * + * + * + * + * + * + * Alternatively, the value can be passed in one go for all sniff using it via + * the command line or by setting a `` value in a custom phpcs.xml ruleset. + * Note: the `_wp_` in the command line property name! + * + * CL: `phpcs --runtime-set minimum_supported_wp_version 4.5` + * Ruleset: `` + * + * @since 0.14.0 Previously the individual sniffs each contained this property. + * + * @var string WordPress version. + */ + public $minimum_supported_version = '4.5'; + + /** + * Custom list of classes which test classes can extend. + * + * This property allows end-users to add to the $test_class_whitelist via their ruleset. + * This property will need to be set for each sniff which uses the + * `is_test_class()` method. + * Currently the method is used by the `WordPress.Variables.GlobalVariables`, + * `WordPress.NamingConventions.PrefixAllGlobals` and the `WordPress.Files.Filename` sniffs. + * + * Example usage: + * + * + * + * + * + * + * @since 0.11.0 + * + * @var string|string[] + */ + public $custom_test_class_whitelist = array(); + /** * List of the functions which verify nonces. * @@ -775,28 +834,6 @@ abstract class Sniff implements PHPCS_Sniff { 'PHPUnit\Framework\TestCase' => true, ); - /** - * Custom list of classes which test classes can extend. - * - * This property allows end-users to add to the $test_class_whitelist via their ruleset. - * This property will need to be set for each sniff which uses the - * `is_test_class()` method. - * Currently the method is used by the `WordPress.Variables.GlobalVariables`, - * `WordPress.NamingConventions.PrefixAllGlobals` and the `WordPress.Files.Filename` sniffs. - * - * Example usage: - * - * - * - * - * - * - * @since 0.11.0 - * - * @var string|string[] - */ - public $custom_test_class_whitelist = array(); - /** * The current file being sniffed. * @@ -1042,6 +1079,25 @@ protected function get_last_ptr_on_line( $stackPtr ) { return $lastPtr; } + /** + * Overrule the minimum supported WordPress version with a command-line/config value. + * + * Handle setting the minimum supported WP version in one go for all sniffs which + * expect it via the command line or via a `` variable in a ruleset. + * The config variable overrules the default `$minimum_supported_version` and/or a + * `$minimum_supported_version` set for individual sniffs through the ruleset. + * + * @since 0.14.0 + */ + protected function get_wp_version_from_cl() { + $cl_supported_version = trim( PHPCSHelper::get_config_data( 'minimum_supported_wp_version' ) ); + if ( ! empty( $cl_supported_version ) + && filter_var( $cl_supported_version, FILTER_VALIDATE_FLOAT ) !== false + ) { + $this->minimum_supported_version = $cl_supported_version; + } + } + /** * Find whitelisting comment. * diff --git a/WordPress/Sniffs/WP/DeprecatedClassesSniff.php b/WordPress/Sniffs/WP/DeprecatedClassesSniff.php index 05d0428f..de9b36da 100644 --- a/WordPress/Sniffs/WP/DeprecatedClassesSniff.php +++ b/WordPress/Sniffs/WP/DeprecatedClassesSniff.php @@ -14,35 +14,24 @@ /** * Restricts the use of deprecated WordPress classes and suggests alternatives. * + * This sniff will throw an error when usage of a deprecated class is detected + * if the class was deprecated before the minimum supported WP version; + * a warning otherwise. + * By default, it is set to presume that a project will support the current + * WP version and up to three releases before. + * * @package WPCS\WordPressCodingStandards * * @since 0.12.0 * @since 0.13.0 Class name changed: this class is now namespaced. + * @since 0.14.0 Now has the ability to handle minimum supported WP version + * being provided via the command-line or as as value + * in a custom ruleset. + * + * @uses \WordPress\Sniff::$minimum_supported_version */ class DeprecatedClassesSniff extends AbstractClassRestrictionsSniff { - /** - * Minimum WordPress version. - * - * This sniff will throw an error when usage of a deprecated class is - * detected if the class was deprecated before the minimum supported - * WP version; a warning otherwise. - * By default, it is set to presume that a project will support the current - * WP version and up to three releases before. - * This variable allows changing the minimum supported WP version used by - * this sniff by setting a property in a custom phpcs.xml ruleset. - * - * Example usage: - * - * - * - * - * - * - * @var string WordPress versions. - */ - public $minimum_supported_version = '4.5'; - /** * List of deprecated classes with alternative when available. * @@ -92,6 +81,9 @@ public function getGroups() { * @return void */ public function process_matched_token( $stackPtr, $group_name, $matched_content ) { + + $this->get_wp_version_from_cl(); + $class_name = ltrim( strtolower( $matched_content ), '\\' ); $message = 'The %s class has been deprecated since WordPress version %s.'; diff --git a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php index d2cc7491..97f2f047 100644 --- a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php +++ b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php @@ -14,35 +14,24 @@ /** * Restricts the use of various deprecated WordPress functions and suggests alternatives. * + * This sniff will throw an error when usage of deprecated functions is detected + * if the function was deprecated before the minimum supported WP version; + * a warning otherwise. + * By default, it is set to presume that a project will support the current + * WP version and up to three releases before. + * * @package WPCS\WordPressCodingStandards * * @since 0.11.0 * @since 0.13.0 Class name changed: this class is now namespaced. + * @since 0.14.0 Now has the ability to handle minimum supported WP version + * being provided via the command-line or as as value + * in a custom ruleset. + * + * @uses \WordPress\Sniff::$minimum_supported_version */ class DeprecatedFunctionsSniff extends AbstractFunctionRestrictionsSniff { - /** - * Minimum WordPress version. - * - * This sniff will throw an error when usage of deprecated functions is - * detected if the function was deprecated before the minimum supported - * WP version; a warning otherwise. - * By default, it is set to presume that a project will support the current - * WP version and up to three releases before. - * This variable allows changing the minimum supported WP version used by - * this sniff by setting a property in a custom phpcs.xml ruleset. - * - * Example usage: - * - * - * - * - * - * - * @var string WordPress versions. - */ - public $minimum_supported_version = '4.5'; - /** * List of deprecated functions with alternative when available. * @@ -1341,6 +1330,9 @@ public function getGroups() { * @return void */ public function process_matched_token( $stackPtr, $group_name, $matched_content ) { + + $this->get_wp_version_from_cl(); + $function_name = strtolower( $matched_content ); $message = '%s() has been deprecated since WordPress version %s.'; diff --git a/WordPress/Sniffs/WP/DeprecatedParametersSniff.php b/WordPress/Sniffs/WP/DeprecatedParametersSniff.php index 7f0c26e0..7512c40c 100644 --- a/WordPress/Sniffs/WP/DeprecatedParametersSniff.php +++ b/WordPress/Sniffs/WP/DeprecatedParametersSniff.php @@ -24,6 +24,11 @@ * * @since 0.12.0 * @since 0.13.0 Class name changed: this class is now namespaced. + * @since 0.14.0 Now has the ability to handle minimum supported WP version + * being provided via the command-line or as as value + * in a custom ruleset. + * + * @uses \WordPress\Sniff::$minimum_supported_version */ class DeprecatedParametersSniff extends AbstractFunctionParameterSniff { @@ -36,25 +41,6 @@ class DeprecatedParametersSniff extends AbstractFunctionParameterSniff { */ protected $group_name = 'wp_deprecated_parameters'; - /** - * Minimum WordPress version. - * - * This variable allows changing the minimum supported WP version used by - * this sniff by setting a property in a custom ruleset XML file. - * - * Example usage: - * - * - * - * - * - * - * @since 0.12.0 - * - * @var string WordPress version. - */ - public $minimum_supported_version = 4.5; - /** * Array of function, argument, and default value for deprecated argument. * @@ -293,6 +279,9 @@ class DeprecatedParametersSniff extends AbstractFunctionParameterSniff { * @return void */ public function process_parameters( $stackPtr, $group_name, $matched_content, $parameters ) { + + $this->get_wp_version_from_cl(); + $paramCount = count( $parameters ); foreach ( $this->target_functions[ $matched_content ] as $position => $parameter_args ) { From 9d30298d2e23e36949f1bc561f50aa5da74d4303 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Mon, 7 Aug 2017 09:18:01 +0200 Subject: [PATCH 171/282] AssignmentInCondition: updated for feedback. --- WordPress/Sniffs/CodeAnalysis/AssignmentInConditionSniff.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WordPress/Sniffs/CodeAnalysis/AssignmentInConditionSniff.php b/WordPress/Sniffs/CodeAnalysis/AssignmentInConditionSniff.php index 7dd5210a..58bbea9d 100644 --- a/WordPress/Sniffs/CodeAnalysis/AssignmentInConditionSniff.php +++ b/WordPress/Sniffs/CodeAnalysis/AssignmentInConditionSniff.php @@ -169,7 +169,7 @@ public function process_token( $stackPtr ) { if ( true === $hasVariable ) { $this->phpcsFile->addWarning( - 'Variable assignment found within a condition. Did you mean to do a comparison ?', + 'Variable assignment found within a condition. Did you mean to do a comparison?', $hasAssignment, 'Found' ); @@ -181,4 +181,4 @@ public function process_token( $stackPtr ) { } -} // End class. +} From c1d43bfa1c86ecab15df831ee0603993bf05dee3 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Mon, 7 Aug 2017 17:24:33 +0200 Subject: [PATCH 172/282] XSS.EscapeOutput sniff: Fix issue #933 - namespace separators. This simple change means that namespace separators will be be ignored completely by the check for output escaping which fixes the immediate issue. For a more thorough fix, the logic of the function would need to be refactored to take namespaced functions into account as well, but that's for another day. --- WordPress/Sniffs/XSS/EscapeOutputSniff.php | 5 +++++ WordPress/Tests/XSS/EscapeOutputUnitTest.inc | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/WordPress/Sniffs/XSS/EscapeOutputSniff.php b/WordPress/Sniffs/XSS/EscapeOutputSniff.php index eb6ac8fe..a829b1b4 100644 --- a/WordPress/Sniffs/XSS/EscapeOutputSniff.php +++ b/WordPress/Sniffs/XSS/EscapeOutputSniff.php @@ -291,6 +291,11 @@ public function process_token( $stackPtr ) { continue; } + // Ignore namespace separators. + if ( T_NS_SEPARATOR === $this->tokens[ $i ]['code'] ) { + continue; + } + if ( T_OPEN_PARENTHESIS === $this->tokens[ $i ]['code'] ) { if ( ! isset( $this->tokens[ $i ]['parenthesis_closer'] ) ) { diff --git a/WordPress/Tests/XSS/EscapeOutputUnitTest.inc b/WordPress/Tests/XSS/EscapeOutputUnitTest.inc index e00a1559..ab483026 100644 --- a/WordPress/Tests/XSS/EscapeOutputUnitTest.inc +++ b/WordPress/Tests/XSS/EscapeOutputUnitTest.inc @@ -225,3 +225,15 @@ echo 8 * 1.2; // Ok. foo ?> 'menu genesis-nav-menu menu-footer', + 'theme_location' => 'footer', + ] + ) + ); +} From 37c41911534230098b7ffcf0fc7feea2cfe8a088 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 8 Aug 2017 15:30:14 +0200 Subject: [PATCH 173/282] AssignmentInCondition sniff: Detect assignments in ternary conditions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the original PR, the conditions for ternaries were explicitly not examined by this sniff. This PR changes that. As long as either the condition, i.e. the part before the `?` is within parentheses, òr the complete ternary is within parentheses, they will now be examined and throw the appropriate errors. I suspect this may still be a little buggy with parentheses not belonging to the ternary, but with a ternary somewhere within them allowing this sniff to trigger. More unit test cases very welcome! For now, I'm only pulling this in WPCS. Once the worst bugs have been removed, I will upstream this improvement to the PHPCS version as well. --- .../AssignmentInConditionSniff.php | 27 ++++++- .../AssignmentInConditionUnitTest.inc | 22 ++++++ .../AssignmentInConditionUnitTest.php | 73 ++++++++++--------- 3 files changed, 88 insertions(+), 34 deletions(-) diff --git a/WordPress/Sniffs/CodeAnalysis/AssignmentInConditionSniff.php b/WordPress/Sniffs/CodeAnalysis/AssignmentInConditionSniff.php index 58bbea9d..6e39eaac 100644 --- a/WordPress/Sniffs/CodeAnalysis/AssignmentInConditionSniff.php +++ b/WordPress/Sniffs/CodeAnalysis/AssignmentInConditionSniff.php @@ -17,7 +17,7 @@ * * This is a typical code smell and more often than not a comparison was intended. * - * Note: this sniff does not detect variable assignments in the conditional part of ternaries! + * Note: this sniff does not detect variable assignments in ternaries without parentheses! * * @package WPCS\WordPressCodingStandards * @@ -64,6 +64,7 @@ public function register() { $starters = Tokens::$booleanOperators; $starters[ T_SEMICOLON ] = T_SEMICOLON; $starters[ T_OPEN_PARENTHESIS ] = T_OPEN_PARENTHESIS; + $starters[ T_INLINE_ELSE ] = T_INLINE_ELSE; $this->condition_start_tokens = $starters; @@ -74,6 +75,7 @@ public function register() { T_SWITCH, T_CASE, T_WHILE, + T_INLINE_THEN, ); }//end register() @@ -119,6 +121,29 @@ public function process_token( $stackPtr ) { $opener = $stackPtr; $closer = $token['scope_opener']; + } elseif ( T_INLINE_THEN === $token['code'] ) { + // Check if the condition for the ternary is bracketed. + $prev = $this->phpcsFile->findPrevious( Tokens::$emptyTokens, ( $stackPtr - 1 ), null, true ); + if ( false === $prev ) { + // Shouldn't happen, but in that case we don't have anything to examine anyway. + return; + } + + if ( T_CLOSE_PARENTHESIS === $this->tokens[ $prev ]['code'] ) { + if ( ! isset( $this->tokens[ $prev ]['parenthesis_opener'] ) ) { + return; + } + + $opener = $this->tokens[ $prev ]['parenthesis_opener']; + $closer = $prev; + } elseif ( isset( $token['nested_parenthesis'] ) ) { + end( $token['nested_parenthesis'] ); + $opener = key( $token['nested_parenthesis'] ); + $closer = $stackPtr; + } else { + // No parenthesis found, can't determine where the conditional part of the ternary starts. + return; + } } else { if ( isset( $token['parenthesis_opener'], $token['parenthesis_closer'] ) === false ) { return; diff --git a/WordPress/Tests/CodeAnalysis/AssignmentInConditionUnitTest.inc b/WordPress/Tests/CodeAnalysis/AssignmentInConditionUnitTest.inc index b530b308..8248b29a 100644 --- a/WordPress/Tests/CodeAnalysis/AssignmentInConditionUnitTest.inc +++ b/WordPress/Tests/CodeAnalysis/AssignmentInConditionUnitTest.inc @@ -92,3 +92,25 @@ while ( $sample = false ) {} if ($a = 123) : endif; + +/* + * Ternaries should also be checked, but can only be reliably done when in parenthesis. + */ + +// OK. +$mode = ( $a == 'something' ) ? 'on' : 'off'; +$mode = ( $a == 'on' ? 'true' : $a == 'off' ? 't' : 'f' ); + +// Bad. +$mode = ( $a = 'on' ) ? 'on' : 'off'; +$mode = ( $a = 'on' ) ?: 'off'; +$mode = ( $a = 'on' ) ? 'true' : ( $a = 'off' ) ? 't' : 'f'; // Bad x 2. +$mode = ( $a = 'on' ? 'on' : 'off' ); +$mode = ( $a = 'on' ?: 'off' ); +$mode = ( $a = 'on' ? 'true' : ( $a = 'off' ? 't' : 'f' ) ); // Bad x 2. +$mode = ( $a = 'on' ? 'true' : $a = 'off' ? 't' : 'f' ); // Bad x 3. The first ? triggers 1, the second (correctly) 2. + +// Currently not checked. +$mode = $a = 'on' ? 'on' : 'off'; +$mode = $a = 'on' ?: 'off'; +$mode = $a = 'on' ? 'true' : $a = 'off' ? 't' : 'f'; diff --git a/WordPress/Tests/CodeAnalysis/AssignmentInConditionUnitTest.php b/WordPress/Tests/CodeAnalysis/AssignmentInConditionUnitTest.php index 5bac100b..d791e863 100644 --- a/WordPress/Tests/CodeAnalysis/AssignmentInConditionUnitTest.php +++ b/WordPress/Tests/CodeAnalysis/AssignmentInConditionUnitTest.php @@ -37,39 +37,46 @@ public function getErrorList() { */ public function getWarningList() { return array( - 47 => 1, - 48 => 1, - 49 => 1, - 50 => 1, - 51 => 1, - 52 => 1, - 53 => 1, - 54 => 1, - 55 => 1, - 56 => 1, - 57 => 1, - 58 => 1, - 59 => 1, - 60 => 1, - 61 => 1, - 62 => 2, - 64 => 1, - 65 => 1, - 68 => 1, - 69 => 1, - 70 => 1, - 71 => 1, - 72 => 1, - 73 => 1, - 74 => 1, - 76 => 1, - 78 => 1, - 81 => 2, - 85 => 1, - 86 => 2, - 89 => 1, - 91 => 1, - 93 => 1, + 47 => 1, + 48 => 1, + 49 => 1, + 50 => 1, + 51 => 1, + 52 => 1, + 53 => 1, + 54 => 1, + 55 => 1, + 56 => 1, + 57 => 1, + 58 => 1, + 59 => 1, + 60 => 1, + 61 => 1, + 62 => 2, + 64 => 1, + 65 => 1, + 68 => 1, + 69 => 1, + 70 => 1, + 71 => 1, + 72 => 1, + 73 => 1, + 74 => 1, + 76 => 1, + 78 => 1, + 81 => 2, + 85 => 1, + 86 => 2, + 89 => 1, + 91 => 1, + 93 => 1, + 105 => 1, + 106 => 1, + 107 => 2, + 108 => 1, + 109 => 1, + 110 => 2, + 111 => 3, ); } From db1a89895fa96f58507bcca61d43dddc5709236a Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 9 Aug 2017 07:52:48 +0200 Subject: [PATCH 174/282] :sparkles: New `WhiteSpace.PrecisionAlignment` sniff for `Core` This sniff complements the upstream `Generic.WhiteSpace.DisallowSpaceIndent` sniff. The `Generic.WhiteSpace.DisallowSpaceIndent` sniff makes sure that tabs are used for indentation instead of spaces. However, the sniff allows for precision alignment of `# spaces < tab_width`. In WP it is not customary to use precision alignment, though there are a few exceptions where it is used intentionally. This means that precision alignment can not be auto-fixed. We can, however, throw a warning when precision alignment is detected which is what this sniff implements. Notes: * This sniff will detect precision alignment in PHP, JS as well as CSS files. * The sniff adds a new `precision alignment` whitelist comment. * The sniff will handle the "space before star"precision alignment for comments without issue. * The sniff adds a new custom property which allows users to pass an array of tokens to ignore for the purposes of this sniff. By default nothing is ignored. Includes unit tests. I've added the sniff to the `Core` ruleset as this is one of the issues which came out of the initial review of auto-fixed core files. A run of the sniff over core (using the current `phpcs.xml.5.dist` basis) results in 281 infractions in 68 files. See the attachment for details. A visual inspection shows no false positives and that nearly all of the infractions found should be corrected. There are only very few were by the looks of it, the precision alignment was actually intended as such. Fixes 983 --- WordPress-Core/ruleset.xml | 1 + .../WhiteSpace/PrecisionAlignmentSniff.php | 181 ++++++++++++++++++ .../PrecisionAlignmentUnitTest.1.inc | 42 ++++ .../PrecisionAlignmentUnitTest.2.inc | 44 +++++ .../PrecisionAlignmentUnitTest.3.inc | 14 ++ .../WhiteSpace/PrecisionAlignmentUnitTest.css | 5 + .../WhiteSpace/PrecisionAlignmentUnitTest.js | 7 + .../WhiteSpace/PrecisionAlignmentUnitTest.php | 104 ++++++++++ 8 files changed, 398 insertions(+) create mode 100644 WordPress/Sniffs/WhiteSpace/PrecisionAlignmentSniff.php create mode 100644 WordPress/Tests/WhiteSpace/PrecisionAlignmentUnitTest.1.inc create mode 100644 WordPress/Tests/WhiteSpace/PrecisionAlignmentUnitTest.2.inc create mode 100644 WordPress/Tests/WhiteSpace/PrecisionAlignmentUnitTest.3.inc create mode 100644 WordPress/Tests/WhiteSpace/PrecisionAlignmentUnitTest.css create mode 100644 WordPress/Tests/WhiteSpace/PrecisionAlignmentUnitTest.js create mode 100644 WordPress/Tests/WhiteSpace/PrecisionAlignmentUnitTest.php diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index d763d610..fc23c616 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -46,6 +46,7 @@ + + + + + + + warning + + From 457319c0bfc8043384ff063878d302a318648b2b Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 17 Aug 2017 00:45:32 +0200 Subject: [PATCH 177/282] ArrayDeclarationSpacing: add a property to make an exception for single item associative arrays Allow for a property to be set in a custom ruleset to allow single item associative arrays to be single line. If someone can come up with a better (less lengthy) property name: please let me know and I'd happily adjust the PR. I've chosen to implement this as a `true`/`false` toggle. The toggle defaults to `false` based on the rule as it is in the handbook. Alternatively, it could be implemented numerically, i.e. number of items needed before the associative array rule take effect with a default of `0`, but that felt like it would make the rule very arbitrary where one project would have it at `1`, another at `3` etc., which would counter the use of having the rule at all. Fixes 1104 ---- - [ ] Add info on the new property to the customizable properties wiki page --- .../Arrays/ArrayDeclarationSpacingSniff.php | 18 +++++++++++++++++- .../ArrayDeclarationSpacingUnitTest.1.inc | 10 ++++++++++ ...ArrayDeclarationSpacingUnitTest.1.inc.fixed | 13 +++++++++++++ .../ArrayDeclarationSpacingUnitTest.2.inc | 10 ++++++++++ ...ArrayDeclarationSpacingUnitTest.2.inc.fixed | 13 +++++++++++++ .../Arrays/ArrayDeclarationSpacingUnitTest.php | 6 ++++++ 6 files changed, 69 insertions(+), 1 deletion(-) diff --git a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php index 95b1c167..fcdcef3c 100644 --- a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php @@ -36,9 +36,21 @@ * which were not covered elsewhere. The `ArrayDeclaration` sniff has * now been deprecated. * @since 0.13.0 Class name changed: this class is now namespaced. + * @since 0.14.0 Single item associative arrays can now be excepted from the + * "must be multi-line" rule using the + * `allow_single_item_single_line_associative_arrays` property. */ class ArrayDeclarationSpacingSniff extends Sniff { + /** + * Whether or not to allow single item associative arrays to be single line. + * + * @since 0.14.0 + * + * @var bool Defaults to false. + */ + public $allow_single_item_single_line_associative_arrays = false; + /** * Token this sniff targets. * @@ -176,7 +188,11 @@ protected function process_single_line_array( $stackPtr, $opener, $closer ) { $array_items = $this->get_function_call_parameters( $stackPtr ); - if ( ! empty( $array_items ) ) { + if ( ( false === $this->allow_single_item_single_line_associative_arrays + && ! empty( $array_items ) ) + || ( true === $this->allow_single_item_single_line_associative_arrays + && count( $array_items ) > 1 ) + ) { /* * Make sure the double arrow is for *this* array, not for a nested one. */ diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc index 5727abba..3d69c1e1 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc @@ -99,3 +99,13 @@ $foo = array(1 $fields = array( 'value' => 'type'); + +// @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays true + +$bad = array( 'key' => 'value' ); // OK. +$bad = array('key' => 'value'); // Bad, spacing around parenthesis. +$bad = array( 'key' => 'value' ); // Bad, spacing around parenthesis. + +$bad = array( 'key1' => 'value1', 'key2' => 'value2' ); // Bad, more than one item should still be fixed. + +// @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays false diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc.fixed b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc.fixed index b3e18bbd..9b35eb59 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc.fixed +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc.fixed @@ -151,3 +151,16 @@ $foo = array( $fields = array( 'value' => 'type' ); + +// @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays true + +$bad = array( 'key' => 'value' ); // OK. +$bad = array( 'key' => 'value' ); // Bad, spacing around parenthesis. +$bad = array( 'key' => 'value' ); // Bad, spacing around parenthesis. + +$bad = array( +'key1' => 'value1', +'key2' => 'value2' +); // Bad, more than one item should still be fixed. + +// @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays false diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc index 53802a52..272ee9a4 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc @@ -82,3 +82,13 @@ $foo = [1 $fields = [ 'value' => 'type']; + +// @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays true + +$bad = [ 'key' => 'value' ]; // OK. +$bad = ['key' => 'value']; // Bad, spacing around parenthesis. +$bad = [ 'key' => 'value' ]; // Bad, spacing around parenthesis. + +$bad = [ 'key1' => 'value1', 'key2' => 'value2' ]; // Bad, more than one item should still be fixed. + +// @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays false diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc.fixed b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc.fixed index 8ed5a400..24583fae 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc.fixed +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc.fixed @@ -135,3 +135,16 @@ $foo = [ $fields = [ 'value' => 'type' ]; + +// @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays true + +$bad = [ 'key' => 'value' ]; // OK. +$bad = [ 'key' => 'value' ]; // Bad, spacing around parenthesis. +$bad = [ 'key' => 'value' ]; // Bad, spacing around parenthesis. + +$bad = [ +'key1' => 'value1', +'key2' => 'value2' +]; // Bad, more than one item should still be fixed. + +// @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays false diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php index fdb9b7c9..c460bd69 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php @@ -59,6 +59,9 @@ public function getErrorList( $testFile = '' ) { 97 => 1, 98 => 2, 101 => 1, + 106 => 2, + 107 => 2, + 109 => 1, ); // Short arrays. @@ -85,6 +88,9 @@ public function getErrorList( $testFile = '' ) { 80 => 1, 81 => 2, 84 => 1, + 89 => 2, + 90 => 2, + 92 => 1, ); default: From 222d4cfa863cd3e205afa7933905d9eb51a26a6c Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 17 Aug 2017 22:53:08 +0200 Subject: [PATCH 178/282] ArrayDeclarationSpacing: change the default for the new property to `true` The default value for the new `$allow_single_item_single_line_associative_arrays` property is now `true`. Adjusted the documentation and the unit tests accordingly. Includes minor change to improve the phrasing of the error message depending on the setting and a changed error code. --- .../Arrays/ArrayDeclarationSpacingSniff.php | 17 +++++++++++------ .../ArrayDeclarationSpacingUnitTest.1.inc | 12 ++++++------ .../ArrayDeclarationSpacingUnitTest.1.inc.fixed | 16 ++++++++-------- .../ArrayDeclarationSpacingUnitTest.2.inc | 12 ++++++------ .../ArrayDeclarationSpacingUnitTest.2.inc.fixed | 16 ++++++++-------- .../Arrays/ArrayDeclarationSpacingUnitTest.php | 12 ++++++------ 6 files changed, 45 insertions(+), 40 deletions(-) diff --git a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php index fcdcef3c..6adfbec9 100644 --- a/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayDeclarationSpacingSniff.php @@ -36,8 +36,8 @@ * which were not covered elsewhere. The `ArrayDeclaration` sniff has * now been deprecated. * @since 0.13.0 Class name changed: this class is now namespaced. - * @since 0.14.0 Single item associative arrays can now be excepted from the - * "must be multi-line" rule using the + * @since 0.14.0 Single item associative arrays are now by default exempt from the + * "must be multi-line" rule. This behaviour can be changed using the * `allow_single_item_single_line_associative_arrays` property. */ class ArrayDeclarationSpacingSniff extends Sniff { @@ -47,9 +47,9 @@ class ArrayDeclarationSpacingSniff extends Sniff { * * @since 0.14.0 * - * @var bool Defaults to false. + * @var bool Defaults to true. */ - public $allow_single_item_single_line_associative_arrays = false; + public $allow_single_item_single_line_associative_arrays = true; /** * Token this sniff targets. @@ -219,10 +219,15 @@ protected function process_single_line_array( $stackPtr, $opener, $closer ) { if ( true === $array_has_keys ) { + $phrase = 'an'; + if ( true === $this->allow_single_item_single_line_associative_arrays ) { + $phrase = 'a multi-item'; + } $fix = $this->phpcsFile->addFixableError( - 'When an array uses associative keys, each value should start on a new line.', + 'When %s array uses associative keys, each value should start on a new line.', $closer, - 'AssociativeKeyFound' + 'AssociativeArrayFound', + array( $phrase ) ); if ( true === $fix ) { diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc index 3d69c1e1..2fcbe2df 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc @@ -10,7 +10,7 @@ $query_vars = array('food'); // Bad, no spaces after opening and before closing // Test for fixing of extra whitespace. $test = array( 1, 2 ); -$bad = array( 'key' => 'value' ); // Bad, each value of an associative array should start on a new line. +$bad = array( 'key' => 'value' ); // OK, one item single-line associative arrays are ok. // Test for fixing nested associative arrays. $bad = array( array( 'key1' => 'value1', 'key2' => array('sub1' => 1, 'sub2' => 2) ), $key3 => 'value3', array( 'value4', 10 => 'value5', ) ); // Bad. @@ -100,12 +100,12 @@ $foo = array(1 $fields = array( 'value' => 'type'); -// @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays true - -$bad = array( 'key' => 'value' ); // OK. $bad = array('key' => 'value'); // Bad, spacing around parenthesis. $bad = array( 'key' => 'value' ); // Bad, spacing around parenthesis. -$bad = array( 'key1' => 'value1', 'key2' => 'value2' ); // Bad, more than one item should still be fixed. - // @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays false + +$bad = array( 'key' => 'value' ); // Bad. +$bad = array( 'key1' => 'value1', 'key2' => 'value2' ); // Bad. + +// @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays true diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc.fixed b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc.fixed index 9b35eb59..3ffd300e 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc.fixed +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.1.inc.fixed @@ -10,9 +10,7 @@ $query_vars = array( 'food' ); // Bad, no spaces after opening and before closin // Test for fixing of extra whitespace. $test = array( 1, 2 ); -$bad = array( -'key' => 'value' -); // Bad, each value of an associative array should start on a new line. +$bad = array( 'key' => 'value' ); // OK, one item single-line associative arrays are ok. // Test for fixing nested associative arrays. $bad = array( @@ -152,15 +150,17 @@ $fields = array( 'value' => 'type' ); -// @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays true - -$bad = array( 'key' => 'value' ); // OK. $bad = array( 'key' => 'value' ); // Bad, spacing around parenthesis. $bad = array( 'key' => 'value' ); // Bad, spacing around parenthesis. +// @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays false + +$bad = array( +'key' => 'value' +); // Bad. $bad = array( 'key1' => 'value1', 'key2' => 'value2' -); // Bad, more than one item should still be fixed. +); // Bad. -// @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays false +// @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays true diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc index 272ee9a4..495847de 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc @@ -10,7 +10,7 @@ $query_vars = ['food']; // Bad, no spaces after opening and before closing paren // Test for fixing of extra whitespace. $test = [ 1, 2 ]; -$bad = [ 'key' => 'value' ]; // Bad, each value of an associative array should start on a new line. +$bad = [ 'key' => 'value' ]; // OK, one item single-line associative arrays are ok. // Test for fixing nested associative arrays. $bad = [ [ 'key1' => 'value1', 'key2' => ['sub1' => 1, 'sub2' => 2] ], $key3 => 'value3', [ 'value4', 10 => 'value5', ] ]; // Bad. @@ -83,12 +83,12 @@ $foo = [1 $fields = [ 'value' => 'type']; -// @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays true - -$bad = [ 'key' => 'value' ]; // OK. $bad = ['key' => 'value']; // Bad, spacing around parenthesis. $bad = [ 'key' => 'value' ]; // Bad, spacing around parenthesis. -$bad = [ 'key1' => 'value1', 'key2' => 'value2' ]; // Bad, more than one item should still be fixed. - // @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays false + +$bad = [ 'key' => 'value' ]; // Bad. +$bad = [ 'key1' => 'value1', 'key2' => 'value2' ]; // Bad. + +// @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays true diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc.fixed b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc.fixed index 24583fae..015fc2de 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc.fixed +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.2.inc.fixed @@ -10,9 +10,7 @@ $query_vars = [ 'food' ]; // Bad, no spaces after opening and before closing par // Test for fixing of extra whitespace. $test = [ 1, 2 ]; -$bad = [ -'key' => 'value' -]; // Bad, each value of an associative array should start on a new line. +$bad = [ 'key' => 'value' ]; // OK, one item single-line associative arrays are ok. // Test for fixing nested associative arrays. $bad = [ @@ -136,15 +134,17 @@ $fields = [ 'value' => 'type' ]; -// @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays true - -$bad = [ 'key' => 'value' ]; // OK. $bad = [ 'key' => 'value' ]; // Bad, spacing around parenthesis. $bad = [ 'key' => 'value' ]; // Bad, spacing around parenthesis. +// @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays false + +$bad = [ +'key' => 'value' +]; // Bad. $bad = [ 'key1' => 'value1', 'key2' => 'value2' -]; // Bad, more than one item should still be fixed. +]; // Bad. -// @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays false +// @codingStandardsChangeSetting WordPress.Arrays.ArrayDeclarationSpacing allow_single_item_single_line_associative_arrays true diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php index c460bd69..d5efbb9b 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php @@ -36,7 +36,6 @@ public function getErrorList( $testFile = '' ) { return array( 8 => 2, 11 => 2, - 13 => 1, 16 => 4, 20 => 2, 22 => 1, @@ -59,8 +58,9 @@ public function getErrorList( $testFile = '' ) { 97 => 1, 98 => 2, 101 => 1, - 106 => 2, - 107 => 2, + 103 => 2, + 104 => 2, + 108 => 1, 109 => 1, ); @@ -69,7 +69,6 @@ public function getErrorList( $testFile = '' ) { return array( 8 => 2, 11 => 2, - 13 => 1, 16 => 4, 20 => 2, 22 => 1, @@ -88,8 +87,9 @@ public function getErrorList( $testFile = '' ) { 80 => 1, 81 => 2, 84 => 1, - 89 => 2, - 90 => 2, + 86 => 2, + 87 => 2, + 91 => 1, 92 => 1, ); From 4664a75bb85b3edc474fdee63d3836e23fba6378 Mon Sep 17 00:00:00 2001 From: JDGrimes Date: Sat, 19 Aug 2017 16:55:47 -0400 Subject: [PATCH 179/282] ClassInstantiation sniff: correctly handle non-variable array keys Variable array keys (like `$a[ $k ]()`) were handled correctly, but not integer or string keys. --- .../Classes/ClassInstantiationSniff.php | 26 +++++----- .../Classes/ClassInstantiationUnitTest.inc | 8 ++++ .../ClassInstantiationUnitTest.inc.fixed | 8 ++++ .../Classes/ClassInstantiationUnitTest.php | 48 ++++++++++--------- 4 files changed, 55 insertions(+), 35 deletions(-) diff --git a/WordPress/Sniffs/Classes/ClassInstantiationSniff.php b/WordPress/Sniffs/Classes/ClassInstantiationSniff.php index 85a7d2ca..bf85bd93 100644 --- a/WordPress/Sniffs/Classes/ClassInstantiationSniff.php +++ b/WordPress/Sniffs/Classes/ClassInstantiationSniff.php @@ -59,19 +59,21 @@ public function register() { * * Currently does not account for classnames passed as a variable variable. */ - $this->classname_tokens = Tokens::$emptyTokens; - $this->classname_tokens[ T_NS_SEPARATOR ] = T_NS_SEPARATOR; - $this->classname_tokens[ T_STRING ] = T_STRING; - $this->classname_tokens[ T_SELF ] = T_SELF; - $this->classname_tokens[ T_STATIC ] = T_STATIC; - $this->classname_tokens[ T_PARENT ] = T_PARENT; - $this->classname_tokens[ T_ANON_CLASS ] = T_ANON_CLASS; + $this->classname_tokens = Tokens::$emptyTokens; + $this->classname_tokens[ T_NS_SEPARATOR ] = T_NS_SEPARATOR; + $this->classname_tokens[ T_STRING ] = T_STRING; + $this->classname_tokens[ T_SELF ] = T_SELF; + $this->classname_tokens[ T_STATIC ] = T_STATIC; + $this->classname_tokens[ T_PARENT ] = T_PARENT; + $this->classname_tokens[ T_ANON_CLASS ] = T_ANON_CLASS; // Classname in a variable. - $this->classname_tokens[ T_VARIABLE ] = T_VARIABLE; - $this->classname_tokens[ T_DOUBLE_COLON ] = T_DOUBLE_COLON; - $this->classname_tokens[ T_OBJECT_OPERATOR ] = T_OBJECT_OPERATOR; - $this->classname_tokens[ T_OPEN_SQUARE_BRACKET ] = T_OPEN_SQUARE_BRACKET; - $this->classname_tokens[ T_CLOSE_SQUARE_BRACKET ] = T_CLOSE_SQUARE_BRACKET; + $this->classname_tokens[ T_VARIABLE ] = T_VARIABLE; + $this->classname_tokens[ T_DOUBLE_COLON ] = T_DOUBLE_COLON; + $this->classname_tokens[ T_OBJECT_OPERATOR ] = T_OBJECT_OPERATOR; + $this->classname_tokens[ T_OPEN_SQUARE_BRACKET ] = T_OPEN_SQUARE_BRACKET; + $this->classname_tokens[ T_CLOSE_SQUARE_BRACKET ] = T_CLOSE_SQUARE_BRACKET; + $this->classname_tokens[ T_CONSTANT_ENCAPSED_STRING ] = T_CONSTANT_ENCAPSED_STRING; + $this->classname_tokens[ T_LNUMBER ] = T_LNUMBER; return array( T_NEW, diff --git a/WordPress/Tests/Classes/ClassInstantiationUnitTest.inc b/WordPress/Tests/Classes/ClassInstantiationUnitTest.inc index c04b9a45..1a9daa9f 100644 --- a/WordPress/Tests/Classes/ClassInstantiationUnitTest.inc +++ b/WordPress/Tests/Classes/ClassInstantiationUnitTest.inc @@ -96,3 +96,11 @@ $a = new \MyNamespace\MyClass(); // Namespaced classes: Bad. $a = new \MyClass; $a = new \MyNamespace\MyClass; + +// Non-variable keys: OK. +$a = new $array['key'](); +$a = new $array[0](); + +// Non-variable keys: Bad. +$a = new $array['key']; +$a = new $array[0]; diff --git a/WordPress/Tests/Classes/ClassInstantiationUnitTest.inc.fixed b/WordPress/Tests/Classes/ClassInstantiationUnitTest.inc.fixed index 75167379..224a73d3 100644 --- a/WordPress/Tests/Classes/ClassInstantiationUnitTest.inc.fixed +++ b/WordPress/Tests/Classes/ClassInstantiationUnitTest.inc.fixed @@ -96,3 +96,11 @@ $a = new \MyNamespace\MyClass(); // Namespaced classes: Bad. $a = new \MyClass(); $a = new \MyNamespace\MyClass(); + +// Non-variable keys: OK. +$a = new $array['key'](); +$a = new $array[0](); + +// Non-variable keys: Bad. +$a = new $array['key'](); +$a = new $array[0](); diff --git a/WordPress/Tests/Classes/ClassInstantiationUnitTest.php b/WordPress/Tests/Classes/ClassInstantiationUnitTest.php index 48c6d50f..c4000602 100644 --- a/WordPress/Tests/Classes/ClassInstantiationUnitTest.php +++ b/WordPress/Tests/Classes/ClassInstantiationUnitTest.php @@ -32,29 +32,31 @@ public function getErrorList( $testFile = '' ) { switch ( $testFile ) { case 'ClassInstantiationUnitTest.inc': return array( - 37 => 1, - 38 => 1, - 39 => 1, - 40 => 1, - 41 => 1, - 42 => 1, - 46 => 1, - 50 => 1, - 56 => 1, - 61 => 1, - 62 => 1, - 67 => 1, - 69 => 1, - 71 => 1, - 72 => 1, - 75 => 1, - 77 => 1, - 79 => 1, - 80 => 1, - 84 => 1, - 85 => 1, - 97 => 1, - 98 => 1, + 37 => 1, + 38 => 1, + 39 => 1, + 40 => 1, + 41 => 1, + 42 => 1, + 46 => 1, + 50 => 1, + 56 => 1, + 61 => 1, + 62 => 1, + 67 => 1, + 69 => 1, + 71 => 1, + 72 => 1, + 75 => 1, + 77 => 1, + 79 => 1, + 80 => 1, + 84 => 1, + 85 => 1, + 97 => 1, + 98 => 1, + 105 => 1, + 106 => 1, ); case 'ClassInstantiationUnitTest.js': From 3695d3ef60399baf1132880d3981890914cc7359 Mon Sep 17 00:00:00 2001 From: "J.D. Grimes" Date: Mon, 21 Aug 2017 11:29:14 -0400 Subject: [PATCH 180/282] Remove outdated comments from .travis.yml --- .travis.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 08f69892..1eeb7453 100644 --- a/.travis.yml +++ b/.travis.yml @@ -79,12 +79,6 @@ script: # WordPress Coding Standards. # @link https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards # @link http://pear.php.net/package/PHP_CodeSniffer/ - # -p flag: Show progress of the run. - # -s flag: Show sniff codes in all reports. - # -v flag: Print verbose output. - # -n flag: Do not print warnings. (shortcut for --warning-severity=0) - # --standard: Use WordPress as the standard. - # --extensions: Only sniff PHP files. - if [[ "$SNIFF" == "1" ]]; then $PHPCS_BIN . --standard=./bin/phpcs.xml --runtime-set ignore_warnings_on_exit 1; fi # Validate the xml files. # @link http://xmlsoft.org/xmllint.html From 0b959c5d396339ccce8c0db0f57b47049b72d5c9 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 29 Aug 2017 22:19:40 +0200 Subject: [PATCH 181/282] Extra: Encourage the best practice of only declaring one class/interface/trait per file PHPCS 3.1.0 will introduce a new `Generic.Files.OneObjectStructurePerFile` sniff will which check for all three in one go, but cannot be used yet. The current sniffs in this proposal will not catch one file containing a class + an interface + a trait, but will catch any file containing two or more of the same type of object structure. I've chosen to downgrade the message to a warning and to soften the error message a little. Once these sniffs have been in for a while and we have not received negative feedback about them, we could chose to defer to the upstream sniffs and let them `error` with a sterner message. --- WordPress-Extra/ruleset.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/WordPress-Extra/ruleset.xml b/WordPress-Extra/ruleset.xml index 9fe15f26..0c8258be 100644 --- a/WordPress-Extra/ruleset.xml +++ b/WordPress-Extra/ruleset.xml @@ -47,6 +47,22 @@ + + + + warning + Best practice suggestion: Declare only one class in a file. + + + warning + Best practice suggestion: Declare only one interface in a file. + + + warning + Best practice suggestion: Declare only one trait in a file. + + + + + + + + + From 245cbaa66c9ca9d4da9b94d813a483e9b8ffd6b1 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 3 Sep 2017 17:26:38 +0200 Subject: [PATCH 183/282] Remove superfluous line --- WordPress/Sniffs/WhiteSpace/PrecisionAlignmentSniff.php | 1 - 1 file changed, 1 deletion(-) diff --git a/WordPress/Sniffs/WhiteSpace/PrecisionAlignmentSniff.php b/WordPress/Sniffs/WhiteSpace/PrecisionAlignmentSniff.php index 2a480fad..4ed15025 100644 --- a/WordPress/Sniffs/WhiteSpace/PrecisionAlignmentSniff.php +++ b/WordPress/Sniffs/WhiteSpace/PrecisionAlignmentSniff.php @@ -157,7 +157,6 @@ public function process_token( $stackPtr ) { */ $content = ltrim( $this->tokens[ $i ]['content'] ); $whitespace = str_replace( $content, '', $this->tokens[ $i ]['content'] ); - $length = strlen( $whitespace ); $spaces = ( strlen( $whitespace ) % $this->tab_width ); } break; From a117575fe8249d001a2ef82a7627f2771e1eb4eb Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 8 Sep 2017 00:24:58 +0200 Subject: [PATCH 184/282] Fix syntax error in test file Wasn't impeding the unit tests or anything, but was causing issues when I was running some tests to detect fixer conflicts. Fixing the syntax error will allow for adding an additional test to the travis run to automatically check for fixer conflicts based on the existing unit tests at some point in the future. --- WordPress/Tests/VIP/SuperGlobalInputUsageUnitTest.inc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/WordPress/Tests/VIP/SuperGlobalInputUsageUnitTest.inc b/WordPress/Tests/VIP/SuperGlobalInputUsageUnitTest.inc index ecb13156..44911785 100644 --- a/WordPress/Tests/VIP/SuperGlobalInputUsageUnitTest.inc +++ b/WordPress/Tests/VIP/SuperGlobalInputUsageUnitTest.inc @@ -18,3 +18,6 @@ $_REQUEST['wp_customize'] = 'on'; // Ok. // Issue: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/542 if ( isset( $_GET['updated'] ) ) { // input var okay ?> + // Do something. + Date: Thu, 7 Sep 2017 22:56:50 +0200 Subject: [PATCH 185/282] WhiteSpace.PrecisionAlignment: fix potential fatal error If a multi-line comment contained a completely empty line, the sniff would throw a fatal error: `Fatal error: Uninitialized string offset: 0 in WordPress\Sniffs\WhiteSpace\PrecisionAlignmentSniff.php on line 144`. This fixes that. --- WordPress/Sniffs/WhiteSpace/PrecisionAlignmentSniff.php | 2 +- WordPress/Tests/WhiteSpace/PrecisionAlignmentUnitTest.1.inc | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/WordPress/Sniffs/WhiteSpace/PrecisionAlignmentSniff.php b/WordPress/Sniffs/WhiteSpace/PrecisionAlignmentSniff.php index 2a480fad..d19abee2 100644 --- a/WordPress/Sniffs/WhiteSpace/PrecisionAlignmentSniff.php +++ b/WordPress/Sniffs/WhiteSpace/PrecisionAlignmentSniff.php @@ -141,7 +141,7 @@ public function process_token( $stackPtr ) { $comment = ltrim( $this->tokens[ $i ]['content'] ); $whitespace = str_replace( $comment, '', $this->tokens[ $i ]['content'] ); $length = strlen( $whitespace ); - if ( '*' === $comment[0] ) { + if ( isset( $comment[0] ) && '*' === $comment[0] ) { $length--; } diff --git a/WordPress/Tests/WhiteSpace/PrecisionAlignmentUnitTest.1.inc b/WordPress/Tests/WhiteSpace/PrecisionAlignmentUnitTest.1.inc index abe3577d..6f9c4d4c 100644 --- a/WordPress/Tests/WhiteSpace/PrecisionAlignmentUnitTest.1.inc +++ b/WordPress/Tests/WhiteSpace/PrecisionAlignmentUnitTest.1.inc @@ -40,3 +40,8 @@

      Date: Thu, 7 Sep 2017 23:03:40 +0200 Subject: [PATCH 186/282] Fix Precision alignment issues found in the WPCS code base --- WordPress/AbstractArrayAssignmentRestrictionsSniff.php | 6 +++--- WordPress/Sniff.php | 8 ++++---- .../Sniffs/NamingConventions/ValidFunctionNameSniff.php | 6 +++--- WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php | 4 ++-- WordPress/Sniffs/WP/I18nSniff.php | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/WordPress/AbstractArrayAssignmentRestrictionsSniff.php b/WordPress/AbstractArrayAssignmentRestrictionsSniff.php index b5558e14..349995ea 100644 --- a/WordPress/AbstractArrayAssignmentRestrictionsSniff.php +++ b/WordPress/AbstractArrayAssignmentRestrictionsSniff.php @@ -149,9 +149,9 @@ public function process_token( $stackPtr ) { $inst = array(); /* - Covers: - $foo = array( 'bar' => 'taz' ); - $foo['bar'] = $taz; + * Covers: + * $foo = array( 'bar' => 'taz' ); + * $foo['bar'] = $taz; */ if ( in_array( $token['code'], array( T_CLOSE_SQUARE_BRACKET, T_DOUBLE_ARROW ), true ) ) { $operator = $stackPtr; // T_DOUBLE_ARROW. diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index de5f2369..e5ecb507 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -1660,8 +1660,8 @@ protected function is_validated( $stackPtr, $array_key = null, $in_condition_onl if ( $in_condition_only ) { /* - This is a stricter check, requiring the variable to be used only - within the validation condition. + * This is a stricter check, requiring the variable to be used only + * within the validation condition. */ // If there are no conditions, there's no validation. @@ -1684,8 +1684,8 @@ protected function is_validated( $stackPtr, $array_key = null, $in_condition_onl } else { /* - We are are more loose, requiring only that the variable be validated - in the same function/file scope as it is used. + * We are are more loose, requiring only that the variable be validated + * in the same function/file scope as it is used. */ $scope_start = 0; diff --git a/WordPress/Sniffs/NamingConventions/ValidFunctionNameSniff.php b/WordPress/Sniffs/NamingConventions/ValidFunctionNameSniff.php index 4f27b7d9..73073e9a 100644 --- a/WordPress/Sniffs/NamingConventions/ValidFunctionNameSniff.php +++ b/WordPress/Sniffs/NamingConventions/ValidFunctionNameSniff.php @@ -146,9 +146,9 @@ protected function processTokenWithinScope( File $phpcsFile, $stackPtr, $currSco if ( 0 === strpos( $methodName, '__' ) ) { $magicPart = strtolower( substr( $methodName, 2 ) ); if ( ! isset( $this->magicMethods[ $magicPart ] ) && ! isset( $this->methodsDoubleUnderscore[ $magicPart ] ) ) { - $error = 'Method name "%s" is invalid; only PHP magic methods should be prefixed with a double underscore'; - $errorData = array( $className . '::' . $methodName ); - $phpcsFile->addError( $error, $stackPtr, 'MethodDoubleUnderscore', $errorData ); + $error = 'Method name "%s" is invalid; only PHP magic methods should be prefixed with a double underscore'; + $errorData = array( $className . '::' . $methodName ); + $phpcsFile->addError( $error, $stackPtr, 'MethodDoubleUnderscore', $errorData ); } return; diff --git a/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php b/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php index 0974b7d7..f9d29278 100644 --- a/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php +++ b/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php @@ -112,8 +112,8 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p $string = $this->strip_quotes( $this->tokens[ $i ]['content'] ); /* - Here be dragons - a double quoted string can contain extrapolated variables - which don't have to comply with these rules. + * Here be dragons - a double quoted string can contain extrapolated variables + * which don't have to comply with these rules. */ if ( T_DOUBLE_QUOTED_STRING === $this->tokens[ $i ]['code'] ) { $transform = $this->transform_complex_string( $string, $regex ); diff --git a/WordPress/Sniffs/WP/I18nSniff.php b/WordPress/Sniffs/WP/I18nSniff.php index d33714ba..05791788 100644 --- a/WordPress/Sniffs/WP/I18nSniff.php +++ b/WordPress/Sniffs/WP/I18nSniff.php @@ -169,7 +169,7 @@ public function process_token( $stack_ptr ) { $func_open_paren_token = $this->phpcsFile->findNext( T_WHITESPACE, ( $stack_ptr + 1 ), null, true ); if ( false === $func_open_paren_token || T_OPEN_PARENTHESIS !== $this->tokens[ $func_open_paren_token ]['code'] ) { - return; + return; } $arguments_tokens = array(); From bcddee08fb70f5f9017aa08ad11e34c174c9de3c Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 8 Sep 2017 16:09:45 +0200 Subject: [PATCH 187/282] :rocket: Fix travis build: load PHPCS native bootstrap if available and test against PHP 7.2 The upstream PR to support PHPUnit 6.x has (finally) been merged and will be released in PHPCS 3.1. Currently builds against PHPCS `master` are failing because of this as the final version of the PHPCS PHPUnit 6.x support PR includes a test bootstrap in PHPCS which is not being loaded as we use our own bootstrap. Easily solved though, by loading the upstream bootstrap - if the file exists - from our own PHPCS 3 bootstrap file. That way our unit testing will be compatible with all supported PHPCS 3.x versions. The `beStrictAboutTestsThatDoNotTestAnything="false"` addition to the `phpunit.xml.dist` file is needed to prevent PHPUnit from reporting there are no tests in our test files (as the tests are in the upstream test suite and our "tests" are basically only data providers). The changes made in 873 should, for now, not be reverted as PHPCS < 3.1 is not compatible with PHPUnit 6.x and accounting for all the different situation with an `if` statement in the build script would get unnecessarily complicated. See the table below for more details. Once PHPCS 2.x support is dropped and the minimum supported PHPCS version has gone up to 3.1, we should be able to revert the changes made in 873 without issues (except for HHVM). Upstream references: * squizlabs/PHP_CodeSniffer 1383 * squizlabs/PHP_CodeSniffer 1384 Additionally: * While looking at the travis builds to fix this I noticed that `nightly` has gone up to PHP `7.3.0-dev`, so I've added PHP 7.2 to the build matrix. --- .travis.yml | 3 ++- Test/phpcs3-bootstrap.php | 8 ++++++++ phpunit.xml.dist | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1eeb7453..278b5e86 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,7 @@ php: - 5.6 - 7.0 - 7.1 + - 7.2 - nightly env: @@ -33,7 +34,7 @@ matrix: packages: - libxml2-utils - # Run against HHVM and PHP nightly. + # Run against HHVM. - php: hhvm sudo: required dist: trusty diff --git a/Test/phpcs3-bootstrap.php b/Test/phpcs3-bootstrap.php index 8d12fce1..ff6c8cf0 100644 --- a/Test/phpcs3-bootstrap.php +++ b/Test/phpcs3-bootstrap.php @@ -34,6 +34,14 @@ // Try and load the PHPCS autoloader. if ( false !== $phpcsDir && file_exists( $phpcsDir . $ds . 'autoload.php' ) ) { require_once $phpcsDir . $ds . 'autoload.php'; + + /* + * As of PHPCS 3.1, PHPCS support PHPUnit 6.x, but needs a bootstrap, so + * load it if it's available. + */ + if ( file_exists( $phpcsDir . $ds . 'tests' . $ds . 'bootstrap.php' ) ) { + require_once $phpcsDir . $ds . 'tests' . $ds . 'bootstrap.php'; + } } else { echo 'Uh oh... can\'t find PHPCS. Are you sure you are using PHPCS 3.x ? diff --git a/phpunit.xml.dist b/phpunit.xml.dist index f5c2cf0c..6c424549 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -4,5 +4,6 @@ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd" backupGlobals="true" bootstrap="./Test/bootstrap.php" + beStrictAboutTestsThatDoNotTestAnything="false" colors="true"> From 3c05a1326c5efa0a03874b45fb1ab159eab3c673 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 8 Sep 2017 15:16:41 +0200 Subject: [PATCH 188/282] Update example ruleset based on feedback Issue 1128 raised the interesting point that example exclusions maybe taken over literally by people who are not as familiar with PHPCS. This minor change should prevent that. --- phpcs.xml.dist.sample | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/phpcs.xml.dist.sample b/phpcs.xml.dist.sample index 46378bba..d027667f 100644 --- a/phpcs.xml.dist.sample +++ b/phpcs.xml.dist.sample @@ -28,10 +28,15 @@ see the names of the sniffs reporting errors. Once we know the sniff names, we can opt to exclude sniffs which don't suit our project like so. + + The below two examples just show how you can exclude rules. + They are not intended as advice about which sniffs to exclude. --> +
      From 0398d4dcbff74f12162af858bf46ce179ec87964 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 9 Sep 2017 11:41:06 +0200 Subject: [PATCH 189/282] UnitTests: fix unintentional syntax/parse errors in the test case files Fixes a variety of parse errors, syntax errors and fatal "function/variable already declared" errors. These fixes are not necessarily needed for the unit tests to work properly, but - except for when intentional to test something - having valid unit test code makes sense. --- .../Arrays/ArrayIndentationUnitTest.1.inc | 2 +- .../ArrayIndentationUnitTest.1.inc.fixed | 2 +- .../Arrays/ArrayIndentationUnitTest.2.inc | 2 +- .../ArrayIndentationUnitTest.2.inc.fixed | 2 +- .../Tests/CSRF/NonceVerificationUnitTest.inc | 6 +-- .../Classes/ClassInstantiationUnitTest.inc | 4 +- .../ClassInstantiationUnitTest.inc.fixed | 4 +- .../Tests/DB/RestrictedClassesUnitTest.1.inc | 8 ++-- .../PrefixAllGlobalsUnitTest.inc | 6 +-- .../ValidFunctionNameUnitTest.inc | 12 +++--- .../ValidVariableNameUnitTest.inc | 38 +++++++++---------- .../Tests/VIP/DirectDatabaseQueryUnitTest.inc | 20 +++++----- .../VariableRestrictionsUnitTest.inc | 12 +++--- .../VariableRestrictionsUnitTest.php | 4 +- WordPress/Tests/WP/CapitalPDangitUnitTest.inc | 6 +-- .../Tests/WP/CapitalPDangitUnitTest.inc.fixed | 6 +-- .../Tests/WP/DeprecatedClassesUnitTest.inc | 2 +- .../Tests/WP/DiscouragedConstantsUnitTest.inc | 2 +- .../ControlStructureSpacingUnitTest.inc | 30 +++++++-------- .../ControlStructureSpacingUnitTest.inc.fixed | 30 +++++++-------- .../PrecisionAlignmentUnitTest.1.inc | 14 +++---- .../PrecisionAlignmentUnitTest.2.inc | 12 +++--- 22 files changed, 112 insertions(+), 112 deletions(-) diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc index 1cf6d43a..8f815788 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc @@ -338,7 +338,7 @@ $my_array = [ /* * Test multi-line strings as the value for an array item. */ -$test => array( +$test = array( 'notes1' => '

      Whether to use isset() or array_key_exists() depends on what you want to know:

      ', diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc.fixed b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc.fixed index 8c557e8a..814c2a0f 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc.fixed +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc.fixed @@ -338,7 +338,7 @@ $my_array = [ /* * Test multi-line strings as the value for an array item. */ -$test => array( +$test = array( 'notes1' => '

      Whether to use isset() or array_key_exists() depends on what you want to know:

      ', diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc index c54f893e..b058eef3 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc @@ -338,7 +338,7 @@ $my_array = [ /* * Test multi-line strings as the value for an array item. */ -$test => array( +$test = array( 'notes1' => '

      Whether to use isset() or array_key_exists() depends on what you want to know:

      ', diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc.fixed b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc.fixed index 5be63e5a..3864ee63 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc.fixed +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc.fixed @@ -338,7 +338,7 @@ $my_array = [ /* * Test multi-line strings as the value for an array item. */ -$test => array( +$test = array( 'notes1' => '

      Whether to use isset() or array_key_exists() depends on what you want to know:

      ', diff --git a/WordPress/Tests/CSRF/NonceVerificationUnitTest.inc b/WordPress/Tests/CSRF/NonceVerificationUnitTest.inc index 3acd57bd..750cc0ec 100644 --- a/WordPress/Tests/CSRF/NonceVerificationUnitTest.inc +++ b/WordPress/Tests/CSRF/NonceVerificationUnitTest.inc @@ -133,7 +133,7 @@ $b = function () { // @codingStandardsChangeSetting WordPress.CSRF.NonceVerification customSanitizingFunctions sanitize_pc,sanitize_twitter // @codingStandardsChangeSetting WordPress.CSRF.NonceVerification customUnslashingSanitizingFunctions do_something -function foo_5() { +function foo_6() { sanitize_twitter( $_POST['foo'] ); // OK. sanitize_pc( $_POST['bar'] ); // OK. @@ -143,7 +143,7 @@ function foo_5() { // @codingStandardsChangeSetting WordPress.CSRF.NonceVerification customSanitizingFunctions sanitize_pc // @codingStandardsChangeSetting WordPress.CSRF.NonceVerification customUnslashingSanitizingFunctions false -function foo_5() { +function foo_7() { do_something( $_POST['foo'] ); // Bad. sanitize_pc( $_POST['bar'] ); // OK. @@ -154,7 +154,7 @@ function foo_5() { // @codingStandardsChangeSetting WordPress.CSRF.NonceVerification customNonceVerificationFunctions false // @codingStandardsChangeSetting WordPress.CSRF.NonceVerification customSanitizingFunctions false -function foo_5() { +function foo_8() { do_something( $_POST['foo'] ); // Bad. sanitize_pc( $_POST['bar'] ); // Bad. diff --git a/WordPress/Tests/Classes/ClassInstantiationUnitTest.inc b/WordPress/Tests/Classes/ClassInstantiationUnitTest.inc index 1a9daa9f..d0a9ae7a 100644 --- a/WordPress/Tests/Classes/ClassInstantiationUnitTest.inc +++ b/WordPress/Tests/Classes/ClassInstantiationUnitTest.inc @@ -41,7 +41,7 @@ $renderer = new $this->inline_diff_renderer; $b = ( new MyClass )->my_function(); $b = ( new MyClass )::$property; -class ClassA { +class ClassAA { public static function get_instance() { return new self; } @@ -51,7 +51,7 @@ class ClassA { } } -class ClassB extends ClassA { +class ClassBB extends ClassA { public function get_parent_instance() { return new parent; } diff --git a/WordPress/Tests/Classes/ClassInstantiationUnitTest.inc.fixed b/WordPress/Tests/Classes/ClassInstantiationUnitTest.inc.fixed index 224a73d3..d906b2d4 100644 --- a/WordPress/Tests/Classes/ClassInstantiationUnitTest.inc.fixed +++ b/WordPress/Tests/Classes/ClassInstantiationUnitTest.inc.fixed @@ -41,7 +41,7 @@ $renderer = new $this->inline_diff_renderer(); $b = ( new MyClass() )->my_function(); $b = ( new MyClass() )::$property; -class ClassA { +class ClassAA { public static function get_instance() { return new self(); } @@ -51,7 +51,7 @@ class ClassA { } } -class ClassB extends ClassA { +class ClassBB extends ClassA { public function get_parent_instance() { return new parent(); } diff --git a/WordPress/Tests/DB/RestrictedClassesUnitTest.1.inc b/WordPress/Tests/DB/RestrictedClassesUnitTest.1.inc index 493415f8..c5dbdc38 100644 --- a/WordPress/Tests/DB/RestrictedClassesUnitTest.1.inc +++ b/WordPress/Tests/DB/RestrictedClassesUnitTest.1.inc @@ -33,7 +33,7 @@ class OurMysqli implements mysqli {} class TheirMysqli implements \mysqli {} $db5 = new PDO(); -$db6 - new PDO->exec(); +$db6 = ( new PDO() )->exec(); PDO::getAvailableDrivers(); $db7 = new PDOStatement; @@ -49,18 +49,18 @@ $db9 = new \My\DBlayer; $db9 = new \My\DBlayer; // Ok - within excluded group. echo mysqli::$affected_rows; // Error. -class YourMysqli extends \mysqli {} // Error. +class YourMysqliA extends \mysqli {} // Error. // Exclude all groups: // @codingStandardsChangeSetting WordPress.DB.RestrictedClasses exclude test,mysql $db9 = new \My\DBlayer; // Ok - within excluded group. echo mysqli::$affected_rows; // Ok - within excluded group. -class YourMysqli extends \mysqli {} // Ok - within excluded group. +class YourMysqliB extends \mysqli {} // Ok - within excluded group. // Reset group exclusions. // @codingStandardsChangeSetting WordPress.DB.RestrictedClasses exclude false $db9 = new \My\DBlayer; // Error. echo mysqli::$affected_rows; // Error. -class YourMysqli extends \mysqli {} // Error. +class YourMysqliC extends \mysqli {} // Error. diff --git a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc index 44d8dbff..75d0e0db 100644 --- a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc +++ b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc @@ -120,14 +120,14 @@ apply_filters( 'acronym', $var ); /* * OK - not in the global namespace. */ -function acronym_do_something( $param = 'default' ) { +function acronym_do_something_else( $param = 'default' ) { $var = 'abc'; ${$something} = 'value'; } function ( $param ) { $var = 'abc'; -} +}; class Acronym_Example { const SOME_CONSTANT = 'value'; @@ -143,7 +143,7 @@ $acronym_class = new class { public $var = 'abc'; function do_something( $param = 'default' ) {} -} +}; namespace Acronym { function do_something( $param = 'default' ) {} diff --git a/WordPress/Tests/NamingConventions/ValidFunctionNameUnitTest.inc b/WordPress/Tests/NamingConventions/ValidFunctionNameUnitTest.inc index 4eef0dc3..f8b9d142 100644 --- a/WordPress/Tests/NamingConventions/ValidFunctionNameUnitTest.inc +++ b/WordPress/Tests/NamingConventions/ValidFunctionNameUnitTest.inc @@ -43,12 +43,12 @@ class Foo implements ArrayAccess { class Its_A_Kind_Of_Magic { function __construct() {} // Ok. function __destruct() {} // Ok. - function __call() {} // Ok. - function __callStatic() {} // Ok. - function __get() {} // Ok. - function __set() {} // Ok. - function __isset() {} // Ok. - function __unset() {} // Ok. + function __call( $a, $b ) {} // Ok. + static function __callStatic( $a, $b ) {} // Ok. + function __get( $a ) {} // Ok. + function __set( $a, $b ) {} // Ok. + function __isset( $a ) {} // Ok. + function __unset( $a ) {} // Ok. function __sleep() {} // Ok. function __wakeup() {} // Ok. function __toString() {} // Ok. diff --git a/WordPress/Tests/NamingConventions/ValidVariableNameUnitTest.inc b/WordPress/Tests/NamingConventions/ValidVariableNameUnitTest.inc index 0abbf0d1..1e8e9b6d 100644 --- a/WordPress/Tests/NamingConventions/ValidVariableNameUnitTest.inc +++ b/WordPress/Tests/NamingConventions/ValidVariableNameUnitTest.inc @@ -5,25 +5,25 @@ $varname = 'hello'; $_varName = 'hello'; // Bad. class MyClass { - $varName = 'hello'; // Bad. - $var_name = 'hello'; - $varname = 'hello'; - $_varName = 'hello'; // Bad. - - public $varName = 'hello'; // Bad. - public $var_name = 'hello'; - public $varname = 'hello'; - public $_varName = 'hello'; // Bad. - - protected $varName = 'hello'; // Bad. - protected $var_name = 'hello'; - protected $varname = 'hello'; - protected $_varName = 'hello'; // Bad. - - private $_varName = 'hello'; // Bad. - private $_var_name = 'hello'; - private $_varname = 'hello'; - private $varName = 'hello'; // Bad. + var $varName = 'hello'; // Bad. + var $var_name = 'hello'; + var $varname = 'hello'; + var $_varName = 'hello'; // Bad. + + public $varNamf = 'hello'; // Bad. + public $var_namf = 'hello'; + public $varnamf = 'hello'; + public $_varNamf = 'hello'; // Bad. + + protected $varNamg = 'hello'; // Bad. + protected $var_namg = 'hello'; + protected $varnamg = 'hello'; + protected $_varNamg = 'hello'; // Bad. + + private $_varNamh = 'hello'; // Bad. + private $_var_namh = 'hello'; + private $_varnamh = 'hello'; + private $varNamh = 'hello'; // Bad. } echo $varName; // Bad. diff --git a/WordPress/Tests/VIP/DirectDatabaseQueryUnitTest.inc b/WordPress/Tests/VIP/DirectDatabaseQueryUnitTest.inc index 638bd625..617c3de3 100644 --- a/WordPress/Tests/VIP/DirectDatabaseQueryUnitTest.inc +++ b/WordPress/Tests/VIP/DirectDatabaseQueryUnitTest.inc @@ -122,7 +122,7 @@ $b = function () { // @codingStandardsChangeSetting WordPress.VIP.DirectDatabaseQuery customCacheGetFunctions my_cacheget // @codingStandardsChangeSetting WordPress.VIP.DirectDatabaseQuery customCacheSetFunctions my_cacheset,my_other_cacheset // @codingStandardsChangeSetting WordPress.VIP.DirectDatabaseQuery customCacheDeleteFunctions my_cachedel -function cache_custom() { +function cache_customA() { global $wpdb; $quux = my_cacheget( 'quux' ); @@ -132,7 +132,7 @@ function cache_custom() { } } -function cache_custom() { +function cache_customB() { global $wpdb; $quux = my_cacheget( 'quux' ); @@ -142,7 +142,7 @@ function cache_custom() { } } -function cache_custom() { +function cache_customC() { global $wpdb; $wpdb->query( 'SELECT X FROM Y' ); // DB call ok; OK. @@ -152,7 +152,7 @@ function cache_custom() { // @codingStandardsChangeSetting WordPress.VIP.DirectDatabaseQuery customCacheSetFunctions my_cacheset // @codingStandardsChangeSetting WordPress.VIP.DirectDatabaseQuery customCacheDeleteFunctions false -function cache_custom() { +function cache_customD() { global $wpdb; $quux = my_cacheget( 'quux' ); @@ -162,7 +162,7 @@ function cache_custom() { } } -function cache_custom() { +function cache_customE() { global $wpdb; $quux = my_cacheget( 'quux' ); @@ -172,7 +172,7 @@ function cache_custom() { } } -function cache_custom() { +function cache_customF() { global $wpdb; $wpdb->query( 'SELECT X FROM Y' ); // DB call ok; Bad. @@ -182,7 +182,7 @@ function cache_custom() { // @codingStandardsChangeSetting WordPress.VIP.DirectDatabaseQuery customCacheGetFunctions false // @codingStandardsChangeSetting WordPress.VIP.DirectDatabaseQuery customCacheSetFunctions false -function cache_custom() { +function cache_customG() { global $wpdb; $quux = my_cacheget( 'quux' ); @@ -244,7 +244,7 @@ function custom_modify_term_relationship() { } // Test Nowdocs and Heredocs -function foo() { +function foofoo() { global $wpdb; $listofthings = $wpdb->get_col( <<<'EOD' @@ -264,7 +264,7 @@ EOD return $listofthings; } -function baz() { +function bazbaz() { global $wpdb; $baz = wp_cache_get( 'baz' ); @@ -278,7 +278,7 @@ EOD } } -function cache_add_instead_of_set() { +function cache_add_instead_of_setter() { global $wpdb; $baz = wp_cache_get( 'baz' ); diff --git a/WordPress/Tests/Variables/VariableRestrictionsUnitTest.inc b/WordPress/Tests/Variables/VariableRestrictionsUnitTest.inc index 6df1a8a5..163699b1 100644 --- a/WordPress/Tests/Variables/VariableRestrictionsUnitTest.inc +++ b/WordPress/Tests/Variables/VariableRestrictionsUnitTest.inc @@ -8,7 +8,7 @@ $foo->bar(); // Ignored, this is a function not a variable. $foo->bar_method(); // Ignored. -FOO::var; // Matches: 'FOO::var'. +FOO::vars; // Matches: 'FOO::var'. FOO::var_test; @@ -16,7 +16,7 @@ FOO::reg; // Matches: 'FOO::reg*'. FOO::regex; // Matches: 'FOO::reg*'. -FOO::var(); // Ignored. +FOO::vars(); // Ignored. FOO::$static; // Matches: 'FOO::$static'. @@ -26,7 +26,7 @@ $foo["test"]; // Matches: '$foo['test']' AND $foo['test']. bar( $tallyho ); // Matches: '$tallyho'. test( $bar->bar ); // Matches: '$bar->bar'. -BAR::var; // Matches: 'BAR::var'. +BAR::vars; // Matches: 'BAR::var'. /* * Test exclude property. @@ -39,7 +39,7 @@ FOO::regex; // Ok - within excluded group. bar( $tallyho ); // Error. test( $bar->bar ); // Error. -BAR::var; // Error. +BAR::vars; // Error. // Exclude all groups: // @codingStandardsChangeSetting WordPress.Variables.VariableRestrictions exclude test,another @@ -49,7 +49,7 @@ FOO::regex; // Ok - within excluded group. bar( $tallyho ); // Ok - within excluded group. test( $bar->bar ); // Ok - within excluded group. -BAR::var; // Ok - within excluded group. +BAR::vars; // Ok - within excluded group. // Reset group exclusions. // @codingStandardsChangeSetting WordPress.Variables.VariableRestrictions exclude false @@ -59,4 +59,4 @@ FOO::regex; // Error. bar( $tallyho ); // Error. test( $bar->bar ); // Error. -BAR::var; // Error. +BAR::vars; // Error. diff --git a/WordPress/Tests/Variables/VariableRestrictionsUnitTest.php b/WordPress/Tests/Variables/VariableRestrictionsUnitTest.php index 20f96946..0d2ed4be 100644 --- a/WordPress/Tests/Variables/VariableRestrictionsUnitTest.php +++ b/WordPress/Tests/Variables/VariableRestrictionsUnitTest.php @@ -34,7 +34,7 @@ protected function setUp() { 'message' => 'Detected usage of %s', 'object_vars' => array( '$foo->bar', - 'FOO::var', + 'FOO::vars', 'FOO::reg*', 'FOO::$static', ), @@ -50,7 +50,7 @@ protected function setUp() { 'message' => 'Detected usage of %s', 'object_vars' => array( '$bar->bar', - 'BAR::var', + 'BAR::vars', 'BAR::reg*', 'BAR::$static', ), diff --git a/WordPress/Tests/WP/CapitalPDangitUnitTest.inc b/WordPress/Tests/WP/CapitalPDangitUnitTest.inc index 4e0c6df8..20783f50 100644 --- a/WordPress/Tests/WP/CapitalPDangitUnitTest.inc +++ b/WordPress/Tests/WP/CapitalPDangitUnitTest.inc @@ -13,21 +13,21 @@ * * @param string $wordpress OK: Here the incorrect spelling is OK to comply with the variable name rules. */ -function something( $wordpress ) {} // OK. +function somethingA( $wordpress ) {} // OK. /** * Function comment * * @param string $my_wordpress_test OK: Here the incorrect spelling is OK to comply with the variable name rules. */ -function something( $my_wordpress_test ) {} // OK. +function somethingB( $my_wordpress_test ) {} // OK. /** * Bad: In this comment wordPresss should be fixed. * * @param string $test Bad: In this comment word press should be fixed. */ -function something( $test ) {} // OK. +function somethingC( $test ) {} // OK. function wordpress_function() {} // OK - comply with the function name rules. diff --git a/WordPress/Tests/WP/CapitalPDangitUnitTest.inc.fixed b/WordPress/Tests/WP/CapitalPDangitUnitTest.inc.fixed index c1accc1c..7dcc1666 100644 --- a/WordPress/Tests/WP/CapitalPDangitUnitTest.inc.fixed +++ b/WordPress/Tests/WP/CapitalPDangitUnitTest.inc.fixed @@ -13,21 +13,21 @@ * * @param string $wordpress OK: Here the incorrect spelling is OK to comply with the variable name rules. */ -function something( $wordpress ) {} // OK. +function somethingA( $wordpress ) {} // OK. /** * Function comment * * @param string $my_wordpress_test OK: Here the incorrect spelling is OK to comply with the variable name rules. */ -function something( $my_wordpress_test ) {} // OK. +function somethingB( $my_wordpress_test ) {} // OK. /** * Bad: In this comment WordPress should be fixed. * * @param string $test Bad: In this comment WordPress should be fixed. */ -function something( $test ) {} // OK. +function somethingC( $test ) {} // OK. function wordpress_function() {} // OK - comply with the function name rules. diff --git a/WordPress/Tests/WP/DeprecatedClassesUnitTest.inc b/WordPress/Tests/WP/DeprecatedClassesUnitTest.inc index add7761f..fcd27c2f 100644 --- a/WordPress/Tests/WP/DeprecatedClassesUnitTest.inc +++ b/WordPress/Tests/WP/DeprecatedClassesUnitTest.inc @@ -12,7 +12,7 @@ echo WP_User_Search::$users_per_page; echo \WP_User_Search::prepare_query(); class My_User_Search extends WP_User_Search {} class Our_User_Search implements WP_User_Search {} -$a = new WP_User_Search->query(); +$a = (new WP_User_Search())->query(); /* * Warning. diff --git a/WordPress/Tests/WP/DiscouragedConstantsUnitTest.inc b/WordPress/Tests/WP/DiscouragedConstantsUnitTest.inc index 687705e7..d5e5f3a6 100644 --- a/WordPress/Tests/WP/DiscouragedConstantsUnitTest.inc +++ b/WordPress/Tests/WP/DiscouragedConstantsUnitTest.inc @@ -7,7 +7,7 @@ */ // Ok, not a (global) constant. namespace STYLESHEETPATH {} -namespace MY\OTHER\STYLESHEETPATH\NAMESPACE {} +namespace MY\OTHER\STYLESHEETPATH\NS {} use STYLESHEETPATH; use Something, STYLESHEETPATH, SomethingElse; class STYLESHEETPATH { diff --git a/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc b/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc index 2da0347b..081409f4 100644 --- a/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc +++ b/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc @@ -46,14 +46,14 @@ if ( false ) : else : endif; // @codingStandardsChangeSetting WordPress.WhiteSpace.ControlStructureSpacing spaces_before_closure_open_paren 1 -function($arg){} // Bad. -function ( $arg ) { +$a = function($arg){}; // Bad. +$a = function ( $arg ) { // Ok. -} +}; -function () { +$a = function () { // Ok. -} +}; function something($arg){} // Bad. function foo( $arg ) { @@ -69,17 +69,17 @@ function and_another() {} // Bad, space before function name prohibited. function bar() {} // Bad. function baz() {} // Bad. -function test() +function testA() {} // Bad. function &return_by_ref() {} // Ok. // @codingStandardsChangeSetting WordPress.WhiteSpace.ControlStructureSpacing spaces_before_closure_open_paren 0 -function() {} // Ok. -function( $arg ) {} // Ok. -function($arg){} // Bad. -function () {} // Bad. +$a = function() {}; // Ok. +$a = function( $arg ) {}; // Ok. +$a = function($arg){}; // Bad. +$a = function () {}; // Bad. $closureWithArgsAndVars = function( $arg1, $arg2 ) use ( $var1, $var2 ) {}; // Ok. $closureWithArgsAndVars = function ( $arg1, $arg2 ) use ( $var1, $var2 ) {}; // Bad. @@ -102,8 +102,8 @@ use Foo\Admin; // @codingStandardsChangeSetting WordPress.WhiteSpace.ControlStructureSpacing spaces_before_closure_open_paren -1 -function( $arg ) {} // Ok. -function ( $arg ) {} // Ok. +$a = function( $arg ) {}; // Ok. +$a = function ( $arg ) {}; // Ok. $closureWithArgsAndVars = function( $arg1, $arg2 ) use ( $var1, $var2 ) {}; // Ok. $closureWithArgsAndVars = function ( $arg1, $arg2 ) use ( $var1, $var2 ) {}; // Ok. @@ -167,7 +167,7 @@ if ( $foo ) { /** * Comment */ - class bar() { + class bar { }//end class @@ -177,7 +177,7 @@ if ( $foo ) { // Check for too many spaces as long as the next non-blank token is on the same line. function test( $blah ) {} // Bad. -function( $bar ) {} // Bad. +$a = function( $bar ) {}; // Bad. if ( 'abc' === $test ) { // Bad. echo 'hi'; @@ -193,7 +193,7 @@ while ( $blah ) { // Bad. echo 'bye bye'; } -for ( $i = 0; $i < 1; $++ ) { // Bad. +for ( $i = 0; $i < 1; $i++ ) { // Bad. echo 'hi'; } diff --git a/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc.fixed b/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc.fixed index d138c2f4..7abd37f7 100644 --- a/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc.fixed +++ b/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.inc.fixed @@ -44,14 +44,14 @@ if ( false ) : else : endif; // @codingStandardsChangeSetting WordPress.WhiteSpace.ControlStructureSpacing spaces_before_closure_open_paren 1 -function ( $arg ) {} // Bad. -function ( $arg ) { +$a = function ( $arg ) {}; // Bad. +$a = function ( $arg ) { // Ok. -} +}; -function () { +$a = function () { // Ok. -} +}; function something( $arg ) {} // Bad. function foo( $arg ) { @@ -66,16 +66,16 @@ function another() {} // Bad, space before open parenthesis prohibited. function and_another() {} // Bad, space before function name prohibited. function bar() {} // Bad. function baz() {} // Bad. -function test() {} // Bad. +function testA() {} // Bad. function &return_by_ref() {} // Ok. // @codingStandardsChangeSetting WordPress.WhiteSpace.ControlStructureSpacing spaces_before_closure_open_paren 0 -function() {} // Ok. -function( $arg ) {} // Ok. -function( $arg ) {} // Bad. -function() {} // Bad. +$a = function() {}; // Ok. +$a = function( $arg ) {}; // Ok. +$a = function( $arg ) {}; // Bad. +$a = function() {}; // Bad. $closureWithArgsAndVars = function( $arg1, $arg2 ) use ( $var1, $var2 ) {}; // Ok. $closureWithArgsAndVars = function( $arg1, $arg2 ) use ( $var1, $var2 ) {}; // Bad. @@ -98,8 +98,8 @@ use Foo\Admin; // @codingStandardsChangeSetting WordPress.WhiteSpace.ControlStructureSpacing spaces_before_closure_open_paren -1 -function( $arg ) {} // Ok. -function ( $arg ) {} // Ok. +$a = function( $arg ) {}; // Ok. +$a = function ( $arg ) {}; // Ok. $closureWithArgsAndVars = function( $arg1, $arg2 ) use ( $var1, $var2 ) {}; // Ok. $closureWithArgsAndVars = function ( $arg1, $arg2 ) use ( $var1, $var2 ) {}; // Ok. @@ -162,7 +162,7 @@ if ( $foo ) { /** * Comment */ - class bar() { + class bar { }//end class @@ -172,7 +172,7 @@ if ( $foo ) { // Check for too many spaces as long as the next non-blank token is on the same line. function test( $blah ) {} // Bad. -function( $bar ) {} // Bad. +$a = function( $bar ) {}; // Bad. if ( 'abc' === $test ) { // Bad. echo 'hi'; @@ -188,7 +188,7 @@ while ( $blah ) { // Bad. echo 'bye bye'; } -for ( $i = 0; $i < 1; $++ ) { // Bad. +for ( $i = 0; $i < 1; $i++ ) { // Bad. echo 'hi'; } diff --git a/WordPress/Tests/WhiteSpace/PrecisionAlignmentUnitTest.1.inc b/WordPress/Tests/WhiteSpace/PrecisionAlignmentUnitTest.1.inc index 6f9c4d4c..378f6dbe 100644 --- a/WordPress/Tests/WhiteSpace/PrecisionAlignmentUnitTest.1.inc +++ b/WordPress/Tests/WhiteSpace/PrecisionAlignmentUnitTest.1.inc @@ -1,18 +1,18 @@ diff --git a/WordPress/Tests/WhiteSpace/PrecisionAlignmentUnitTest.2.inc b/WordPress/Tests/WhiteSpace/PrecisionAlignmentUnitTest.2.inc index 528266a6..b8dc1a9d 100644 --- a/WordPress/Tests/WhiteSpace/PrecisionAlignmentUnitTest.2.inc +++ b/WordPress/Tests/WhiteSpace/PrecisionAlignmentUnitTest.2.inc @@ -2,19 +2,19 @@ From 3ad0053eac421313e3d7863c90c46e2b25024e95 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 13 Sep 2017 21:20:55 +0200 Subject: [PATCH 190/282] I18n unit tests: Rename unit test files - part 1 --- .../Tests/WP/{I18nUnitTest.1.inc => I18nUnitTest.2.inc} | 0 WordPress/Tests/WP/I18nUnitTest.php | 8 ++++---- 2 files changed, 4 insertions(+), 4 deletions(-) rename WordPress/Tests/WP/{I18nUnitTest.1.inc => I18nUnitTest.2.inc} (100%) diff --git a/WordPress/Tests/WP/I18nUnitTest.1.inc b/WordPress/Tests/WP/I18nUnitTest.2.inc similarity index 100% rename from WordPress/Tests/WP/I18nUnitTest.1.inc rename to WordPress/Tests/WP/I18nUnitTest.2.inc diff --git a/WordPress/Tests/WP/I18nUnitTest.php b/WordPress/Tests/WP/I18nUnitTest.php index 0083094b..fcc788cd 100644 --- a/WordPress/Tests/WP/I18nUnitTest.php +++ b/WordPress/Tests/WP/I18nUnitTest.php @@ -44,7 +44,7 @@ protected function tearDown() { * @param string $testFile The name of the file being tested. * @return array => */ - public function getErrorList( $testFile = 'I18nUnitTest.inc' ) { + public function getErrorList( $testFile = '' ) { switch ( $testFile ) { case 'I18nUnitTest.inc': @@ -112,7 +112,7 @@ public function getErrorList( $testFile = 'I18nUnitTest.inc' ) { 148 => 1, ); - case 'I18nUnitTest.1.inc': + case 'I18nUnitTest.2.inc': return array( 104 => 2, ); @@ -130,7 +130,7 @@ public function getErrorList( $testFile = 'I18nUnitTest.inc' ) { * @param string $testFile The name of the file being tested. * @return array => */ - public function getWarningList( $testFile = 'I18nUnitTest.inc' ) { + public function getWarningList( $testFile = '' ) { switch ( $testFile ) { case 'I18nUnitTest.inc': return array( @@ -142,7 +142,7 @@ public function getWarningList( $testFile = 'I18nUnitTest.inc' ) { 103 => 1, ); - case 'I18nUnitTest.1.inc': + case 'I18nUnitTest.2.inc': return array( 8 => 1, 43 => 1, From e2e0ee5f817f59464bf8288b85f3e23353c5900c Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 13 Sep 2017 21:21:51 +0200 Subject: [PATCH 191/282] I18n unit tests: Rename unit test files - part 2 --- WordPress/Tests/WP/{I18nUnitTest.inc => I18nUnitTest.1.inc} | 0 .../WP/{I18nUnitTest.inc.fixed => I18nUnitTest.1.inc.fixed} | 0 WordPress/Tests/WP/I18nUnitTest.php | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) rename WordPress/Tests/WP/{I18nUnitTest.inc => I18nUnitTest.1.inc} (100%) rename WordPress/Tests/WP/{I18nUnitTest.inc.fixed => I18nUnitTest.1.inc.fixed} (100%) diff --git a/WordPress/Tests/WP/I18nUnitTest.inc b/WordPress/Tests/WP/I18nUnitTest.1.inc similarity index 100% rename from WordPress/Tests/WP/I18nUnitTest.inc rename to WordPress/Tests/WP/I18nUnitTest.1.inc diff --git a/WordPress/Tests/WP/I18nUnitTest.inc.fixed b/WordPress/Tests/WP/I18nUnitTest.1.inc.fixed similarity index 100% rename from WordPress/Tests/WP/I18nUnitTest.inc.fixed rename to WordPress/Tests/WP/I18nUnitTest.1.inc.fixed diff --git a/WordPress/Tests/WP/I18nUnitTest.php b/WordPress/Tests/WP/I18nUnitTest.php index fcc788cd..a16065bd 100644 --- a/WordPress/Tests/WP/I18nUnitTest.php +++ b/WordPress/Tests/WP/I18nUnitTest.php @@ -47,7 +47,7 @@ protected function tearDown() { public function getErrorList( $testFile = '' ) { switch ( $testFile ) { - case 'I18nUnitTest.inc': + case 'I18nUnitTest.1.inc': return array( 3 => 1, 6 => 1, @@ -132,7 +132,7 @@ public function getErrorList( $testFile = '' ) { */ public function getWarningList( $testFile = '' ) { switch ( $testFile ) { - case 'I18nUnitTest.inc': + case 'I18nUnitTest.1.inc': return array( 69 => 1, 70 => 1, From 4926698654d54c1c47d833a89d87eb27c6d41014 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 13 Sep 2017 22:19:06 +0200 Subject: [PATCH 192/282] I18n unit tests: Change over from setting property value via config to inline --- WordPress/Tests/WP/I18nUnitTest.1.inc | 3 ++- WordPress/Tests/WP/I18nUnitTest.1.inc.fixed | 3 ++- WordPress/Tests/WP/I18nUnitTest.2.inc | 4 +++- WordPress/Tests/WP/I18nUnitTest.php | 18 +----------------- 4 files changed, 8 insertions(+), 20 deletions(-) diff --git a/WordPress/Tests/WP/I18nUnitTest.1.inc b/WordPress/Tests/WP/I18nUnitTest.1.inc index 79d1d32b..534bc9ba 100644 --- a/WordPress/Tests/WP/I18nUnitTest.1.inc +++ b/WordPress/Tests/WP/I18nUnitTest.1.inc @@ -1,5 +1,6 @@ 1, + 9 => 1, 43 => 1, 49 => 1, 52 => 1, From 89c0138ef4d9d485c047d0d6d694b9f79956356b Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 13 Sep 2017 22:22:52 +0200 Subject: [PATCH 193/282] I18n unit tests: Add previously missing unit test cases and adjust the line numbering --- WordPress/Tests/WP/I18nUnitTest.1.inc | 21 ++++++++++----------- WordPress/Tests/WP/I18nUnitTest.1.inc.fixed | 21 ++++++++++----------- WordPress/Tests/WP/I18nUnitTest.php | 21 ++++++++++++--------- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/WordPress/Tests/WP/I18nUnitTest.1.inc b/WordPress/Tests/WP/I18nUnitTest.1.inc index 534bc9ba..1a5405f3 100644 --- a/WordPress/Tests/WP/I18nUnitTest.1.inc +++ b/WordPress/Tests/WP/I18nUnitTest.1.inc @@ -1,8 +1,17 @@ 1, - 6 => 1, - 9 => 1, + 10 => 1, 11 => 1, - 13 => 1, - 15 => 1, - 17 => 1, + 12 => 1, + 14 => 1, + 16 => 1, 19 => 1, 21 => 1, 23 => 1, - 25 => 1, + 24 => 1, + 26 => 1, 27 => 1, - 33 => 1, - 35 => 1, + 28 => 1, + 30 => 1, + 31 => 1, + 32 => 1, 37 => 1, + 38 => 1, 39 => 1, 41 => 1, + 42 => 1, 43 => 1, 45 => 1, 47 => 1, From d225ba7b6ba9c2a79b4f2d7ac68dbdf3f31e8180 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 13 Sep 2017 22:20:55 +0200 Subject: [PATCH 194/282] I18n unit tests: Add additional unit test file to test setting text_domain from the command line --- WordPress/Tests/WP/I18nUnitTest.3.inc | 21 ++++++++++++ WordPress/Tests/WP/I18nUnitTest.php | 49 +++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 WordPress/Tests/WP/I18nUnitTest.3.inc diff --git a/WordPress/Tests/WP/I18nUnitTest.3.inc b/WordPress/Tests/WP/I18nUnitTest.3.inc new file mode 100644 index 00000000..bac1dadc --- /dev/null +++ b/WordPress/Tests/WP/I18nUnitTest.3.inc @@ -0,0 +1,21 @@ +setConfigData( 'text_domain', 'something', true ); + } + } + /** * Returns the lines where errors should occur. * @@ -104,6 +139,20 @@ public function getErrorList( $testFile = '' ) { 104 => 2, ); + case 'I18nUnitTest.3.inc': + return array( + 10 => 1, + 11 => 1, + 13 => 1, + 14 => 1, + 15 => 1, + 16 => 1, + 17 => 1, + 18 => 1, + 20 => 1, + 21 => 1, + ); + default: return array(); From 8a4dfcecea0ebdd9270583303264d3e390a14423 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Wed, 13 Sep 2017 10:08:27 -0700 Subject: [PATCH 195/282] [WordPress.WP.I18n] Allow omitting $text_domain arg when 'default' --- WordPress/Sniffs/WP/I18nSniff.php | 2 +- WordPress/Tests/WP/I18nUnitTest.1.inc | 9 +++++++-- WordPress/Tests/WP/I18nUnitTest.1.inc.fixed | 9 +++++++-- WordPress/Tests/WP/I18nUnitTest.2.inc | 2 +- WordPress/Tests/WP/I18nUnitTest.php | 1 + 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/WordPress/Sniffs/WP/I18nSniff.php b/WordPress/Sniffs/WP/I18nSniff.php index 05791788..8fe92e1f 100644 --- a/WordPress/Sniffs/WP/I18nSniff.php +++ b/WordPress/Sniffs/WP/I18nSniff.php @@ -345,7 +345,7 @@ protected function check_argument_tokens( $context ) { if ( empty( $tokens ) || 0 === count( $tokens ) ) { $code = $this->string_to_errorcode( 'MissingArg' . ucfirst( $arg_name ) ); - if ( 'domain' !== $arg_name || ! empty( $this->text_domain ) ) { + if ( 'domain' !== $arg_name || ( ! empty( $this->text_domain ) && ! in_array( 'default', $this->text_domain, true ) ) ) { $this->addMessage( 'Missing $%s arg.', $stack_ptr, $is_error, $code, array( $arg_name ) ); } return false; diff --git a/WordPress/Tests/WP/I18nUnitTest.1.inc b/WordPress/Tests/WP/I18nUnitTest.1.inc index 1a5405f3..e6de3ac9 100644 --- a/WordPress/Tests/WP/I18nUnitTest.1.inc +++ b/WordPress/Tests/WP/I18nUnitTest.1.inc @@ -5,7 +5,7 @@ __( 'string' ); // OK - no text domain known, so not checked. __( 'string', 'something' ); // OK - no text domain known, so not checked. -// @codingStandardsChangeSetting WordPress.WP.I18n text_domain my-slug,default +// @codingStandardsChangeSetting WordPress.WP.I18n text_domain my-slug __( 'string' ); // Bad - no text domain passed. __( 'string', 'something' ); // Bad - text domain mismatch. @@ -112,7 +112,7 @@ __( 'String with a literal %%', 'my-slug'); // Ok, replacement would be a single __( 'String with a literal %% and a %s placeholder', 'my-slug'); // Ok. __( 'A replacement variable can not start with "%%cf_" or "%%ct_" as these are reserved for the WPSEO standard variable variables for custom fields and custom taxonomies. Try making your variable name unique.', 'my-slug' ); // Ok. -// The domain 'default' was also added to the text domains. +// @codingStandardsChangeSetting WordPress.WP.I18n text_domain my-slug,default __( 'String default text domain.', 'default' ); // Ok. __( "String default text domain.", "default" ); // Ok. @@ -151,5 +151,10 @@ really. EOD , 'my-slug' ); // OK. +// @codingStandardsChangeSetting WordPress.WP.I18n text_domain default +__( 'String default text domain.', 'my-slug' ); // Bad because text_domain is only 'default'. +__( 'String default text domain.', 'default' ); // Ok because domain is being explicit. +__( 'String default text domain.' ); // Ok because default domain is 'default' and it matches one of the supplied configured text domains. + // @codingStandardsChangeSetting WordPress.WP.I18n text_domain null // @codingStandardsChangeSetting WordPress.WP.I18n check_translator_comments true diff --git a/WordPress/Tests/WP/I18nUnitTest.1.inc.fixed b/WordPress/Tests/WP/I18nUnitTest.1.inc.fixed index 4fe24866..dedb68c7 100644 --- a/WordPress/Tests/WP/I18nUnitTest.1.inc.fixed +++ b/WordPress/Tests/WP/I18nUnitTest.1.inc.fixed @@ -5,7 +5,7 @@ __( 'string' ); // OK - no text domain known, so not checked. __( 'string', 'something' ); // OK - no text domain known, so not checked. -// @codingStandardsChangeSetting WordPress.WP.I18n text_domain my-slug,default +// @codingStandardsChangeSetting WordPress.WP.I18n text_domain my-slug __( 'string' ); // Bad - no text domain passed. __( 'string', 'something' ); // Bad - text domain mismatch. @@ -112,7 +112,7 @@ __( 'String with a literal %%', 'my-slug'); // Ok, replacement would be a single __( 'String with a literal %% and a %s placeholder', 'my-slug'); // Ok. __( 'A replacement variable can not start with "%%cf_" or "%%ct_" as these are reserved for the WPSEO standard variable variables for custom fields and custom taxonomies. Try making your variable name unique.', 'my-slug' ); // Ok. -// The domain 'default' was also added to the text domains. +// @codingStandardsChangeSetting WordPress.WP.I18n text_domain my-slug,default __( 'String default text domain.', 'default' ); // Ok. __( "String default text domain.", "default" ); // Ok. @@ -151,5 +151,10 @@ really. EOD , 'my-slug' ); // OK. +// @codingStandardsChangeSetting WordPress.WP.I18n text_domain default +__( 'String default text domain.', 'my-slug' ); // Bad because text_domain is only 'default'. +__( 'String default text domain.', 'default' ); // Ok because domain is being explicit. +__( 'String default text domain.' ); // Ok because default domain is 'default' and it matches one of the supplied configured text domains. + // @codingStandardsChangeSetting WordPress.WP.I18n text_domain null // @codingStandardsChangeSetting WordPress.WP.I18n check_translator_comments true diff --git a/WordPress/Tests/WP/I18nUnitTest.2.inc b/WordPress/Tests/WP/I18nUnitTest.2.inc index bfda379f..0da82a10 100644 --- a/WordPress/Tests/WP/I18nUnitTest.2.inc +++ b/WordPress/Tests/WP/I18nUnitTest.2.inc @@ -2,7 +2,7 @@ /* * Test sniffing for translator comments. */ -// @codingStandardsChangeSetting WordPress.WP.I18n text_domain my-slug,default +// @codingStandardsChangeSetting WordPress.WP.I18n text_domain my-slug /* Basic test ****************************************************************/ __( 'No placeholders here.', 'my-slug' ); // Ok, no placeholders, so no translators comment needed. diff --git a/WordPress/Tests/WP/I18nUnitTest.php b/WordPress/Tests/WP/I18nUnitTest.php index 63ffb75e..55b9ff98 100644 --- a/WordPress/Tests/WP/I18nUnitTest.php +++ b/WordPress/Tests/WP/I18nUnitTest.php @@ -132,6 +132,7 @@ public function getErrorList( $testFile = '' ) { 138 => 1, 143 => 1, 148 => 1, + 155 => 1, ); case 'I18nUnitTest.2.inc': From 78f2b37d5de8289ab6a161e5392d0f0d6d018059 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Wed, 13 Sep 2017 16:48:58 -0700 Subject: [PATCH 196/282] Reset text_domain to false instead of null See https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/pull/1141#issuecomment-329318319 Props @jrfnl. --- WordPress/Tests/WP/I18nUnitTest.1.inc | 2 +- WordPress/Tests/WP/I18nUnitTest.1.inc.fixed | 2 +- WordPress/Tests/WP/I18nUnitTest.2.inc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WordPress/Tests/WP/I18nUnitTest.1.inc b/WordPress/Tests/WP/I18nUnitTest.1.inc index e6de3ac9..1728a733 100644 --- a/WordPress/Tests/WP/I18nUnitTest.1.inc +++ b/WordPress/Tests/WP/I18nUnitTest.1.inc @@ -156,5 +156,5 @@ __( 'String default text domain.', 'my-slug' ); // Bad because text_domain is on __( 'String default text domain.', 'default' ); // Ok because domain is being explicit. __( 'String default text domain.' ); // Ok because default domain is 'default' and it matches one of the supplied configured text domains. -// @codingStandardsChangeSetting WordPress.WP.I18n text_domain null +// @codingStandardsChangeSetting WordPress.WP.I18n text_domain false // @codingStandardsChangeSetting WordPress.WP.I18n check_translator_comments true diff --git a/WordPress/Tests/WP/I18nUnitTest.1.inc.fixed b/WordPress/Tests/WP/I18nUnitTest.1.inc.fixed index dedb68c7..d9a1e6e7 100644 --- a/WordPress/Tests/WP/I18nUnitTest.1.inc.fixed +++ b/WordPress/Tests/WP/I18nUnitTest.1.inc.fixed @@ -156,5 +156,5 @@ __( 'String default text domain.', 'my-slug' ); // Bad because text_domain is on __( 'String default text domain.', 'default' ); // Ok because domain is being explicit. __( 'String default text domain.' ); // Ok because default domain is 'default' and it matches one of the supplied configured text domains. -// @codingStandardsChangeSetting WordPress.WP.I18n text_domain null +// @codingStandardsChangeSetting WordPress.WP.I18n text_domain false // @codingStandardsChangeSetting WordPress.WP.I18n check_translator_comments true diff --git a/WordPress/Tests/WP/I18nUnitTest.2.inc b/WordPress/Tests/WP/I18nUnitTest.2.inc index 0da82a10..0c6a5a5c 100644 --- a/WordPress/Tests/WP/I18nUnitTest.2.inc +++ b/WordPress/Tests/WP/I18nUnitTest.2.inc @@ -103,4 +103,4 @@ __( 'foo 100% bar', 'my-slug' ); // Ok, not a placeholder. // Issue #830. _e(); // Bad. -// @codingStandardsChangeSetting WordPress.WP.I18n text_domain null +// @codingStandardsChangeSetting WordPress.WP.I18n text_domain false From 2f5582e873803e12408d7e246689e611d0cd7457 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 15 Sep 2017 13:19:11 +0200 Subject: [PATCH 197/282] Ruleset: maintain compatibility with PHPCS 2.x In PHPCS 3.x, the message, type and a number of other errorcode properties can be changes for all errors in a sniff in one go. In PHPCS 2.x this is not yet possible and needs to be configured for each errorcode individually. --- WordPress-Extra/ruleset.xml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/WordPress-Extra/ruleset.xml b/WordPress-Extra/ruleset.xml index 0c8258be..daa43982 100644 --- a/WordPress-Extra/ruleset.xml +++ b/WordPress-Extra/ruleset.xml @@ -50,15 +50,18 @@ - + + warning Best practice suggestion: Declare only one class in a file. - + + warning Best practice suggestion: Declare only one interface in a file. - + + warning Best practice suggestion: Declare only one trait in a file. From 4c25d2df9d0c081d00b0f20a3a5b2b33745e7db7 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 15 Sep 2017 02:12:13 +0200 Subject: [PATCH 198/282] [Extra] Add PEAR.Files.IncludingFile sniff --- WordPress-Extra/ruleset.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/WordPress-Extra/ruleset.xml b/WordPress-Extra/ruleset.xml index daa43982..98383709 100644 --- a/WordPress-Extra/ruleset.xml +++ b/WordPress-Extra/ruleset.xml @@ -39,6 +39,22 @@ https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/pull/809 --> + + + + + + + warning + + + warning + + + warning + + From 5c7f3a665eee879cb5191dfe7eb485b5190d70f3 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 15 Sep 2017 13:05:56 +0200 Subject: [PATCH 199/282] Fix up the existing codebase for newly added IncludingFile sniff --- Test/phpcs2-bootstrap.php | 6 +++--- Test/phpcs3-bootstrap.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Test/phpcs2-bootstrap.php b/Test/phpcs2-bootstrap.php index 940e7ade..fefff184 100644 --- a/Test/phpcs2-bootstrap.php +++ b/Test/phpcs2-bootstrap.php @@ -44,9 +44,9 @@ } // Load the PHPCS test classes and the WPCS versions where necessary. -include_once PHPCS_DIR . $ds . 'tests' . $ds . 'AllTests.php'; -include_once __DIR__ . $ds . 'Standards' . $ds . 'AllSniffs.php'; -include_once __DIR__ . $ds . 'Standards' . $ds . 'AbstractSniffUnitTest.php'; +require_once PHPCS_DIR . $ds . 'tests' . $ds . 'AllTests.php'; +require_once __DIR__ . $ds . 'Standards' . $ds . 'AllSniffs.php'; +require_once __DIR__ . $ds . 'Standards' . $ds . 'AbstractSniffUnitTest.php'; class_alias( 'WordPressCS\Test\AbstractSniffUnitTest', 'PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest' ); diff --git a/Test/phpcs3-bootstrap.php b/Test/phpcs3-bootstrap.php index ff6c8cf0..93ccd68b 100644 --- a/Test/phpcs3-bootstrap.php +++ b/Test/phpcs3-bootstrap.php @@ -57,5 +57,5 @@ } // Load our class aliases. -include_once dirname( __DIR__ ) . $ds . 'WordPress' . $ds . 'PHPCSAliases.php'; +require_once dirname( __DIR__ ) . $ds . 'WordPress' . $ds . 'PHPCSAliases.php'; unset( $ds, $phpcsDir ); From 200416a2a3610213930338cbecb9bcd43fd08537 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 19 Sep 2017 01:31:19 +0200 Subject: [PATCH 200/282] :sparkles: New "Generic.PHP.DiscourageGoto" sniff Usage of goto is seen as a typical code smell. Includes unit tests. Adding this sniff to `Extra` for now. The sniff can be moved to `Core` once the handbook has been adjusted (if it will be). This sniff is a duplicate of the same as pulled upstream in PR squizlabs/PHP_CodeSniffer 1664 Once the minimum PHPCS requirement for WPCS goes up beyond the version in which the upstream PR is merged, this sniff can be safely removed. --- WordPress-Extra/ruleset.xml | 10 ++++ WordPress/Sniffs/PHP/DiscourageGotoSniff.php | 50 +++++++++++++++++++ .../Tests/PHP/DiscourageGotoUnitTest.inc | 18 +++++++ .../Tests/PHP/DiscourageGotoUnitTest.php | 46 +++++++++++++++++ 4 files changed, 124 insertions(+) create mode 100644 WordPress/Sniffs/PHP/DiscourageGotoSniff.php create mode 100644 WordPress/Tests/PHP/DiscourageGotoUnitTest.inc create mode 100644 WordPress/Tests/PHP/DiscourageGotoUnitTest.php diff --git a/WordPress-Extra/ruleset.xml b/WordPress-Extra/ruleset.xml index 98383709..f2f028d8 100644 --- a/WordPress-Extra/ruleset.xml +++ b/WordPress-Extra/ruleset.xml @@ -126,6 +126,16 @@ eval() is a security risk so not allowed. + + + + + error + The "goto" language construct should not be used. + + diff --git a/WordPress/Sniffs/PHP/DiscourageGotoSniff.php b/WordPress/Sniffs/PHP/DiscourageGotoSniff.php new file mode 100644 index 00000000..3e8f7e05 --- /dev/null +++ b/WordPress/Sniffs/PHP/DiscourageGotoSniff.php @@ -0,0 +1,50 @@ +phpcsFile->addWarning( 'Using the "goto" language construct is discouraged', $stackPtr, 'Found' ); + } + +}//end class diff --git a/WordPress/Tests/PHP/DiscourageGotoUnitTest.inc b/WordPress/Tests/PHP/DiscourageGotoUnitTest.inc new file mode 100644 index 00000000..f564215b --- /dev/null +++ b/WordPress/Tests/PHP/DiscourageGotoUnitTest.inc @@ -0,0 +1,18 @@ + => + */ + public function getErrorList() { + return array(); + } + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array( + 3 => 1, + 6 => 1, + 11 => 1, + 16 => 1, + ); + } + +} From 7ad699721b79de39a505ff8c8047fccbe88b4598 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 3 Sep 2017 17:32:50 +0200 Subject: [PATCH 201/282] Add some missing `@since` tags --- WordPress/Sniff.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index e5ecb507..2e89a388 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -2095,6 +2095,8 @@ public function get_function_call_parameter( $stackPtr, $param_offset ) { /** * Find the array opener & closer based on a T_ARRAY or T_OPEN_SHORT_ARRAY token. * + * @since 0.12.0 + * * @param int $stackPtr The stack pointer to the array token. * * @return array|bool Array with two keys `opener`, `closer` or false if @@ -2308,6 +2310,8 @@ public function is_class_constant( $stackPtr ) { /** * Check whether a T_VARIABLE token is a class property declaration. * + * @since 0.14.0 + * * @param int $stackPtr The position in the stack of the T_VARIABLE token to verify. * * @return bool From 109e4f3f125d82030f4c1e980665084fa41c69a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20=C5=BDoljom?= Date: Tue, 19 Sep 2017 23:47:41 +0200 Subject: [PATCH 202/282] Add customisable property to set the posts_per_page variable (#1152) --- WordPress/Sniffs/VIP/PostsPerPageSniff.php | 20 +++++++++++++++++--- WordPress/Tests/VIP/PostsPerPageUnitTest.inc | 12 ++++++++++++ WordPress/Tests/VIP/PostsPerPageUnitTest.php | 4 ++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/WordPress/Sniffs/VIP/PostsPerPageSniff.php b/WordPress/Sniffs/VIP/PostsPerPageSniff.php index d4f28adc..07692e8d 100644 --- a/WordPress/Sniffs/VIP/PostsPerPageSniff.php +++ b/WordPress/Sniffs/VIP/PostsPerPageSniff.php @@ -20,9 +20,21 @@ * * @since 0.3.0 * @since 0.13.0 Class name changed: this class is now namespaced. + * @since 0.14.0 Added the posts_per_page property. */ class PostsPerPageSniff extends AbstractArrayAssignmentRestrictionsSniff { + /** + * Posts per page property + * + * Posts per page limit to check against. + * + * @since 0.14.0 + * + * @var int + */ + public $posts_per_page = 100; + /** * Groups of variables to restrict. * @@ -53,18 +65,20 @@ public function getGroups() { * with custom error message passed to ->process(). */ public function callback( $key, $val, $line, $group ) { - $key = strtolower( $key ); + $key = strtolower( $key ); + $this->posts_per_page = (int) $this->posts_per_page; + if ( ( 'nopaging' === $key && ( 'true' === $val || 1 === $val ) ) || - ( in_array( $key, array( 'numberposts', 'posts_per_page' ), true ) && '-1' == $val ) + ( in_array( $key, array( 'numberposts', 'posts_per_page' ), true ) && '-1' === $val ) ) { return 'Disabling pagination is prohibited in VIP context, do not set `%s` to `%s` ever.'; } elseif ( in_array( $key, array( 'posts_per_page', 'numberposts' ), true ) ) { - if ( $val > 100 ) { + if ( $val > $this->posts_per_page ) { return 'Detected high pagination limit, `%s` is set to `%s`'; } } diff --git a/WordPress/Tests/VIP/PostsPerPageUnitTest.inc b/WordPress/Tests/VIP/PostsPerPageUnitTest.inc index 9fd7d8aa..75330d6e 100644 --- a/WordPress/Tests/VIP/PostsPerPageUnitTest.inc +++ b/WordPress/Tests/VIP/PostsPerPageUnitTest.inc @@ -16,3 +16,15 @@ $query_args['posts_per_page'] = '1'; // Ok. $query_args['posts_per_page'] = '-1'; // Bad. $query_args['my_posts_per_page'] = -1; // Ok. + +// @codingStandardsChangeSetting WordPress.VIP.PostsPerPage posts_per_page 50 + $query_args['posts_per_page'] = 50; // OK. + $query_args['posts_per_page'] = 100; // Bad. + $query_args['posts_per_page'] = 200; // Bad. + $query_args['posts_per_page'] = 300; // Bad. +// @codingStandardsChangeSetting WordPress.VIP.PostsPerPage posts_per_page 200 + $query_args['posts_per_page'] = 50; // OK. + $query_args['posts_per_page'] = 100; // OK. + $query_args['posts_per_page'] = 200; // OK. + $query_args['posts_per_page'] = 300; // Bad. +// @codingStandardsChangeSetting WordPress.VIP.PostsPerPage posts_per_page 100 diff --git a/WordPress/Tests/VIP/PostsPerPageUnitTest.php b/WordPress/Tests/VIP/PostsPerPageUnitTest.php index d4ad2544..00ad8420 100644 --- a/WordPress/Tests/VIP/PostsPerPageUnitTest.php +++ b/WordPress/Tests/VIP/PostsPerPageUnitTest.php @@ -34,6 +34,10 @@ public function getErrorList() { 11 => 2, 13 => 1, 16 => 1, + 22 => 1, + 23 => 1, + 24 => 1, + 29 => 1, ); } From 837b9d7d0e03acd29a0d6a6424e90b2e2ab13bdc Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 22 Sep 2017 19:53:56 +0200 Subject: [PATCH 203/282] Modern code/Extra: add sniff to check for single blank line after namespace declaration Related to 764 For now, I've added this as a separate section to `Extra`, but I'd like to use this to (re-)open the discussion on having separate standards which only deal with code style. Please add your voice to the discussions on this in 740 and 1067 --- WordPress-Extra/ruleset.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/WordPress-Extra/ruleset.xml b/WordPress-Extra/ruleset.xml index f2f028d8..c8b604d9 100644 --- a/WordPress-Extra/ruleset.xml +++ b/WordPress-Extra/ruleset.xml @@ -176,4 +176,13 @@ https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/919 --> + + + + +
      From dfebcba80706cb63a845e41cc06a161a604a9dd4 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 23 Sep 2017 01:07:28 +0200 Subject: [PATCH 204/282] CronInterval: make the minimum cron interval configurable This change allows for passing a minimum cron interval through a property in a custom ruleset. Includes unit tests. Includes one additional minor documentation fix for a previously added property. - [ ] Add info about the new property to the wiki --- WordPress/Sniffs/VIP/CronIntervalSniff.php | 29 ++++++++++- WordPress/Tests/VIP/CronIntervalUnitTest.inc | 52 +++++++++++++++++++- WordPress/Tests/VIP/CronIntervalUnitTest.php | 17 ++++--- 3 files changed, 87 insertions(+), 11 deletions(-) diff --git a/WordPress/Sniffs/VIP/CronIntervalSniff.php b/WordPress/Sniffs/VIP/CronIntervalSniff.php index aa6309fa..2d51a48e 100644 --- a/WordPress/Sniffs/VIP/CronIntervalSniff.php +++ b/WordPress/Sniffs/VIP/CronIntervalSniff.php @@ -23,12 +23,26 @@ * @since 0.11.0 - Extends the WordPress_Sniff class. * - Now deals correctly with WP time constants. * @since 0.13.0 Class name changed: this class is now namespaced. + * @since 0.14.0 The minimum cron interval tested against is now configurable. */ class CronIntervalSniff extends Sniff { + /** + * Minimum allowed cron interval in seconds. + * + * Defaults to 900 (= 15 minutes), which is the requirement for the VIP platform. + * + * @since 0.14.0 + * + * @var int + */ + public $min_interval = 900; + /** * Known WP Time constant names and their value. * + * @since 0.11.0 + * * @var array */ protected $wp_time_constants = array( @@ -168,8 +182,19 @@ public function process_token( $stackPtr ) { } } - if ( isset( $interval ) && $interval < 900 ) { - $this->phpcsFile->addError( 'Scheduling crons at %s sec ( less than 15 min ) is prohibited.', $stackPtr, 'CronSchedulesInterval', array( $interval ) ); + $this->min_interval = (int) $this->min_interval; + + if ( isset( $interval ) && $interval < $this->min_interval ) { + $minutes = round( ( $this->min_interval / 60 ), 1 ); + $this->phpcsFile->addError( + 'Scheduling crons at %s sec ( less than %s minutes ) is prohibited.', + $stackPtr, + 'CronSchedulesInterval', + array( + $interval, + $minutes, + ) + ); return; } diff --git a/WordPress/Tests/VIP/CronIntervalUnitTest.inc b/WordPress/Tests/VIP/CronIntervalUnitTest.inc index 3a4e44c1..aeae496a 100644 --- a/WordPress/Tests/VIP/CronIntervalUnitTest.inc +++ b/WordPress/Tests/VIP/CronIntervalUnitTest.inc @@ -13,11 +13,11 @@ add_filter( 'cron_schedules', 'my_add_weekly'); // Error: 6 min. class Foo { - function __construct() { + public function __construct() { add_filter( 'cron_schedules', array( $this, 'my_add_quickly' ) ); // Error: 10 min. } - function my_add_quickly( $schedules ) { + public function my_add_quickly( $schedules ) { $schedules['every_10_mins'] = array( 'interval' => 10 * 60, 'display' => __( 'Once every 10 minutes' ) @@ -80,3 +80,51 @@ add_filter( 'cron_schedules', function ( $schedules ) { ]; return $schedules; } ); // Warning: time undetermined. + +// @codingStandardsChangeSetting WordPress.VIP.CronInterval min_interval 600 +add_filter( 'cron_schedules', function ( $schedules ) { + $schedules['every_2_mins'] = array( + 'interval' => 2 * 60, + 'display' => __( 'Once every 2 minutes' ) + ); + return $schedules; +} ); // Error: 2 min. +add_filter( 'cron_schedules', function ( $schedules ) { + $schedules['every_10_mins'] = array( + 'interval' => 10 * 60, + 'display' => __( 'Once every 10 minutes' ) + ); + return $schedules; +} ); // OK: 10 min. +add_filter( 'cron_schedules', function ( $schedules ) { + $schedules['every_hour'] = [ + 'interval' => HOUR_IN_SECONDS, + 'display' => __( 'Once every hour' ) + ]; + return $schedules; +} ); // OK: > 10 min. + +// @codingStandardsChangeSetting WordPress.VIP.CronInterval min_interval 1800 +add_filter( 'cron_schedules', function ( $schedules ) { + $schedules['every_2_mins'] = array( + 'interval' => 2 * 60, + 'display' => __( 'Once every 2 minutes' ) + ); + return $schedules; +} ); // Error: 2 min. +add_filter( 'cron_schedules', function ( $schedules ) { + $schedules['every_15_mins'] = array( + 'interval' => 15 * 60, + 'display' => __( 'Once every 15 minutes' ) + ); + return $schedules; +} ); // Error: 15 min. +add_filter( 'cron_schedules', function ( $schedules ) { + $schedules['every_hour'] = [ + 'interval' => HOUR_IN_SECONDS, + 'display' => __( 'Once every hour' ) + ]; + return $schedules; +} ); // Ok: > 30 min. + +// @codingStandardsChangeSetting WordPress.VIP.CronInterval min_interval 900 diff --git a/WordPress/Tests/VIP/CronIntervalUnitTest.php b/WordPress/Tests/VIP/CronIntervalUnitTest.php index 63dd08bb..8b12122f 100644 --- a/WordPress/Tests/VIP/CronIntervalUnitTest.php +++ b/WordPress/Tests/VIP/CronIntervalUnitTest.php @@ -28,13 +28,16 @@ class CronIntervalUnitTest extends AbstractSniffUnitTest { */ public function getErrorList() { return array( - 12 => 1, - 17 => 1, - 37 => 1, - 43 => 1, - 53 => 1, - 56 => 1, // False positive. - 67 => 1, + 12 => 1, + 17 => 1, + 37 => 1, + 43 => 1, + 53 => 1, + 56 => 1, // False positive. + 67 => 1, + 85 => 1, + 108 => 1, + 115 => 1, ); } From 8592bc9feae97658097fbc466db69b3bf55b9636 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 23 Sep 2017 06:44:28 +0200 Subject: [PATCH 205/282] Move `is_wpdb_method_call()` method from PreparedSQL to WP base Sniff --- WordPress/Sniff.php | 55 ++++++++++++++++++++++++ WordPress/Sniffs/WP/PreparedSQLSniff.php | 54 ----------------------- 2 files changed, 55 insertions(+), 54 deletions(-) diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index 2e89a388..e1be9e60 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -2372,4 +2372,59 @@ protected function valid_direct_scope( $stackPtr, array $valid_scopes ) { return isset( $valid_scopes[ $this->tokens[ $ptr ]['type'] ] ); } + /** + * Checks whether this is a call to a $wpdb method that we want to sniff. + * + * The $i and $end properties are automatically set to correspond to the start + * and end of the method call. The $i property is also set if this is not a + * method call but rather the use of a $wpdb property. + * + * @since 0.8.0 + * @since 0.9.0 The return value is now always boolean. The $end and $i member + * vars are automatically updated. + * @since 0.14.0 Moved this method from the `PreparedSQL` sniff to the base WP sniff. + * + * @param int $stackPtr The index of the $wpdb variable. + * + * @return bool Whether this is a $wpdb method call. + */ + protected function is_wpdb_method_call( $stackPtr ) { + + // Check that this is a method call. + $is_object_call = $this->phpcsFile->findNext( T_OBJECT_OPERATOR, ( $stackPtr + 1 ), null, false, null, true ); + if ( false === $is_object_call ) { + return false; + } + + $methodPtr = $this->phpcsFile->findNext( array( T_WHITESPACE ), ( $is_object_call + 1 ), null, true, null, true ); + $method = $this->tokens[ $methodPtr ]['content']; + + // Find the opening parenthesis. + $opening_paren = $this->phpcsFile->findNext( T_WHITESPACE, ( $methodPtr + 1 ), null, true, null, true ); + + if ( false === $opening_paren ) { + return false; + } + + $this->i = $opening_paren; + + if ( T_OPEN_PARENTHESIS !== $this->tokens[ $opening_paren ]['code'] ) { + return false; + } + + // Check that this is one of the methods that we are interested in. + if ( ! isset( $this->methods[ $method ] ) ) { + return false; + } + + // Find the end of the first parameter. + $this->end = $this->phpcsFile->findEndOfStatement( $opening_paren + 1 ); + + if ( T_COMMA !== $this->tokens[ $this->end ]['code'] ) { + $this->end += 1; + } + + return true; + } // End is_wpdb_method_call(). + } diff --git a/WordPress/Sniffs/WP/PreparedSQLSniff.php b/WordPress/Sniffs/WP/PreparedSQLSniff.php index b695d29e..ebf25d0d 100644 --- a/WordPress/Sniffs/WP/PreparedSQLSniff.php +++ b/WordPress/Sniffs/WP/PreparedSQLSniff.php @@ -201,58 +201,4 @@ function ( $symbol ) { } // End process_token(). - /** - * Checks whether this is a call to a $wpdb method that we want to sniff. - * - * The $i and $end properties are automatically set to correspond to the start - * and end of the method call. The $i property is also set if this is not a - * method call but rather the use of a $wpdb property. - * - * @since 0.8.0 - * @since 0.9.0 The return value is now always boolean. The $end and $i member - * vars are automatically updated. - * - * @param int $stackPtr The index of the $wpdb variable. - * - * @return bool Whether this is a $wpdb method call. - */ - protected function is_wpdb_method_call( $stackPtr ) { - - // Check that this is a method call. - $is_object_call = $this->phpcsFile->findNext( T_OBJECT_OPERATOR, ( $stackPtr + 1 ), null, false, null, true ); - if ( false === $is_object_call ) { - return false; - } - - $methodPtr = $this->phpcsFile->findNext( array( T_WHITESPACE ), ( $is_object_call + 1 ), null, true, null, true ); - $method = $this->tokens[ $methodPtr ]['content']; - - // Find the opening parenthesis. - $opening_paren = $this->phpcsFile->findNext( T_WHITESPACE, ( $methodPtr + 1 ), null, true, null, true ); - - if ( false === $opening_paren ) { - return false; - } - - $this->i = $opening_paren; - - if ( T_OPEN_PARENTHESIS !== $this->tokens[ $opening_paren ]['code'] ) { - return false; - } - - // Check that this is one of the methods that we are interested in. - if ( ! isset( $this->methods[ $method ] ) ) { - return false; - } - - // Find the end of the first parameter. - $this->end = $this->phpcsFile->findEndOfStatement( $opening_paren + 1 ); - - if ( T_COMMA !== $this->tokens[ $this->end ]['code'] ) { - $this->end += 1; - } - - return true; - } // End is_wpdb_method_call(). - } // End class. From 7e00c82357a38694cd5532bef1b267d0c0ccd540 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 23 Sep 2017 07:05:10 +0200 Subject: [PATCH 206/282] Improve re-usability and stability of the `is_wpdb_method_call()` method. * Add recognition of static function calls using `::` operator. * Pass the methods to check for via a property to allow for child classes to be more flexible. * Only set the properties if such a property exists in the child class. * Don't sniff the method during live coding, i.e. when no close parenthesis is found yet. Includes unit tests. --- WordPress/Sniff.php | 60 +++++++++++++++++----- WordPress/Sniffs/WP/PreparedSQLSniff.php | 10 ++-- WordPress/Tests/WP/PreparedSQLUnitTest.inc | 5 ++ WordPress/Tests/WP/PreparedSQLUnitTest.php | 1 + 4 files changed, 55 insertions(+), 21 deletions(-) diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index e1be9e60..cccf0dee 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -2375,29 +2375,53 @@ protected function valid_direct_scope( $stackPtr, array $valid_scopes ) { /** * Checks whether this is a call to a $wpdb method that we want to sniff. * - * The $i and $end properties are automatically set to correspond to the start - * and end of the method call. The $i property is also set if this is not a - * method call but rather the use of a $wpdb property. + * If available in the child class, the $methodPtr, $i and $end properties are + * automatically set to correspond to the start and end of the method call. + * The $i property is also set if this is not a method call but rather the + * use of a $wpdb property. * * @since 0.8.0 * @since 0.9.0 The return value is now always boolean. The $end and $i member * vars are automatically updated. * @since 0.14.0 Moved this method from the `PreparedSQL` sniff to the base WP sniff. * - * @param int $stackPtr The index of the $wpdb variable. + * {@internal This method should probably be refactored.}} + * + * @param int $stackPtr The index of the $wpdb variable. + * @param array $target_methods Array of methods. Key(s) should be method name. * * @return bool Whether this is a $wpdb method call. */ - protected function is_wpdb_method_call( $stackPtr ) { + protected function is_wpdb_method_call( $stackPtr, $target_methods ) { + + // Check for wpdb. + if ( ( T_VARIABLE === $this->tokens[ $stackPtr ]['code'] && '$wpdb' !== $this->tokens[ $stackPtr ]['content'] ) + || ( T_STRING === $this->tokens[ $stackPtr ]['code'] && 'wpdb' !== $this->tokens[ $stackPtr ]['content'] ) + ) { + return false; + } // Check that this is a method call. - $is_object_call = $this->phpcsFile->findNext( T_OBJECT_OPERATOR, ( $stackPtr + 1 ), null, false, null, true ); + $is_object_call = $this->phpcsFile->findNext( + array( T_OBJECT_OPERATOR, T_DOUBLE_COLON ), + ( $stackPtr + 1 ), + null, + false, + null, + true + ); if ( false === $is_object_call ) { return false; } - $methodPtr = $this->phpcsFile->findNext( array( T_WHITESPACE ), ( $is_object_call + 1 ), null, true, null, true ); - $method = $this->tokens[ $methodPtr ]['content']; + $methodPtr = $this->phpcsFile->findNext( T_WHITESPACE, ( $is_object_call + 1 ), null, true, null, true ); + if ( false === $methodPtr ) { + return false; + } + + if ( T_STRING === $this->tokens[ $methodPtr ]['code'] && property_exists( $this, 'methodPtr' ) ) { + $this->methodPtr = $methodPtr; + } // Find the opening parenthesis. $opening_paren = $this->phpcsFile->findNext( T_WHITESPACE, ( $methodPtr + 1 ), null, true, null, true ); @@ -2406,22 +2430,30 @@ protected function is_wpdb_method_call( $stackPtr ) { return false; } - $this->i = $opening_paren; + if ( property_exists( $this, 'i' ) ) { + $this->i = $opening_paren; + } - if ( T_OPEN_PARENTHESIS !== $this->tokens[ $opening_paren ]['code'] ) { + if ( T_OPEN_PARENTHESIS !== $this->tokens[ $opening_paren ]['code'] + || ! isset( $this->tokens[ $opening_paren ]['parenthesis_closer'] ) + ) { return false; } // Check that this is one of the methods that we are interested in. - if ( ! isset( $this->methods[ $method ] ) ) { + if ( ! isset( $target_methods[ $this->tokens[ $methodPtr ]['content'] ] ) ) { return false; } // Find the end of the first parameter. - $this->end = $this->phpcsFile->findEndOfStatement( $opening_paren + 1 ); + $end = $this->phpcsFile->findEndOfStatement( $opening_paren + 1 ); + + if ( T_COMMA !== $this->tokens[ $end ]['code'] ) { + ++$end; + } - if ( T_COMMA !== $this->tokens[ $this->end ]['code'] ) { - $this->end += 1; + if ( property_exists( $this, 'end' ) ) { + $this->end = $end; } return true; diff --git a/WordPress/Sniffs/WP/PreparedSQLSniff.php b/WordPress/Sniffs/WP/PreparedSQLSniff.php index ebf25d0d..3a26151f 100644 --- a/WordPress/Sniffs/WP/PreparedSQLSniff.php +++ b/WordPress/Sniffs/WP/PreparedSQLSniff.php @@ -99,6 +99,7 @@ class PreparedSQLSniff extends Sniff { public function register() { return array( T_VARIABLE, + T_STRING, ); } @@ -114,12 +115,7 @@ public function register() { */ public function process_token( $stackPtr ) { - // Check for $wpdb variable. - if ( '$wpdb' !== $this->tokens[ $stackPtr ]['content'] ) { - return; - } - - if ( ! $this->is_wpdb_method_call( $stackPtr ) ) { + if ( ! $this->is_wpdb_method_call( $stackPtr, $this->methods ) ) { return; } @@ -160,7 +156,7 @@ function ( $symbol ) { if ( T_VARIABLE === $this->tokens[ $this->i ]['code'] ) { if ( '$wpdb' === $this->tokens[ $this->i ]['content'] ) { - $this->is_wpdb_method_call( $this->i ); + $this->is_wpdb_method_call( $this->i, $this->methods ); continue; } } diff --git a/WordPress/Tests/WP/PreparedSQLUnitTest.inc b/WordPress/Tests/WP/PreparedSQLUnitTest.inc index 6da97cf7..7550ca56 100644 --- a/WordPress/Tests/WP/PreparedSQLUnitTest.inc +++ b/WordPress/Tests/WP/PreparedSQLUnitTest.inc @@ -81,3 +81,8 @@ ND , $wpdb->postmeta, implode( ',', array_fill( 0, count( $post_ids ), '%d' ) ) ), $post_ids ) ); // OK. + +wpdb::prepare( "SELECT * FROM $wpdb->posts WHERE post_title LIKE '" . foo() . "';" ); // Bad. + +// Don't throw an error during live coding. +wpdb::prepare( "SELECT * FROM $wpdb->posts diff --git a/WordPress/Tests/WP/PreparedSQLUnitTest.php b/WordPress/Tests/WP/PreparedSQLUnitTest.php index bccc30f1..183b9df8 100644 --- a/WordPress/Tests/WP/PreparedSQLUnitTest.php +++ b/WordPress/Tests/WP/PreparedSQLUnitTest.php @@ -43,6 +43,7 @@ public function getErrorList() { 54 => 1, 64 => 1, 71 => 1, + 85 => 1, ); } From 5f5d52c9219872373106ac2394b1d581782a519c Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 23 Sep 2017 11:58:16 +0200 Subject: [PATCH 207/282] :sparkles: New `PreparedSQLPlaceholders` sniff WordPress 4.8.2 introduced a security fix which removed an undocumented, but well used feature in the `$wpdb->prepare()` method. Officially only the `%s`, `%d` and `%f` placeholders were supported. In reality, most forms of `sprintf()` type placeholders formats were supported before WP 4.8.2. See: https://core.trac.wordpress.org/changeset/41496 This already has caused havoc, breaking big plugins like Yoast SEO and WordFence. This new sniff will check that `$wpdb->prepare()` is used correctly by checking for the following issues: - Are only the following placeholders used ? %d, %f (%F) and %s. - Are literal % signs properly escaped ? - Are placeholders left unquoted in the query string ? (as they should be) - Is the correct number of replacement variables passed ? Includes unit tests. The sniff has been added to the `Extra` ruleset, though it could be argued that it should be added to `Core` as most of the above points are already [in the handbook](https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#formatting-sql-statements). Refs: * https://wordpress.org/news/2017/09/wordpress-4-8-2-security-and-maintenance-release/ * https://developer.wordpress.org/reference/classes/wpdb/prepare/ * https://github.com/Yoast/wordpress-seo/issues/7886 * https://wordpress.org/plugins/wordfence/#developers (see changelog for 6.3.19) * https://core.trac.wordpress.org/ticket/41925 --- WordPress-Extra/ruleset.xml | 3 + .../DB/PreparedSQLPlaceholdersSniff.php | 220 ++++++++++++++++++ .../DB/PreparedSQLPlaceholdersUnitTest.inc | 32 +++ .../DB/PreparedSQLPlaceholdersUnitTest.php | 58 +++++ 4 files changed, 313 insertions(+) create mode 100644 WordPress/Sniffs/DB/PreparedSQLPlaceholdersSniff.php create mode 100644 WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.inc create mode 100644 WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.php diff --git a/WordPress-Extra/ruleset.xml b/WordPress-Extra/ruleset.xml index c8b604d9..3cdad112 100644 --- a/WordPress-Extra/ruleset.xml +++ b/WordPress-Extra/ruleset.xml @@ -176,6 +176,9 @@ https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/919 --> + + + + + @@ -79,22 +81,4 @@ - - - - - - - - - - - - - - - - - -
      From 8289df750c5e86e07a60067971e7733ab51e2eeb Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 23 Sep 2017 14:20:16 +0200 Subject: [PATCH 209/282] Contributing: update info about unit testing Related to 1130 --- .github/CONTRIBUTING.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 06922ce1..58a2ea69 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -66,7 +66,7 @@ When you introduce a new whitelist comment, please don't forget to update the [w ## Pre-requisites * WordPress-Coding-Standards * PHP CodeSniffer 2.9.x or 3.x -* PHPUnit 4.x or 5.x +* PHPUnit 4.x, 5.x or 6.x The WordPress Coding Standards use the PHP CodeSniffer native unit test suite for unit testing the sniffs. @@ -89,6 +89,7 @@ The easiest way to do this is to add a `phpunit.xml` file to the root of your WP ```xml @@ -121,13 +122,13 @@ PHPUnit 4.8.19 by Sebastian Bergmann and contributors. Runtime: PHP 7.1.3 with Xdebug 2.5.1 Configuration: /WordPressCS/phpunit.xml -...................................................... +.......................................................... -Tests generated 558 unique error codes; 48 were fixable (8.6%) +Tests generated 556 unique error codes; 48 were fixable (8.63%) -Time: 12.25 seconds, Memory: 24.00Mb +Time: 24.08 seconds, Memory: 41.75Mb -OK (54 tests, 0 assertions) +OK (58 tests, 0 assertions) ``` [![asciicast](https://asciinema.org/a/98078.png)](https://asciinema.org/a/98078) From b4e2abea1e9806d292d23ae914e6b03a03695942 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 23 Sep 2017 14:52:58 +0200 Subject: [PATCH 210/282] Move the `WordPress.DB.PreparedSQLPlaceholders` from `Extra` to `Core` --- WordPress-Core/ruleset.xml | 4 ++-- WordPress-Extra/ruleset.xml | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index 58dc9bd6..94004d8d 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -222,8 +222,8 @@ SQL slash escaping when passed. https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/640 --> - + + diff --git a/WordPress-Extra/ruleset.xml b/WordPress-Extra/ruleset.xml index 3cdad112..249a487c 100644 --- a/WordPress-Extra/ruleset.xml +++ b/WordPress-Extra/ruleset.xml @@ -176,8 +176,6 @@ https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/919 --> - - + + + + + error + The "goto" language construct should not be used. + + + + + + error + eval() is a security risk so not allowed. + + - - - - error - The "goto" language construct should not be used. - - From 1979d234c5361e03b0cca1b402526e185d16debe Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 6 Oct 2017 10:39:48 +0200 Subject: [PATCH 218/282] ArrayIndentation: deal correctly with trailing comments If a previous array item has a trailing comment, the sniff would bow out as it would defer to the ArrayDeclarationSpacing sniff to fix a multi-line array where items are not all on their own line first. However, in the case of a trailing comment and the next array item in actual fact starting on its own line, the ArrayDeclarationSpacing sniff would (correctly) not kick in and the indentation error for the item would never be addressed. This fixes that. Includes unit tests. N.B.: Verified & confirmed that the ArrayDeclaration sniff already handled this situation correctly. Fixes 1179 --- WordPress/Sniffs/Arrays/ArrayIndentationSniff.php | 13 +++++++++++++ .../Tests/Arrays/ArrayIndentationUnitTest.1.inc | 8 ++++++++ .../Arrays/ArrayIndentationUnitTest.1.inc.fixed | 8 ++++++++ .../Tests/Arrays/ArrayIndentationUnitTest.2.inc | 8 ++++++++ .../Arrays/ArrayIndentationUnitTest.2.inc.fixed | 8 ++++++++ WordPress/Tests/Arrays/ArrayIndentationUnitTest.php | 2 ++ 6 files changed, 47 insertions(+) diff --git a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php index 8262db0c..c62e2ff1 100644 --- a/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php +++ b/WordPress/Sniffs/Arrays/ArrayIndentationSniff.php @@ -179,6 +179,19 @@ public function process_token( $stackPtr ) { true ); + // Deal with trailing comments. + if ( false !== $first_content + && T_COMMENT === $this->tokens[ $first_content ]['code'] + && $this->tokens[ $first_content ]['line'] === $this->tokens[ $end_of_previous_item ]['line'] + ) { + $first_content = $this->phpcsFile->findNext( + array( T_WHITESPACE, T_DOC_COMMENT_WHITESPACE ), + ( $first_content + 1 ), + $end_of_this_item, + true + ); + } + if ( false === $first_content ) { $end_of_previous_item = $end_of_this_item; continue; diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc index 8f815788..eb870c31 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc @@ -391,3 +391,11 @@ else { '

      The code snippet is simplified for brevity. Please refer to the source of this file on GitHub for full details on how to use filter_var_array().

      ', ), ); + +// Issue #1179. +b( + array( + 1 => false, // wat + 2 => false, + ) +); diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc.fixed b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc.fixed index 814c2a0f..6a78a1a1 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc.fixed +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.1.inc.fixed @@ -391,3 +391,11 @@ else { '

      The code snippet is simplified for brevity. Please refer to the source of this file on GitHub for full details on how to use filter_var_array().

      ', ), ); + +// Issue #1179. +b( + array( + 1 => false, // wat + 2 => false, + ) +); diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc index b058eef3..faf10b74 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc @@ -392,4 +392,12 @@ else { ), ); +// Issue #1179. +b( + [ + 1 => false, // wat + 2 => false, + ] +); + // @codingStandardsChangeSetting WordPress.Arrays.ArrayIndentation tabIndent true diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc.fixed b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc.fixed index 3864ee63..4335fc39 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc.fixed +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.2.inc.fixed @@ -392,4 +392,12 @@ else { ), ); +// Issue #1179. +b( + [ + 1 => false, // wat + 2 => false, + ] +); + // @codingStandardsChangeSetting WordPress.Arrays.ArrayIndentation tabIndent true diff --git a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php index b048c4b0..b13a53fc 100644 --- a/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php +++ b/WordPress/Tests/Arrays/ArrayIndentationUnitTest.php @@ -162,6 +162,8 @@ public function getErrorList() { 347 => 1, 356 => 1, 369 => 1, + 398 => 1, + 399 => 1, ); } From ed5238a6e6097139ea86d39920fda4b45e7e622e Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 6 Oct 2017 03:23:51 +0200 Subject: [PATCH 219/282] :sparkles: New RestrictedPHPFunctions sniff The following has been added to the handbook: > create_function() function, which internally performs an eval(), is deprecated in PHP 7.2. Both of these must not be used. https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#clever-code `create_function` was already discouraged in `Extra` via the `WordPress.PHP.DiscouragedPHPFunctions` sniff. As it is now forbidden for Core, this check has been moved a new `WordPress.PHP.RestrictedPHPFunctions` sniff and added to the `Core` ruleset. --- WordPress-Core/ruleset.xml | 4 ++ .../PHP/DiscouragedPHPFunctionsSniff.php | 9 +--- .../PHP/RestrictedPHPFunctionsSniff.php | 49 +++++++++++++++++++ .../PHP/DiscouragedPHPFunctionsUnitTest.inc | 6 +-- .../PHP/DiscouragedPHPFunctionsUnitTest.php | 1 - .../PHP/RestrictedPHPFunctionsUnitTest.inc | 5 ++ .../PHP/RestrictedPHPFunctionsUnitTest.php | 44 +++++++++++++++++ 7 files changed, 106 insertions(+), 12 deletions(-) create mode 100644 WordPress/Sniffs/PHP/RestrictedPHPFunctionsSniff.php create mode 100644 WordPress/Tests/PHP/RestrictedPHPFunctionsUnitTest.inc create mode 100644 WordPress/Tests/PHP/RestrictedPHPFunctionsUnitTest.php diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index 828001e5..79c606b0 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -348,6 +348,10 @@ eval() is a security risk so not allowed.
      + + + - - - - + diff --git a/WordPress/ruleset.xml b/WordPress/ruleset.xml index c4db9597..5acf9334 100644 --- a/WordPress/ruleset.xml +++ b/WordPress/ruleset.xml @@ -10,10 +10,9 @@ - - +
      From 2676dd4d7ad05b35275831290c1e8fb7d0b39400 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 6 Oct 2017 15:46:19 +0200 Subject: [PATCH 221/282] VIP ruleset: remove the explicit inclusion of two sniffs which are also in `Core` As the whole `Core` ruleset is included in `VIP`, there is no need for these sniffs to be included twice. --- WordPress-VIP/ruleset.xml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/WordPress-VIP/ruleset.xml b/WordPress-VIP/ruleset.xml index 33b75e58..9035e489 100644 --- a/WordPress-VIP/ruleset.xml +++ b/WordPress-VIP/ruleset.xml @@ -31,9 +31,6 @@ - - - @@ -41,13 +38,6 @@ - - - - error - eval() is a security risk so not allowed. - - From d7e51578dc66ff60004fd5cfbd6574ad01ef5610 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 6 Oct 2017 16:56:36 +0200 Subject: [PATCH 222/282] Sync the WP global var lists The WP base `Sniff` class contains a list of WP global variables which is used by two sniffs. The `ValidVariableName` sniff contains a secondary list of globals which don't the WP variable name guidelines. I've done a quick compare and found some differences between the lists which needed to be fixed. It would be nice to build up the mixed_case_vars list dynamically, but unfortunately, as the `ValidVariableName` sniff extends an upstream sniff rather than the WP `Sniff`, this is currently not an option. --- WordPress/Sniff.php | 1 + .../ValidVariableNameSniff.php | 17 ++++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index cccf0dee..864adb3d 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -647,6 +647,7 @@ abstract class Sniff implements PHPCS_Sniff { 'is_IIS' => true, 'is_iis7' => true, 'is_macIE' => true, + 'is_NS4' => true, 'is_opera' => true, 'is_safari' => true, 'is_winIE' => true, diff --git a/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php b/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php index 3a10912b..ea027576 100644 --- a/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php +++ b/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php @@ -59,13 +59,16 @@ class ValidVariableNameSniff extends PHPCS_AbstractVariableSniff { * @var array */ protected $wordpress_mixed_case_vars = array( - 'EZSQL_ERROR' => true, - 'is_IE' => true, - 'is_IIS' => true, - 'is_macIE' => true, - 'is_NS4' => true, - 'is_winIE' => true, - 'PHP_SELF' => true, + 'EZSQL_ERROR' => true, + 'GETID3_ERRORARRAY' => true, + 'is_IE' => true, + 'is_IIS' => true, + 'is_macIE' => true, + 'is_NS4' => true, + 'is_winIE' => true, + 'PHP_SELF' => true, + 'post_ID' => true, + 'user_ID' => true, ); /** From a8f782ce1238cca351e35daa41fb2f45d3686222 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 6 Oct 2017 19:29:20 +0200 Subject: [PATCH 223/282] YodaConditions: fix issue 1181 - complex ternary This is a quick fix which seems to work well (see the unit tests), but more unit tests are welcome. Fixes 1181 --- WordPress/Sniffs/PHP/YodaConditionsSniff.php | 2 ++ WordPress/Tests/PHP/YodaConditionsUnitTest.inc | 9 +++++++++ WordPress/Tests/PHP/YodaConditionsUnitTest.php | 1 + 3 files changed, 12 insertions(+) diff --git a/WordPress/Sniffs/PHP/YodaConditionsSniff.php b/WordPress/Sniffs/PHP/YodaConditionsSniff.php index 6da38d9a..203df5e9 100644 --- a/WordPress/Sniffs/PHP/YodaConditionsSniff.php +++ b/WordPress/Sniffs/PHP/YodaConditionsSniff.php @@ -45,6 +45,8 @@ public function register() { $starters += Tokens::$assignmentTokens; $starters[ T_CASE ] = T_CASE; $starters[ T_RETURN ] = T_RETURN; + $starters[ T_INLINE_THEN ] = T_INLINE_THEN; + $starters[ T_INLINE_ELSE ] = T_INLINE_ELSE; $starters[ T_SEMICOLON ] = T_SEMICOLON; $starters[ T_OPEN_PARENTHESIS ] = T_OPEN_PARENTHESIS; diff --git a/WordPress/Tests/PHP/YodaConditionsUnitTest.inc b/WordPress/Tests/PHP/YodaConditionsUnitTest.inc index 86015042..53b31fbc 100644 --- a/WordPress/Tests/PHP/YodaConditionsUnitTest.inc +++ b/WordPress/Tests/PHP/YodaConditionsUnitTest.inc @@ -126,3 +126,12 @@ while ( $sample === false ) {} // Bad. while ( false != $sample ) {} // OK. $a = ( $sample ) === 'yes'; // OK. + +// Issue #1181 +function is_windows() { + return false !== ( $test_is_windows = getenv( 'WP_CLI_TEST_IS_WINDOWS' ) ) ? (bool) $test_is_windows : 0 === stripos( PHP_OS, 'WIN' ); // OK. +} + +if ( $something == ( false !== ( $test_is_windows = getenv( 'WP_CLI_TEST_IS_WINDOWS' ) ) ? (bool) $test_is_windows : 0 === stripos( PHP_OS, 'WIN' ) ) ) {} // Bad. + +if ( ( false !== ( $test_is_windows = getenv( 'WP_CLI_TEST_IS_WINDOWS' ) ) ? (bool) $test_is_windows : 0 === stripos( PHP_OS, 'WIN' ) ) === $something ) {} // OK. diff --git a/WordPress/Tests/PHP/YodaConditionsUnitTest.php b/WordPress/Tests/PHP/YodaConditionsUnitTest.php index ecdb6243..63f4a6ee 100644 --- a/WordPress/Tests/PHP/YodaConditionsUnitTest.php +++ b/WordPress/Tests/PHP/YodaConditionsUnitTest.php @@ -45,6 +45,7 @@ public function getErrorList() { 114 => 1, 119 => 1, 125 => 1, + 135 => 1, ); } From c58723da4d038dee91c2923f6f6eebb54ad3f6f6 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 7 Sep 2017 22:18:38 +0200 Subject: [PATCH 224/282] :sparkles: Add new Arrays.MultipleStatementAlignment sniff to `Core` This new sniff enforces alignment of the double arrow assignment operator to the same column for each item in a multi-item, multi-line array. For single line arrays it forces the space between the index key and the double arrow to be exactly one space. The sniff has three public properties which can be set from a ruleset: - `ignoreNewline`: Set to allow new line(s) between the item key and the double arrow. Defaults to `true`. When set to true, the item will be ignored completely when a new line is encountered between the item key and the double arrow. - `exact`: Whether the alignment has to be exactly 1 space from the end of the widest index. Defaults to `true`. When set to `false`, the largest index key + 1 space is taken as a minimum and if a predominant number of items is already alignment at a position which is more than the minimum, this predominant alignment position is taken as the preferred alignment. This allows for cleaner diffs as the array does not have to be realigned when the largest key is taken out. - `maxColumn`: The maximum column at which the double arrow can be placed. Defaults to `1000`. This property has been added to aid in managing line-length. Includes extensive unit tests. Fixes 1122 --- WordPress-Core/ruleset.xml | 7 + .../MultipleStatementAlignmentSniff.php | 433 ++++++++++++++++++ .../MultipleStatementAlignmentUnitTest.1.inc | 294 ++++++++++++ ...ipleStatementAlignmentUnitTest.1.inc.fixed | 280 +++++++++++ .../MultipleStatementAlignmentUnitTest.2.inc | 294 ++++++++++++ ...ipleStatementAlignmentUnitTest.2.inc.fixed | 280 +++++++++++ .../MultipleStatementAlignmentUnitTest.php | 152 ++++++ 7 files changed, 1740 insertions(+) create mode 100644 WordPress/Sniffs/Arrays/MultipleStatementAlignmentSniff.php create mode 100644 WordPress/Tests/Arrays/MultipleStatementAlignmentUnitTest.1.inc create mode 100644 WordPress/Tests/Arrays/MultipleStatementAlignmentUnitTest.1.inc.fixed create mode 100644 WordPress/Tests/Arrays/MultipleStatementAlignmentUnitTest.2.inc create mode 100644 WordPress/Tests/Arrays/MultipleStatementAlignmentUnitTest.2.inc.fixed create mode 100644 WordPress/Tests/Arrays/MultipleStatementAlignmentUnitTest.php diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index 79c606b0..52cce7d4 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -68,6 +68,13 @@ + + + + + + + + + + + + + From c1b7af15a43cbe7e9915be03a14d17d4ecb75a83 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Mon, 25 Sep 2017 03:01:59 +0200 Subject: [PATCH 228/282] Fix existing codebase for warnings thrown by the new `Arrays.MultipleStatementAlignment` sniff --- WordPress/Sniff.php | 22 ++--- .../Sniffs/DB/RestrictedClassesSniff.php | 4 +- .../Sniffs/VIP/DirectDatabaseQuerySniff.php | 14 +-- .../Sniffs/VIP/RestrictedFunctionsSniff.php | 2 +- WordPress/Sniffs/WP/I18nSniff.php | 2 +- .../ArrayAssignmentRestrictionsUnitTest.php | 6 +- .../ArrayDeclarationSpacingUnitTest.php | 48 +++++----- .../ArrayKeySpacingRestrictionsUnitTest.php | 6 +- .../Tests/DB/RestrictedClassesUnitTest.php | 4 +- WordPress/Tests/Files/FileNameUnitTest.php | 32 +++---- .../Tests/Functions/DontExtractUnitTest.php | 2 +- .../PrefixAllGlobalsUnitTest.php | 2 +- .../ValidFunctionNameUnitTest.php | 4 +- .../ValidHookNameUnitTest.php | 4 +- .../PHP/DevelopmentFunctionsUnitTest.php | 14 +-- WordPress/Tests/PHP/StrictInArrayUnitTest.php | 6 +- .../Tests/PHP/YodaConditionsUnitTest.php | 26 ++--- WordPress/Tests/VIP/PostsPerPageUnitTest.php | 2 +- .../VIP/SuperGlobalInputUsageUnitTest.php | 2 +- .../Tests/VIP/TimezoneChangeUnitTest.php | 2 +- .../VIP/ValidatedSanitizedInputUnitTest.php | 28 +++--- .../VariableRestrictionsUnitTest.php | 4 +- .../Tests/WP/EnqueuedResourcesUnitTest.php | 8 +- WordPress/Tests/WP/I18nUnitTest.php | 96 +++++++++---------- WordPress/Tests/WP/PreparedSQLUnitTest.php | 10 +- .../ControlStructureSpacingUnitTest.php | 44 ++++----- WordPress/Tests/XSS/EscapeOutputUnitTest.php | 32 +++---- 27 files changed, 213 insertions(+), 213 deletions(-) diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index 864adb3d..0ecd8984 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -500,18 +500,18 @@ abstract class Sniff implements PHPCS_Sniff { * @var array */ protected $cacheDeleteFunctions = array( - 'wp_cache_delete' => true, - 'clean_attachment_cache' => true, - 'clean_blog_cache' => true, - 'clean_bookmark_cache' => true, - 'clean_category_cache' => true, - 'clean_comment_cache' => true, - 'clean_network_cache' => true, + 'wp_cache_delete' => true, + 'clean_attachment_cache' => true, + 'clean_blog_cache' => true, + 'clean_bookmark_cache' => true, + 'clean_category_cache' => true, + 'clean_comment_cache' => true, + 'clean_network_cache' => true, 'clean_object_term_cache' => true, - 'clean_page_cache' => true, - 'clean_post_cache' => true, - 'clean_term_cache' => true, - 'clean_user_cache' => true, + 'clean_page_cache' => true, + 'clean_post_cache' => true, + 'clean_term_cache' => true, + 'clean_user_cache' => true, ); /** diff --git a/WordPress/Sniffs/DB/RestrictedClassesSniff.php b/WordPress/Sniffs/DB/RestrictedClassesSniff.php index 1083c86c..8da5672e 100644 --- a/WordPress/Sniffs/DB/RestrictedClassesSniff.php +++ b/WordPress/Sniffs/DB/RestrictedClassesSniff.php @@ -45,8 +45,8 @@ public function getGroups() { return array( 'mysql' => array( - 'type' => 'error', - 'message' => 'Accessing the database directly should be avoided. Please use the $wpdb object and associated functions instead. Found: %s.', + 'type' => 'error', + 'message' => 'Accessing the database directly should be avoided. Please use the $wpdb object and associated functions instead. Found: %s.', 'classes' => array( 'mysqli', 'PDO', diff --git a/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php b/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php index d3b095dc..69aa8c0b 100644 --- a/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php +++ b/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php @@ -79,14 +79,14 @@ class DirectDatabaseQuerySniff extends Sniff { */ protected $methods = array( 'cachable' => array( - 'delete' => true, - 'get_var' => true, - 'get_col' => true, - 'get_row' => true, + 'delete' => true, + 'get_var' => true, + 'get_col' => true, + 'get_row' => true, 'get_results' => true, - 'query' => true, - 'replace' => true, - 'update' => true, + 'query' => true, + 'replace' => true, + 'update' => true, ), 'noncachable' => array( 'insert' => true, diff --git a/WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php b/WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php index c1b768b1..53309855 100644 --- a/WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php +++ b/WordPress/Sniffs/VIP/RestrictedFunctionsSniff.php @@ -216,7 +216,7 @@ public function getGroups() { // @link https://vip.wordpress.com/documentation/vip/code-review-what-we-look-for/#use-wp_safe_redirect-instead-of-wp_redirect 'wp_redirect' => array( - 'type' => 'warning', + 'type' => 'warning', 'message' => '%s() found. Using wp_safe_redirect(), along with the allowed_redirect_hosts filter, can help avoid any chances of malicious redirects within code. It is also important to remember to call exit() after a redirect so that no other unwanted code is executed.', 'functions' => array( 'wp_redirect', diff --git a/WordPress/Sniffs/WP/I18nSniff.php b/WordPress/Sniffs/WP/I18nSniff.php index 8fe92e1f..4819d43a 100644 --- a/WordPress/Sniffs/WP/I18nSniff.php +++ b/WordPress/Sniffs/WP/I18nSniff.php @@ -279,7 +279,7 @@ public function process_token( $stack_ptr ) { ); $argument_assertions[] = array( 'arg_name' => 'plural', - 'tokens' => array_shift( $arguments_tokens ), + 'tokens' => array_shift( $arguments_tokens ), ); $argument_assertions[] = array( 'arg_name' => 'domain', diff --git a/WordPress/Tests/Arrays/ArrayAssignmentRestrictionsUnitTest.php b/WordPress/Tests/Arrays/ArrayAssignmentRestrictionsUnitTest.php index 865ca313..0cd720fd 100644 --- a/WordPress/Tests/Arrays/ArrayAssignmentRestrictionsUnitTest.php +++ b/WordPress/Tests/Arrays/ArrayAssignmentRestrictionsUnitTest.php @@ -55,9 +55,9 @@ protected function tearDown() { */ public function getErrorList() { return array( - 3 => 1, - 5 => 1, - 7 => 2, + 3 => 1, + 5 => 1, + 7 => 2, 20 => 1, ); diff --git a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php index d5efbb9b..4ee95461 100644 --- a/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php +++ b/WordPress/Tests/Arrays/ArrayDeclarationSpacingUnitTest.php @@ -67,30 +67,30 @@ public function getErrorList( $testFile = '' ) { // Short arrays. case 'ArrayDeclarationSpacingUnitTest.2.inc': return array( - 8 => 2, - 11 => 2, - 16 => 4, - 20 => 2, - 22 => 1, - 26 => 1, - 29 => 1, - 32 => 1, - 45 => 1, - 46 => 1, - 47 => 1, - 67 => 1, - 68 => 1, - 71 => 1, - 72 => 2, - 75 => 3, - 77 => 1, - 80 => 1, - 81 => 2, - 84 => 1, - 86 => 2, - 87 => 2, - 91 => 1, - 92 => 1, + 8 => 2, + 11 => 2, + 16 => 4, + 20 => 2, + 22 => 1, + 26 => 1, + 29 => 1, + 32 => 1, + 45 => 1, + 46 => 1, + 47 => 1, + 67 => 1, + 68 => 1, + 71 => 1, + 72 => 2, + 75 => 3, + 77 => 1, + 80 => 1, + 81 => 2, + 84 => 1, + 86 => 2, + 87 => 2, + 91 => 1, + 92 => 1, ); default: diff --git a/WordPress/Tests/Arrays/ArrayKeySpacingRestrictionsUnitTest.php b/WordPress/Tests/Arrays/ArrayKeySpacingRestrictionsUnitTest.php index 49b2ebdc..bc2e3ba9 100644 --- a/WordPress/Tests/Arrays/ArrayKeySpacingRestrictionsUnitTest.php +++ b/WordPress/Tests/Arrays/ArrayKeySpacingRestrictionsUnitTest.php @@ -28,9 +28,9 @@ class ArrayKeySpacingRestrictionsUnitTest extends AbstractSniffUnitTest { */ public function getErrorList() { return array( - 4 => 1, - 5 => 1, - 6 => 1, + 4 => 1, + 5 => 1, + 6 => 1, 11 => 1, 12 => 1, 13 => 1, diff --git a/WordPress/Tests/DB/RestrictedClassesUnitTest.php b/WordPress/Tests/DB/RestrictedClassesUnitTest.php index 4bf68b6c..ed839781 100644 --- a/WordPress/Tests/DB/RestrictedClassesUnitTest.php +++ b/WordPress/Tests/DB/RestrictedClassesUnitTest.php @@ -34,8 +34,8 @@ protected function setUp() { AbstractFunctionRestrictionsSniff::$unittest_groups = array( 'test' => array( - 'type' => 'error', - 'message' => 'Detected usage of %s.', + 'type' => 'error', + 'message' => 'Detected usage of %s.', 'classes' => array( '\My\DBlayer', 'AdoDb\Test*', diff --git a/WordPress/Tests/Files/FileNameUnitTest.php b/WordPress/Tests/Files/FileNameUnitTest.php index 85a1f87a..d5a65940 100644 --- a/WordPress/Tests/Files/FileNameUnitTest.php +++ b/WordPress/Tests/Files/FileNameUnitTest.php @@ -34,14 +34,14 @@ class FileNameUnitTest extends AbstractSniffUnitTest { */ // File names generic. - 'some_file.inc' => 1, - 'SomeFile.inc' => 1, - 'some-File.inc' => 1, + 'some_file.inc' => 1, + 'SomeFile.inc' => 1, + 'some-File.inc' => 1, // Class file names. - 'my-class.inc' => 1, - 'class-different-class.inc' => 1, - 'ClassMyClass.inc' => 2, + 'my-class.inc' => 1, + 'class-different-class.inc' => 1, + 'ClassMyClass.inc' => 2, // Theme specific exceptions in a non-theme context. 'single-my_post_type.inc' => 1, @@ -52,38 +52,38 @@ class FileNameUnitTest extends AbstractSniffUnitTest { */ // Non-strict class names still have to comply with lowercase hyphenated. - 'ClassNonStrictClass.inc' => 1, + 'ClassNonStrictClass.inc' => 1, /* * In /FileNameUnitTests/TestFiles. */ - 'test-sample-phpunit.inc' => 0, - 'test-sample-phpunit6.inc' => 0, - 'test-sample-wpunit.inc' => 0, - 'test-sample-custom-unit.inc' => 0, + 'test-sample-phpunit.inc' => 0, + 'test-sample-phpunit6.inc' => 0, + 'test-sample-wpunit.inc' => 0, + 'test-sample-custom-unit.inc' => 0, /* * In /FileNameUnitTests/ThemeExceptions. */ // Files in a theme context. - 'front_page.inc' => 1, - 'FrontPage.inc' => 1, - 'author-nice_name.inc' => 1, + 'front_page.inc' => 1, + 'FrontPage.inc' => 1, + 'author-nice_name.inc' => 1, /* * In /FileNameUnitTests/wp-includes. */ // Files containing template tags. - 'general.inc' => 1, + 'general.inc' => 1, /* * In /. */ // Fall-back file in case glob() fails. - 'FileNameUnitTest.inc' => 1, + 'FileNameUnitTest.inc' => 1, ); /** diff --git a/WordPress/Tests/Functions/DontExtractUnitTest.php b/WordPress/Tests/Functions/DontExtractUnitTest.php index 10a490c2..081e794b 100644 --- a/WordPress/Tests/Functions/DontExtractUnitTest.php +++ b/WordPress/Tests/Functions/DontExtractUnitTest.php @@ -28,7 +28,7 @@ class DontExtractUnitTest extends AbstractSniffUnitTest { */ public function getErrorList() { return array( - 3 => 1, + 3 => 1, ); } diff --git a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php index d23bc645..00798e48 100644 --- a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php +++ b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.php @@ -57,7 +57,7 @@ public function getErrorList( $testFile = 'PrefixAllGlobalsUnitTest.inc' ) { 230 => ( function_exists( '\array_column' ) ) ? 0 : 1, 234 => ( defined( '\E_DEPRECATED' ) ) ? 0 : 1, 238 => ( class_exists( '\IntlTimeZone' ) ) ? 0 : 1, - 318 => 1, + 318 => 1, ); case 'PrefixAllGlobalsUnitTest.1.inc': diff --git a/WordPress/Tests/NamingConventions/ValidFunctionNameUnitTest.php b/WordPress/Tests/NamingConventions/ValidFunctionNameUnitTest.php index 5a2e7e54..223f7b3c 100644 --- a/WordPress/Tests/NamingConventions/ValidFunctionNameUnitTest.php +++ b/WordPress/Tests/NamingConventions/ValidFunctionNameUnitTest.php @@ -28,8 +28,8 @@ class ValidFunctionNameUnitTest extends AbstractSniffUnitTest { */ public function getErrorList() { return array( - 3 => 1, - 9 => 1, + 3 => 1, + 9 => 1, 13 => 1, 15 => 1, 79 => 1, diff --git a/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.php b/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.php index 72278e95..a605b898 100644 --- a/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.php +++ b/WordPress/Tests/NamingConventions/ValidHookNameUnitTest.php @@ -90,8 +90,8 @@ public function getWarningList( $testFile = 'ValidHookNameUnitTest.inc' ) { switch ( $testFile ) { case 'ValidHookNameUnitTest.inc': return array( - 8 => 1, - 9 => 1, + 8 => 1, + 9 => 1, 10 => 1, 11 => 1, 68 => 1, diff --git a/WordPress/Tests/PHP/DevelopmentFunctionsUnitTest.php b/WordPress/Tests/PHP/DevelopmentFunctionsUnitTest.php index 842daa2e..bb448c77 100644 --- a/WordPress/Tests/PHP/DevelopmentFunctionsUnitTest.php +++ b/WordPress/Tests/PHP/DevelopmentFunctionsUnitTest.php @@ -38,13 +38,13 @@ public function getErrorList() { */ public function getWarningList() { return array( - 3 => 1, - 4 => 1, - 5 => 1, - 6 => 1, - 7 => 1, - 8 => 1, - 9 => 1, + 3 => 1, + 4 => 1, + 5 => 1, + 6 => 1, + 7 => 1, + 8 => 1, + 9 => 1, 10 => 1, 11 => 1, 13 => 1, diff --git a/WordPress/Tests/PHP/StrictInArrayUnitTest.php b/WordPress/Tests/PHP/StrictInArrayUnitTest.php index 96184760..cf9efce3 100644 --- a/WordPress/Tests/PHP/StrictInArrayUnitTest.php +++ b/WordPress/Tests/PHP/StrictInArrayUnitTest.php @@ -39,9 +39,9 @@ public function getErrorList() { */ public function getWarningList() { return array( - 5 => 1, - 6 => 1, - 7 => 1, + 5 => 1, + 6 => 1, + 7 => 1, 23 => 1, 24 => 1, 25 => 1, diff --git a/WordPress/Tests/PHP/YodaConditionsUnitTest.php b/WordPress/Tests/PHP/YodaConditionsUnitTest.php index ecdb6243..9d5189f5 100644 --- a/WordPress/Tests/PHP/YodaConditionsUnitTest.php +++ b/WordPress/Tests/PHP/YodaConditionsUnitTest.php @@ -28,19 +28,19 @@ class YodaConditionsUnitTest extends AbstractSniffUnitTest { */ public function getErrorList() { return array( - 2 => 2, - 4 => 2, - 11 => 1, - 18 => 1, - 25 => 1, - 32 => 1, - 49 => 1, - 55 => 1, - 62 => 1, - 68 => 1, - 84 => 1, - 88 => 1, - 90 => 1, + 2 => 2, + 4 => 2, + 11 => 1, + 18 => 1, + 25 => 1, + 32 => 1, + 49 => 1, + 55 => 1, + 62 => 1, + 68 => 1, + 84 => 1, + 88 => 1, + 90 => 1, 105 => 1, 114 => 1, 119 => 1, diff --git a/WordPress/Tests/VIP/PostsPerPageUnitTest.php b/WordPress/Tests/VIP/PostsPerPageUnitTest.php index 00ad8420..7b38b81e 100644 --- a/WordPress/Tests/VIP/PostsPerPageUnitTest.php +++ b/WordPress/Tests/VIP/PostsPerPageUnitTest.php @@ -31,7 +31,7 @@ public function getErrorList() { 4 => 1, 5 => 1, 6 => 1, - 11 => 2, + 11 => 2, 13 => 1, 16 => 1, 22 => 1, diff --git a/WordPress/Tests/VIP/SuperGlobalInputUsageUnitTest.php b/WordPress/Tests/VIP/SuperGlobalInputUsageUnitTest.php index 5c60f2e1..cbd8cabe 100644 --- a/WordPress/Tests/VIP/SuperGlobalInputUsageUnitTest.php +++ b/WordPress/Tests/VIP/SuperGlobalInputUsageUnitTest.php @@ -38,7 +38,7 @@ public function getErrorList() { */ public function getWarningList() { return array( - 3 => 1, + 3 => 1, 13 => 1, 15 => 1, ); diff --git a/WordPress/Tests/VIP/TimezoneChangeUnitTest.php b/WordPress/Tests/VIP/TimezoneChangeUnitTest.php index b0f49806..7a8d9f35 100644 --- a/WordPress/Tests/VIP/TimezoneChangeUnitTest.php +++ b/WordPress/Tests/VIP/TimezoneChangeUnitTest.php @@ -28,7 +28,7 @@ class TimezoneChangeUnitTest extends AbstractSniffUnitTest { */ public function getErrorList() { return array( - 3 => 1, + 3 => 1, ); } diff --git a/WordPress/Tests/VIP/ValidatedSanitizedInputUnitTest.php b/WordPress/Tests/VIP/ValidatedSanitizedInputUnitTest.php index 068ec3e3..46c30fc0 100644 --- a/WordPress/Tests/VIP/ValidatedSanitizedInputUnitTest.php +++ b/WordPress/Tests/VIP/ValidatedSanitizedInputUnitTest.php @@ -28,20 +28,20 @@ class ValidatedSanitizedInputUnitTest extends AbstractSniffUnitTest { */ public function getErrorList() { return array( - 5 => 3, - 7 => 1, - 10 => 1, - 20 => 1, - 33 => 3, - 65 => 1, - 79 => 1, - 80 => 1, - 81 => 1, - 82 => 1, - 85 => 1, - 90 => 1, - 93 => 1, - 96 => 1, + 5 => 3, + 7 => 1, + 10 => 1, + 20 => 1, + 33 => 3, + 65 => 1, + 79 => 1, + 80 => 1, + 81 => 1, + 82 => 1, + 85 => 1, + 90 => 1, + 93 => 1, + 96 => 1, 100 => 2, 101 => 1, 104 => 2, diff --git a/WordPress/Tests/Variables/VariableRestrictionsUnitTest.php b/WordPress/Tests/Variables/VariableRestrictionsUnitTest.php index 0d2ed4be..cbbf02f2 100644 --- a/WordPress/Tests/Variables/VariableRestrictionsUnitTest.php +++ b/WordPress/Tests/Variables/VariableRestrictionsUnitTest.php @@ -79,8 +79,8 @@ protected function tearDown() { */ public function getErrorList() { return array( - 3 => 1, - 5 => 1, + 3 => 1, + 5 => 1, 11 => 1, 15 => 1, 17 => 1, diff --git a/WordPress/Tests/WP/EnqueuedResourcesUnitTest.php b/WordPress/Tests/WP/EnqueuedResourcesUnitTest.php index dd19200c..28da1f87 100644 --- a/WordPress/Tests/WP/EnqueuedResourcesUnitTest.php +++ b/WordPress/Tests/WP/EnqueuedResourcesUnitTest.php @@ -28,10 +28,10 @@ class EnqueuedResourcesUnitTest extends AbstractSniffUnitTest { */ public function getErrorList() { return array( - 1 => 1, - 2 => 1, - 6 => 1, - 7 => 1, + 1 => 1, + 2 => 1, + 6 => 1, + 7 => 1, 10 => 1, 11 => 1, 13 => 1, diff --git a/WordPress/Tests/WP/I18nUnitTest.php b/WordPress/Tests/WP/I18nUnitTest.php index 55b9ff98..e0517408 100644 --- a/WordPress/Tests/WP/I18nUnitTest.php +++ b/WordPress/Tests/WP/I18nUnitTest.php @@ -68,51 +68,51 @@ public function getErrorList( $testFile = '' ) { switch ( $testFile ) { case 'I18nUnitTest.1.inc': return array( - 10 => 1, - 11 => 1, - 12 => 1, - 14 => 1, - 16 => 1, - 19 => 1, - 21 => 1, - 23 => 1, - 24 => 1, - 26 => 1, - 27 => 1, - 28 => 1, - 30 => 1, - 31 => 1, - 32 => 1, - 37 => 1, - 38 => 1, - 39 => 1, - 41 => 1, - 42 => 1, - 43 => 1, - 45 => 1, - 47 => 1, - 48 => 1, - 50 => 1, - 52 => 1, - 53 => 1, - 55 => 1, - 56 => 2, - 58 => 1, - 59 => 1, - 60 => 1, - 62 => 1, - 63 => 2, - 65 => 1, - 66 => 1, - 67 => 1, - 72 => 1, - 74 => 1, - 75 => 1, - 76 => 1, - 77 => 1, - 78 => 1, - 93 => 1, - 95 => 2, + 10 => 1, + 11 => 1, + 12 => 1, + 14 => 1, + 16 => 1, + 19 => 1, + 21 => 1, + 23 => 1, + 24 => 1, + 26 => 1, + 27 => 1, + 28 => 1, + 30 => 1, + 31 => 1, + 32 => 1, + 37 => 1, + 38 => 1, + 39 => 1, + 41 => 1, + 42 => 1, + 43 => 1, + 45 => 1, + 47 => 1, + 48 => 1, + 50 => 1, + 52 => 1, + 53 => 1, + 55 => 1, + 56 => 2, + 58 => 1, + 59 => 1, + 60 => 1, + 62 => 1, + 63 => 2, + 65 => 1, + 66 => 1, + 67 => 1, + 72 => 1, + 74 => 1, + 75 => 1, + 76 => 1, + 77 => 1, + 78 => 1, + 93 => 1, + 95 => 2, 100 => 1, 101 => 1, 102 => 1, @@ -171,8 +171,8 @@ public function getWarningList( $testFile = '' ) { switch ( $testFile ) { case 'I18nUnitTest.1.inc': return array( - 69 => 1, - 70 => 1, + 69 => 1, + 70 => 1, 100 => 1, 101 => 1, 102 => 1, @@ -181,7 +181,7 @@ public function getWarningList( $testFile = '' ) { case 'I18nUnitTest.2.inc': return array( - 9 => 1, + 9 => 1, 43 => 1, 49 => 1, 52 => 1, diff --git a/WordPress/Tests/WP/PreparedSQLUnitTest.php b/WordPress/Tests/WP/PreparedSQLUnitTest.php index 183b9df8..047c9370 100644 --- a/WordPress/Tests/WP/PreparedSQLUnitTest.php +++ b/WordPress/Tests/WP/PreparedSQLUnitTest.php @@ -30,11 +30,11 @@ class PreparedSQLUnitTest extends AbstractSniffUnitTest { */ public function getErrorList() { return array( - 3 => 1, - 4 => 1, - 5 => 1, - 7 => 1, - 8 => 1, + 3 => 1, + 4 => 1, + 5 => 1, + 7 => 1, + 8 => 1, 16 => 1, 17 => 1, 18 => 1, diff --git a/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.php b/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.php index 642f69c4..a5b9537f 100644 --- a/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.php +++ b/WordPress/Tests/WhiteSpace/ControlStructureSpacingUnitTest.php @@ -28,28 +28,28 @@ class ControlStructureSpacingUnitTest extends AbstractSniffUnitTest { */ public function getErrorList() { $ret = array( - 4 => 2, - 17 => 2, - 29 => 5, - 37 => 1, - 41 => 1, - 42 => 1, - 49 => 5, - 58 => 3, - 67 => 1, - 68 => 1, - 69 => 1, - 71 => 1, - 72 => 1, - 81 => 3, - 82 => 1, - 85 => 1, - 91 => 2, - 92 => 1, - 94 => 1, - 95 => 1, - 97 => 1, - 98 => 1, + 4 => 2, + 17 => 2, + 29 => 5, + 37 => 1, + 41 => 1, + 42 => 1, + 49 => 5, + 58 => 3, + 67 => 1, + 68 => 1, + 69 => 1, + 71 => 1, + 72 => 1, + 81 => 3, + 82 => 1, + 85 => 1, + 91 => 2, + 92 => 1, + 94 => 1, + 95 => 1, + 97 => 1, + 98 => 1, 135 => 2, 137 => 5, 144 => 1, diff --git a/WordPress/Tests/XSS/EscapeOutputUnitTest.php b/WordPress/Tests/XSS/EscapeOutputUnitTest.php index 0be554aa..af455140 100644 --- a/WordPress/Tests/XSS/EscapeOutputUnitTest.php +++ b/WordPress/Tests/XSS/EscapeOutputUnitTest.php @@ -28,22 +28,22 @@ class EscapeOutputUnitTest extends AbstractSniffUnitTest { */ public function getErrorList() { return array( - 17 => 1, - 19 => 1, - 36 => 1, - 39 => 1, - 40 => 1, - 41 => 1, - 43 => 1, - 46 => 1, - 53 => 1, - 59 => 1, - 60 => 1, - 65 => 1, - 68 => 1, - 71 => 1, - 73 => 1, - 75 => 1, + 17 => 1, + 19 => 1, + 36 => 1, + 39 => 1, + 40 => 1, + 41 => 1, + 43 => 1, + 46 => 1, + 53 => 1, + 59 => 1, + 60 => 1, + 65 => 1, + 68 => 1, + 71 => 1, + 73 => 1, + 75 => 1, 101 => 1, 103 => 1, 111 => 1, From f8229eb62f4b6a3b45a8e8fae7bdb7a28f70f753 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 7 Oct 2017 12:21:52 +0200 Subject: [PATCH 229/282] Array properties: always be lenient about spaces While PHPCS does not allow for additional spaces in custom properties which are passed through a ruleset, WPCS was already lenient about this when the property was (incorrectly) passed as a string. This fix will also make WPCS lenient about this when the property is passed as an array. Inspired by upstream issue squizlabs/PHP_CodeSniffer 1688 So for WPCS, all of the below four examples will now work properly as expected: ```xml ``` --- WordPress/Sniff.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index 864adb3d..89ca3f4e 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -1038,9 +1038,12 @@ public static function merge_custom_array( $custom, $base = array(), $flip = tru // Allow for a comma delimited list. if ( is_string( $custom ) ) { - $custom = array_filter( array_map( 'trim', explode( ',', $custom ) ) ); + $custom = explode( ',', $custom ); } + // Always trim whitespace from the values. + $custom = array_filter( array_map( 'trim', $custom ) ); + if ( true === $flip ) { $custom = array_fill_keys( $custom, false ); } From 964ec2cc0f6b0680886bb01aae7b549764ce0d08 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 8 Sep 2017 06:09:37 +0200 Subject: [PATCH 230/282] Add sniff to check for alignment of assignment operators to `Core` This sniff has already been added and remove a couple of times previously, see the discussion in 382#discussion_r29970107 amongst others. Adding the `maxPadding` property will hopefully make the sniff more acceptable. Sister-PR to the array arrow alignment sniff PR as requested in 1122. --- WordPress-Core/ruleset.xml | 8 ++++++++ WordPress-Extra/ruleset.xml | 4 ---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index 52cce7d4..4974ffaf 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -68,6 +68,13 @@ + + + + + + + @@ -75,6 +82,7 @@ + - - - From de8044b277aeb73b9b3de8660071b3c04854ef58 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 10 Sep 2017 11:09:30 +0200 Subject: [PATCH 231/282] Fix up existing WPCS code / multiple statement assignment operator alignment --- Test/phpcs2-bootstrap.php | 2 +- Test/phpcs3-bootstrap.php | 2 +- WordPress/AbstractClassRestrictionsSniff.php | 4 ++-- WordPress/Sniffs/CSRF/NonceVerificationSniff.php | 3 +++ .../Sniffs/Classes/ClassInstantiationSniff.php | 15 ++++++++------- .../NamingConventions/PrefixAllGlobalsSniff.php | 6 +++--- .../NamingConventions/ValidHookNameSniff.php | 2 +- .../NamingConventions/ValidVariableNameSniff.php | 3 ++- WordPress/Sniffs/PHP/StrictComparisonsSniff.php | 2 +- WordPress/Sniffs/VIP/AdminBarRemovalSniff.php | 9 +++++++-- WordPress/Sniffs/VIP/CronIntervalSniff.php | 2 +- WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php | 3 +++ .../Sniffs/VIP/ValidatedSanitizedInputSniff.php | 2 ++ WordPress/Sniffs/WP/DeprecatedClassesSniff.php | 4 ++-- WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php | 4 ++-- WordPress/Sniffs/WP/DeprecatedParametersSniff.php | 4 ++-- WordPress/Sniffs/WP/I18nSniff.php | 4 ++-- WordPress/Sniffs/XSS/EscapeOutputSniff.php | 5 ++++- 18 files changed, 47 insertions(+), 29 deletions(-) diff --git a/Test/phpcs2-bootstrap.php b/Test/phpcs2-bootstrap.php index fefff184..b4bde5b8 100644 --- a/Test/phpcs2-bootstrap.php +++ b/Test/phpcs2-bootstrap.php @@ -20,7 +20,7 @@ $phpcsDir = getenv( 'PHPCS_DIR' ); if ( false === $phpcsDir && is_dir( dirname( __DIR__ ) . $ds . 'vendor' . $ds . 'squizlabs' . $ds . 'php_codesniffer' ) ) { - $phpcsDir = dirname( __DIR__ ) . $ds . 'vendor' . $ds . 'squizlabs' . $ds . 'php_codesniffer'; + $phpcsDir = dirname( __DIR__ ) . $ds . 'vendor' . $ds . 'squizlabs' . $ds . 'php_codesniffer'; } elseif ( false !== $phpcsDir ) { $phpcsDir = realpath( $phpcsDir ); } diff --git a/Test/phpcs3-bootstrap.php b/Test/phpcs3-bootstrap.php index 93ccd68b..6b6fe229 100644 --- a/Test/phpcs3-bootstrap.php +++ b/Test/phpcs3-bootstrap.php @@ -26,7 +26,7 @@ // This may be a Composer install. if ( false === $phpcsDir && is_dir( dirname( __DIR__ ) . $ds . 'vendor' . $ds . 'squizlabs' . $ds . 'php_codesniffer' ) ) { - $phpcsDir = dirname( __DIR__ ) . $ds . 'vendor' . $ds . 'squizlabs' . $ds . 'php_codesniffer'; + $phpcsDir = dirname( __DIR__ ) . $ds . 'vendor' . $ds . 'squizlabs' . $ds . 'php_codesniffer'; } elseif ( false !== $phpcsDir ) { $phpcsDir = realpath( $phpcsDir ); } diff --git a/WordPress/AbstractClassRestrictionsSniff.php b/WordPress/AbstractClassRestrictionsSniff.php index b37cd490..3e42c047 100644 --- a/WordPress/AbstractClassRestrictionsSniff.php +++ b/WordPress/AbstractClassRestrictionsSniff.php @@ -121,9 +121,9 @@ public function is_targetted_token( $stackPtr ) { if ( in_array( $token['code'], array( T_NEW, T_EXTENDS, T_IMPLEMENTS ), true ) ) { if ( T_NEW === $token['code'] ) { - $nameEnd = ( $this->phpcsFile->findNext( array( T_OPEN_PARENTHESIS, T_WHITESPACE, T_SEMICOLON, T_OBJECT_OPERATOR ), ( $stackPtr + 2 ) ) - 1 ); + $nameEnd = ( $this->phpcsFile->findNext( array( T_OPEN_PARENTHESIS, T_WHITESPACE, T_SEMICOLON, T_OBJECT_OPERATOR ), ( $stackPtr + 2 ) ) - 1 ); } else { - $nameEnd = ( $this->phpcsFile->findNext( array( T_CLOSE_CURLY_BRACKET, T_WHITESPACE ), ( $stackPtr + 2 ) ) - 1 ); + $nameEnd = ( $this->phpcsFile->findNext( array( T_CLOSE_CURLY_BRACKET, T_WHITESPACE ), ( $stackPtr + 2 ) ) - 1 ); } $length = ( $nameEnd - ( $stackPtr + 1 ) ); diff --git a/WordPress/Sniffs/CSRF/NonceVerificationSniff.php b/WordPress/Sniffs/CSRF/NonceVerificationSniff.php index d9828410..3eff3780 100644 --- a/WordPress/Sniffs/CSRF/NonceVerificationSniff.php +++ b/WordPress/Sniffs/CSRF/NonceVerificationSniff.php @@ -177,6 +177,7 @@ protected function mergeFunctionLists() { $this->customNonceVerificationFunctions, $this->nonceVerificationFunctions ); + $this->addedCustomFunctions['nonce'] = $this->customNonceVerificationFunctions; } @@ -185,6 +186,7 @@ protected function mergeFunctionLists() { $this->customSanitizingFunctions, $this->sanitizingFunctions ); + $this->addedCustomFunctions['sanitize'] = $this->customSanitizingFunctions; } @@ -193,6 +195,7 @@ protected function mergeFunctionLists() { $this->customUnslashingSanitizingFunctions, $this->unslashingSanitizingFunctions ); + $this->addedCustomFunctions['unslashsanitize'] = $this->customUnslashingSanitizingFunctions; } } diff --git a/WordPress/Sniffs/Classes/ClassInstantiationSniff.php b/WordPress/Sniffs/Classes/ClassInstantiationSniff.php index bf85bd93..c5a4d1bb 100644 --- a/WordPress/Sniffs/Classes/ClassInstantiationSniff.php +++ b/WordPress/Sniffs/Classes/ClassInstantiationSniff.php @@ -59,13 +59,14 @@ public function register() { * * Currently does not account for classnames passed as a variable variable. */ - $this->classname_tokens = Tokens::$emptyTokens; - $this->classname_tokens[ T_NS_SEPARATOR ] = T_NS_SEPARATOR; - $this->classname_tokens[ T_STRING ] = T_STRING; - $this->classname_tokens[ T_SELF ] = T_SELF; - $this->classname_tokens[ T_STATIC ] = T_STATIC; - $this->classname_tokens[ T_PARENT ] = T_PARENT; - $this->classname_tokens[ T_ANON_CLASS ] = T_ANON_CLASS; + $this->classname_tokens = Tokens::$emptyTokens; + $this->classname_tokens[ T_NS_SEPARATOR ] = T_NS_SEPARATOR; + $this->classname_tokens[ T_STRING ] = T_STRING; + $this->classname_tokens[ T_SELF ] = T_SELF; + $this->classname_tokens[ T_STATIC ] = T_STATIC; + $this->classname_tokens[ T_PARENT ] = T_PARENT; + $this->classname_tokens[ T_ANON_CLASS ] = T_ANON_CLASS; + // Classname in a variable. $this->classname_tokens[ T_VARIABLE ] = T_VARIABLE; $this->classname_tokens[ T_DOUBLE_COLON ] = T_DOUBLE_COLON; diff --git a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php index cce8305c..9c351547 100644 --- a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php +++ b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php @@ -570,7 +570,7 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p return; } - $is_error = true; + $is_error = true; $raw_content = $this->strip_quotes( $parameters[1]['raw'] ); if ( $this->is_prefixed( $raw_content ) === true ) { @@ -600,8 +600,8 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p if ( T_DOUBLE_QUOTED_STRING === $this->tokens[ $first_non_empty ]['code'] ) { // If the first part of the parameter is a double quoted string, try again with only // the part before the first variable (if any). - $exploded = explode( '$', $first_non_empty_content ); - $first = rtrim( $exploded[0], '{' ); + $exploded = explode( '$', $first_non_empty_content ); + $first = rtrim( $exploded[0], '{' ); if ( '' !== $first ) { if ( $this->is_prefixed( $first ) === true ) { return; diff --git a/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php b/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php index f9d29278..ef20800f 100644 --- a/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php +++ b/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php @@ -97,7 +97,7 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p return; } - $regex = $this->prepare_regex(); + $regex = $this->prepare_regex(); $case_errors = 0; $underscores = 0; diff --git a/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php b/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php index ea027576..d57924c9 100644 --- a/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php +++ b/WordPress/Sniffs/NamingConventions/ValidVariableNameSniff.php @@ -202,7 +202,7 @@ protected function processVariable( File $phpcs_file, $stack_ptr ) { } if ( isset( $error, $error_name ) ) { - $data = array( $original_var_name ); + $data = array( $original_var_name ); $phpcs_file->addError( $error, $stack_ptr, $error_name, $data ); } } @@ -327,6 +327,7 @@ protected function mergeWhiteList( File $phpcs_file ) { $customProperties, $this->whitelisted_mixed_case_member_var_names ); + $this->addedCustomProperties['properties'] = $this->customPropertiesWhitelist; $this->addedCustomProperties['variables'] = $this->customVariablesWhitelist; } diff --git a/WordPress/Sniffs/PHP/StrictComparisonsSniff.php b/WordPress/Sniffs/PHP/StrictComparisonsSniff.php index e24b98b4..ee815270 100644 --- a/WordPress/Sniffs/PHP/StrictComparisonsSniff.php +++ b/WordPress/Sniffs/PHP/StrictComparisonsSniff.php @@ -49,7 +49,7 @@ public function register() { public function process_token( $stackPtr ) { if ( ! $this->has_whitelist_comment( 'loose comparison', $stackPtr ) ) { - $error = 'Found: ' . $this->tokens[ $stackPtr ]['content'] . '. Use strict comparisons (=== or !==).'; + $error = 'Found: ' . $this->tokens[ $stackPtr ]['content'] . '. Use strict comparisons (=== or !==).'; $this->phpcsFile->addWarning( $error, $stackPtr, 'LooseComparison' ); } diff --git a/WordPress/Sniffs/VIP/AdminBarRemovalSniff.php b/WordPress/Sniffs/VIP/AdminBarRemovalSniff.php index 0dbdb508..e692ff09 100644 --- a/WordPress/Sniffs/VIP/AdminBarRemovalSniff.php +++ b/WordPress/Sniffs/VIP/AdminBarRemovalSniff.php @@ -149,7 +149,12 @@ public function register() { $targets[] = T_STYLE; // Set the target selectors regex only once. - $selectors = array_map( 'preg_quote', $this->target_css_selectors, array_fill( 0, count( $this->target_css_selectors ), '`' ) ); + $selectors = array_map( + 'preg_quote', + $this->target_css_selectors, + array_fill( 0, count( $this->target_css_selectors ), '`' ) + ); + // Parse the selectors array into the regex string. $this->target_css_selectors_regex = sprintf( $this->target_css_selectors_regex, implode( '|', $selectors ) ); // Add function call targets. @@ -368,7 +373,7 @@ protected function process_css_style( $stackPtr ) { break; } } - $start = ( $i + 1 ); + $start = ( $i + 1 ); $selector = trim( $this->phpcsFile->getTokensAsString( $start, ( $opener - $start ) ) ); unset( $i ); diff --git a/WordPress/Sniffs/VIP/CronIntervalSniff.php b/WordPress/Sniffs/VIP/CronIntervalSniff.php index aa6309fa..4a82958f 100644 --- a/WordPress/Sniffs/VIP/CronIntervalSniff.php +++ b/WordPress/Sniffs/VIP/CronIntervalSniff.php @@ -61,7 +61,7 @@ public function register() { * @return void */ public function process_token( $stackPtr ) { - $token = $this->tokens[ $stackPtr ]; + $token = $this->tokens[ $stackPtr ]; if ( 'cron_schedules' !== $this->strip_quotes( $token['content'] ) ) { return; diff --git a/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php b/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php index 69aa8c0b..6458fd45 100644 --- a/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php +++ b/WordPress/Sniffs/VIP/DirectDatabaseQuerySniff.php @@ -240,6 +240,7 @@ protected function mergeFunctionLists() { $this->customCacheGetFunctions, $this->cacheGetFunctions ); + $this->addedCustomFunctions['cacheget'] = $this->customCacheGetFunctions; } @@ -248,6 +249,7 @@ protected function mergeFunctionLists() { $this->customCacheSetFunctions, $this->cacheSetFunctions ); + $this->addedCustomFunctions['cacheset'] = $this->customCacheSetFunctions; } @@ -256,6 +258,7 @@ protected function mergeFunctionLists() { $this->customCacheDeleteFunctions, $this->cacheDeleteFunctions ); + $this->addedCustomFunctions['cachedelete'] = $this->customCacheDeleteFunctions; } } diff --git a/WordPress/Sniffs/VIP/ValidatedSanitizedInputSniff.php b/WordPress/Sniffs/VIP/ValidatedSanitizedInputSniff.php index 704a16eb..d51744ed 100644 --- a/WordPress/Sniffs/VIP/ValidatedSanitizedInputSniff.php +++ b/WordPress/Sniffs/VIP/ValidatedSanitizedInputSniff.php @@ -167,6 +167,7 @@ protected function mergeFunctionLists() { $this->customSanitizingFunctions, $this->sanitizingFunctions ); + $this->addedCustomFunctions['sanitize'] = $this->customSanitizingFunctions; } @@ -175,6 +176,7 @@ protected function mergeFunctionLists() { $this->customUnslashingSanitizingFunctions, $this->unslashingSanitizingFunctions ); + $this->addedCustomFunctions['unslashsanitize'] = $this->customUnslashingSanitizingFunctions; } } diff --git a/WordPress/Sniffs/WP/DeprecatedClassesSniff.php b/WordPress/Sniffs/WP/DeprecatedClassesSniff.php index de9b36da..1e46dcf3 100644 --- a/WordPress/Sniffs/WP/DeprecatedClassesSniff.php +++ b/WordPress/Sniffs/WP/DeprecatedClassesSniff.php @@ -58,8 +58,8 @@ class DeprecatedClassesSniff extends AbstractClassRestrictionsSniff { */ public function getGroups() { // Make sure all array keys are lowercase. - $keys = array_keys( $this->deprecated_classes ); - $keys = array_map( 'strtolower', $keys ); + $keys = array_keys( $this->deprecated_classes ); + $keys = array_map( 'strtolower', $keys ); $this->deprecated_classes = array_combine( $keys, $this->deprecated_classes ); return array( diff --git a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php index 97f2f047..23c1d1d0 100644 --- a/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php +++ b/WordPress/Sniffs/WP/DeprecatedFunctionsSniff.php @@ -1307,8 +1307,8 @@ class DeprecatedFunctionsSniff extends AbstractFunctionRestrictionsSniff { */ public function getGroups() { // Make sure all array keys are lowercase. - $keys = array_keys( $this->deprecated_functions ); - $keys = array_map( 'strtolower', $keys ); + $keys = array_keys( $this->deprecated_functions ); + $keys = array_map( 'strtolower', $keys ); $this->deprecated_functions = array_combine( $keys, $this->deprecated_functions ); return array( diff --git a/WordPress/Sniffs/WP/DeprecatedParametersSniff.php b/WordPress/Sniffs/WP/DeprecatedParametersSniff.php index 7512c40c..30794b7a 100644 --- a/WordPress/Sniffs/WP/DeprecatedParametersSniff.php +++ b/WordPress/Sniffs/WP/DeprecatedParametersSniff.php @@ -314,9 +314,9 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p continue; } - $message = 'The parameter "%s" at position #%s of %s() has been deprecated since WordPress version %s.'; + $message = 'The parameter "%s" at position #%s of %s() has been deprecated since WordPress version %s.'; $is_error = version_compare( $parameter_args['version'], $this->minimum_supported_version, '<' ); - $code = $this->string_to_errorcode( ucfirst( $matched_content ) . 'Param' . $position . 'Found' ); + $code = $this->string_to_errorcode( ucfirst( $matched_content ) . 'Param' . $position . 'Found' ); $data = array( $parameters[ $position ]['raw'], diff --git a/WordPress/Sniffs/WP/I18nSniff.php b/WordPress/Sniffs/WP/I18nSniff.php index 4819d43a..05601dd6 100644 --- a/WordPress/Sniffs/WP/I18nSniff.php +++ b/WordPress/Sniffs/WP/I18nSniff.php @@ -468,9 +468,9 @@ protected function check_text( $context ) { // Prepare the strings for use a regex. $replace_regexes[ $i ] = '`\Q' . $unordered_matches[ $i ] . '\E`'; // Note: the initial \\ is a literal \, the four \ in the replacement translate to also to a literal \. - $replacements[ $i ] = str_replace( '\\', '\\\\', $suggestions[ $i ] ); + $replacements[ $i ] = str_replace( '\\', '\\\\', $suggestions[ $i ] ); // Note: the $ needs escaping to prevent numeric sequences after the $ being interpreted as match replacements. - $replacements[ $i ] = str_replace( '$', '\\$', $replacements[ $i ] ); + $replacements[ $i ] = str_replace( '$', '\\$', $replacements[ $i ] ); } $fix = $this->addFixableMessage( diff --git a/WordPress/Sniffs/XSS/EscapeOutputSniff.php b/WordPress/Sniffs/XSS/EscapeOutputSniff.php index a829b1b4..4b90758f 100644 --- a/WordPress/Sniffs/XSS/EscapeOutputSniff.php +++ b/WordPress/Sniffs/XSS/EscapeOutputSniff.php @@ -403,7 +403,7 @@ public function process_token( $stackPtr ) { // If we're able to resolve the function name, do so. if ( $mapped_function && T_CONSTANT_ENCAPSED_STRING === $this->tokens[ $mapped_function ]['code'] ) { $functionName = $this->strip_quotes( $this->tokens[ $mapped_function ]['content'] ); - $ptr = $mapped_function; + $ptr = $mapped_function; } } @@ -482,6 +482,7 @@ protected function mergeFunctionLists() { $customEscapeFunctions, $this->escapingFunctions ); + $this->addedCustomFunctions['escape'] = $this->customEscapingFunctions; $this->addedCustomFunctions['sanitize'] = $this->customSanitizingFunctions; } @@ -491,6 +492,7 @@ protected function mergeFunctionLists() { $this->customAutoEscapedFunctions, $this->autoEscapedFunctions ); + $this->addedCustomFunctions['autoescape'] = $this->customAutoEscapedFunctions; } @@ -500,6 +502,7 @@ protected function mergeFunctionLists() { $this->customPrintingFunctions, $this->printingFunctions ); + $this->addedCustomFunctions['print'] = $this->customPrintingFunctions; } } From 77da53fef2ae9227a94dc44cf32b8095f865ff4e Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 8 Oct 2017 17:12:28 +0200 Subject: [PATCH 232/282] StrictInArray: Allow for excluding warning when `false` is found When a dev has supplied `false` as the third parameter, this will in all likelyhood be a very conscious choice. Using a different error code for that particular code allows for modularly excluding the warning from the ruleset. --- WordPress/Sniffs/PHP/StrictInArraySniff.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/WordPress/Sniffs/PHP/StrictInArraySniff.php b/WordPress/Sniffs/PHP/StrictInArraySniff.php index f81b0a11..6feb1b26 100644 --- a/WordPress/Sniffs/PHP/StrictInArraySniff.php +++ b/WordPress/Sniffs/PHP/StrictInArraySniff.php @@ -81,10 +81,20 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p // We're only interested in the third parameter. if ( false === isset( $parameters[3] ) || 'true' !== strtolower( $parameters[3]['raw'] ) ) { + $errorcode = 'MissingTrueStrict'; + + /* + * Use a different error code when `false` is found to allow for excluding + * the warning as this will be a conscious choice made by the dev. + */ + if ( isset( $parameters[3] ) && 'false' === strtolower( $parameters[3]['raw'] ) ) { + $errorcode = 'FoundNonStrictFalse'; + } + $this->phpcsFile->addWarning( 'Not using strict comparison for %s; supply true for third argument.', ( isset( $parameters[3]['start'] ) ? $parameters[3]['start'] : $parameters[1]['start'] ), - 'MissingTrueStrict', + $errorcode, array( $matched_content ) ); return; From 4bf659abf2cd578e1249c7e3ad5c65c4796af620 Mon Sep 17 00:00:00 2001 From: JDGrimes Date: Sat, 23 Sep 2017 10:30:34 -0400 Subject: [PATCH 233/282] Improve fixes for PEAR.Files.IncludingFile.BracketsNotRequired MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds two sniffs that correct spacing on either side of the `require*` after the parentheses are removed: - `Squiz.WhiteSpace.SemicolonSpacing` (added to `Core`) — Requires no whitespace before the semicolon. - `Squiz.WhiteSpace.LanguageConstructSpacing` (added to `Extra`) — Requires exactly one space after a control structure. Fixes #1153 --- WordPress-Core/ruleset.xml | 3 +++ WordPress-Extra/ruleset.xml | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index 4974ffaf..278e179c 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -404,6 +404,9 @@ + + + diff --git a/WordPress-Extra/ruleset.xml b/WordPress-Extra/ruleset.xml index f5e3694d..84514388 100644 --- a/WordPress-Extra/ruleset.xml +++ b/WordPress-Extra/ruleset.xml @@ -55,6 +55,11 @@ warning + + + From 7dc2c168f0e6dd72f24fbd2bfd54b1eed70098dd Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 7 Oct 2017 18:03:30 +0200 Subject: [PATCH 234/282] :sparkles: Add new WhiteSpace.SemicolonSpacing sniff This new sniff extends the upstream `Squiz.WhiteSpace.SemicolonSpacing` sniff but allows for semi-colons used to denote an empty condition within a `for()` control structure to have a space before them. Once this has been fixed upstream and the WPCS minimum required PHPCS version has gone up beyond the PHPCS version containing the fix, this custom sniff can be removed and we can defer to the upstream sniff again. Refs: * http://php.net/manual/en/control-structures.for.php * squizlabs/PHP_CodeSniffer 1690 --- WordPress-Core/ruleset.xml | 5 +- WordPress/PHPCSAliases.php | 3 + .../WhiteSpace/SemicolonSpacingSniff.php | 65 +++++++++++++++++++ .../WhiteSpace/SemicolonSpacingUnitTest.inc | 12 ++++ .../SemicolonSpacingUnitTest.inc.fixed | 12 ++++ .../WhiteSpace/SemicolonSpacingUnitTest.php | 48 ++++++++++++++ 6 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 WordPress/Sniffs/WhiteSpace/SemicolonSpacingSniff.php create mode 100644 WordPress/Tests/WhiteSpace/SemicolonSpacingUnitTest.inc create mode 100644 WordPress/Tests/WhiteSpace/SemicolonSpacingUnitTest.inc.fixed create mode 100644 WordPress/Tests/WhiteSpace/SemicolonSpacingUnitTest.php diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index 278e179c..4b4d84cb 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -405,7 +405,10 @@ - + + diff --git a/WordPress/PHPCSAliases.php b/WordPress/PHPCSAliases.php index b7223b60..affacaa7 100644 --- a/WordPress/PHPCSAliases.php +++ b/WordPress/PHPCSAliases.php @@ -45,6 +45,9 @@ class_alias( 'PHP_CodeSniffer\Standards\PEAR\Sniffs\NamingConventions\ValidFunct if ( ! class_exists( '\Squiz_Sniffs_WhiteSpace_OperatorSpacingSniff' ) ) { class_alias( 'PHP_CodeSniffer\Standards\Squiz\Sniffs\WhiteSpace\OperatorSpacingSniff', '\Squiz_Sniffs_WhiteSpace_OperatorSpacingSniff' ); } + if ( ! class_exists( '\Squiz_Sniffs_WhiteSpace_SemicolonSpacingSniff' ) ) { + class_alias( 'PHP_CodeSniffer\Standards\Squiz\Sniffs\WhiteSpace\SemicolonSpacingSniff', '\Squiz_Sniffs_WhiteSpace_SemicolonSpacingSniff' ); + } define( 'WPCS_PHPCS_ALIASES_SET', true ); diff --git a/WordPress/Sniffs/WhiteSpace/SemicolonSpacingSniff.php b/WordPress/Sniffs/WhiteSpace/SemicolonSpacingSniff.php new file mode 100644 index 00000000..14733186 --- /dev/null +++ b/WordPress/Sniffs/WhiteSpace/SemicolonSpacingSniff.php @@ -0,0 +1,65 @@ +getTokens(); + + // Don't examine semi-colons for empty conditions in `for()` control structures. + if ( isset( $tokens[ $stackPtr ]['nested_parenthesis'] ) ) { + $close_parenthesis = end( $tokens[ $stackPtr ]['nested_parenthesis'] ); + + if ( isset( $tokens[ $close_parenthesis ]['parenthesis_owner'] ) ) { + $owner = $tokens[ $close_parenthesis ]['parenthesis_owner']; + + if ( T_FOR === $tokens[ $owner ]['code'] ) { + $previous = $phpcsFile->findPrevious( + Tokens::$emptyTokens, + ( $stackPtr - 1 ), + $tokens[ $owner ]['parenthesis_opener'], + true + ); + + if ( false !== $previous + && ( $previous === $tokens[ $owner ]['parenthesis_opener'] + || T_SEMICOLON === $tokens[ $previous ]['code'] ) + ) { + return; + } + } + } + } + + return parent::process( $phpcsFile, $stackPtr ); + } + +} // End class. diff --git a/WordPress/Tests/WhiteSpace/SemicolonSpacingUnitTest.inc b/WordPress/Tests/WhiteSpace/SemicolonSpacingUnitTest.inc new file mode 100644 index 00000000..ec7f4067 --- /dev/null +++ b/WordPress/Tests/WhiteSpace/SemicolonSpacingUnitTest.inc @@ -0,0 +1,12 @@ += 0; $ptr-- ) {} +for ( ; ; ) {} + +// But it should when the whitespace is between a condition and a semi-colon. +for ( $i = 1 ; ; $i++ ) {} diff --git a/WordPress/Tests/WhiteSpace/SemicolonSpacingUnitTest.inc.fixed b/WordPress/Tests/WhiteSpace/SemicolonSpacingUnitTest.inc.fixed new file mode 100644 index 00000000..0a0820f1 --- /dev/null +++ b/WordPress/Tests/WhiteSpace/SemicolonSpacingUnitTest.inc.fixed @@ -0,0 +1,12 @@ += 0; $ptr-- ) {} +for ( ; ; ) {} + +// But it should when the whitespace is between a condition and a semi-colon. +for ( $i = 1; ; $i++ ) {} diff --git a/WordPress/Tests/WhiteSpace/SemicolonSpacingUnitTest.php b/WordPress/Tests/WhiteSpace/SemicolonSpacingUnitTest.php new file mode 100644 index 00000000..0de15603 --- /dev/null +++ b/WordPress/Tests/WhiteSpace/SemicolonSpacingUnitTest.php @@ -0,0 +1,48 @@ + => + */ + public function getErrorList() { + return array( + 12 => 1, + ); + + } + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array(); + + } + +} // End class. From c49845d8a042c6331b33918990bf0ab5250dc798 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 11 Oct 2017 08:46:52 +0200 Subject: [PATCH 235/282] Core: Add `Generic.Functions.FunctionCallArgumentSpacing` sniff Fixes 1189 --- WordPress-Core/ruleset.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index 4b4d84cb..29fd0d05 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -213,6 +213,8 @@ + + From 3bea576cf4798c6fb6aee6a5caf04bf1e1ca1c34 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 11 Oct 2017 09:04:49 +0200 Subject: [PATCH 236/282] Fix up issues in the WPCS codebase with the new FunctionCallArgumentSpacing sniff --- WordPress/Sniff.php | 24 +++++++++---------- WordPress/Sniffs/PHP/YodaConditionsSniff.php | 8 +++---- WordPress/Sniffs/WP/I18nSniff.php | 2 +- .../Tests/WP/DeprecatedFunctionsUnitTest.php | 6 ++--- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/WordPress/Sniff.php b/WordPress/Sniff.php index 92427756..a40e95c6 100644 --- a/WordPress/Sniff.php +++ b/WordPress/Sniff.php @@ -1269,12 +1269,12 @@ protected function is_assignment( $stackPtr ) { } $next_non_empty = $this->phpcsFile->findNext( - Tokens::$emptyTokens - , ( $stackPtr + 1 ) - , null - , true - , null - , true + Tokens::$emptyTokens, + ( $stackPtr + 1 ), + null, + true, + null, + true ); // No token found. @@ -1463,10 +1463,10 @@ protected function is_safe_casted( $stackPtr ) { // Get the last non-empty token. $prev = $this->phpcsFile->findPrevious( - Tokens::$emptyTokens - , ( $stackPtr - 1 ) - , null - , true + Tokens::$emptyTokens, + ( $stackPtr - 1 ), + null, + true ); // Check if it is a safe cast. @@ -1619,8 +1619,8 @@ protected function get_array_access_key( $stackPtr ) { } $key = $this->phpcsFile->getTokensAsString( - ( $open_bracket + 1 ) - , ( $this->tokens[ $open_bracket ]['bracket_closer'] - $open_bracket - 1 ) + ( $open_bracket + 1 ), + ( $this->tokens[ $open_bracket ]['bracket_closer'] - $open_bracket - 1 ) ); return trim( $key ); diff --git a/WordPress/Sniffs/PHP/YodaConditionsSniff.php b/WordPress/Sniffs/PHP/YodaConditionsSniff.php index 203df5e9..f66b3471 100644 --- a/WordPress/Sniffs/PHP/YodaConditionsSniff.php +++ b/WordPress/Sniffs/PHP/YodaConditionsSniff.php @@ -109,10 +109,10 @@ public function process_token( $stackPtr ) { if ( in_array( $this->tokens[ $next_non_empty ]['code'], array( T_SELF, T_PARENT, T_STATIC ), true ) ) { $next_non_empty = $this->phpcsFile->findNext( - array_merge( Tokens::$emptyTokens, array( T_DOUBLE_COLON ) ) - , ( $next_non_empty + 1 ) - , null - , true + array_merge( Tokens::$emptyTokens, array( T_DOUBLE_COLON ) ), + ( $next_non_empty + 1 ), + null, + true ); } diff --git a/WordPress/Sniffs/WP/I18nSniff.php b/WordPress/Sniffs/WP/I18nSniff.php index 05601dd6..6a83f8cc 100644 --- a/WordPress/Sniffs/WP/I18nSniff.php +++ b/WordPress/Sniffs/WP/I18nSniff.php @@ -574,7 +574,7 @@ protected function check_for_translator_comment( $stack_ptr, $args ) { } elseif ( T_DOC_COMMENT_CLOSE_TAG === $this->tokens[ $previous_comment ]['code'] ) { // If it's docblock comment (wrong style) make sure that it's a translators comment. $db_start = $this->phpcsFile->findPrevious( T_DOC_COMMENT_OPEN_TAG, ( $previous_comment - 1 ) ); - $db_first_text = $this->phpcsFile->findNext( T_DOC_COMMENT_STRING, ( $db_start + 1 ), $previous_comment ); + $db_first_text = $this->phpcsFile->findNext( T_DOC_COMMENT_STRING, ( $db_start + 1 ), $previous_comment ); if ( true === $this->is_translators_comment( $this->tokens[ $db_first_text ]['content'] ) ) { $this->phpcsFile->addWarning( diff --git a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php index 1226febc..957ce678 100644 --- a/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php +++ b/WordPress/Tests/WP/DeprecatedFunctionsUnitTest.php @@ -32,9 +32,9 @@ public function getErrorList() { // Unset the lines related to version comments. unset( - $errors[10], $errors[12], $errors[14], $errors[16], $errors[29], - $errors[55], $errors[57], $errors[59], $errors[73], $errors[76], - $errors[80], $errors[118], $errors[125], $errors[161], $errors[174], + $errors[10], $errors[12], $errors[14], $errors[16], $errors[29], + $errors[55], $errors[57], $errors[59], $errors[73], $errors[76], + $errors[80], $errors[118], $errors[125], $errors[161], $errors[174], $errors[178], $errors[210], $errors[233], $errors[251], $errors[255], $errors[262], $errors[274], $errors[281], $errors[285], $errors[290], $errors[295], $errors[303] From 1c8b969bef11695eebdc0a4340329a2c960d471c Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 9 Sep 2017 01:25:57 +0200 Subject: [PATCH 237/282] :rocket: Travis: Add simple test for fixer conflicts to the build script By running the complete WPCS suite over the test case files, we should be able to catch at least some fixer conflicts early. The exit code should be 1 when all fixable errors have been fixed. The exit code will be 2 when not all fixable errors have been fixed, indicating a fixer conflict. The command will output a summary report which will indicate the files which "FAILED TO FIX". --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.travis.yml b/.travis.yml index 278b5e86..c299d741 100644 --- a/.travis.yml +++ b/.travis.yml @@ -77,6 +77,12 @@ script: - if [[ ${TRAVIS_PHP_VERSION:0:2} == "5." && ${PHPCS_BRANCH:0:2} != "2." ]]; then phpunit --filter WordPress $PHPCS_DIR/tests/AllTests.php; fi - if [[ ${TRAVIS_PHP_VERSION:0:2} != "5." && ${PHPCS_BRANCH:0:2} == "2." ]]; then php $PHPUNIT_DIR/phpunit-5.7.17.phar --filter WordPress $(pwd)/Test/AllTests.php; fi - if [[ ${TRAVIS_PHP_VERSION:0:2} != "5." && ${PHPCS_BRANCH:0:2} != "2." ]]; then php $PHPUNIT_DIR/phpunit-5.7.17.phar --filter WordPress $PHPCS_DIR/tests/AllTests.php; fi + # Test for fixer conflicts by running the auto-fixers of the complete WPCS over the test case files. + # This is not an exhaustive test, but should give an early indication for typical fixer conflicts. + # For the first run, the exit code will be 1 (= all fixable errors fixed). + # `travis_retry` should then kick in to run the fixer again which should now return 0 (= no fixable errors found). + # All error codes for the PHPCBF: https://github.com/squizlabs/PHP_CodeSniffer/issues/1270#issuecomment-272768413 + - if [[ "$SNIFF" == "1" ]]; then travis_retry $PHPCS_DIR/bin/phpcbf -p ./WordPress/Tests/ --standard=WordPress --extensions=inc --exclude=Generic.PHP.Syntax --report=summary; fi # WordPress Coding Standards. # @link https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards # @link http://pear.php.net/package/PHP_CodeSniffer/ From 1c6d8d349eaa07c793f009b00478ed609d1d87ef Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 12 Oct 2017 09:13:13 +0200 Subject: [PATCH 238/282] :sparkles: New ArbitraryParenthesesSpacing sniff for Core Checks the spacing on the inside of arbitrary parentheses. Arbitrary parentheses, for the purposes of this sniff, are all parentheses which do not belong to a control structure, function declaration, function call or language construct. This is to prevent conflicts and duplication with rules for those type of constructs. The sniff will throw (fixable) errors when an incorrect amount of whitespace (too much/too little) has been found on the inside or the parenthesis. The sniff will throw a warning when an empty set of arbitrary parentheses is encountered. Includes extensive unit tests. The sniff has been set up to be pulled upstream and once upstream has been merged and the minimum PHPCS requirement for WPCS has gone up, to be removed from WPCS. Fixes 1194 - [ ] Add info on the custom properties to the wiki --- WordPress-Core/ruleset.xml | 15 + .../ArbitraryParenthesesSpacingSniff.php | 256 ++++++++++++++++++ .../ArbitraryParenthesesSpacingUnitTest.inc | 161 +++++++++++ ...itraryParenthesesSpacingUnitTest.inc.fixed | 149 ++++++++++ .../ArbitraryParenthesesSpacingUnitTest.php | 76 ++++++ 5 files changed, 657 insertions(+) create mode 100644 WordPress/Sniffs/WhiteSpace/ArbitraryParenthesesSpacingSniff.php create mode 100644 WordPress/Tests/WhiteSpace/ArbitraryParenthesesSpacingUnitTest.inc create mode 100644 WordPress/Tests/WhiteSpace/ArbitraryParenthesesSpacingUnitTest.inc.fixed create mode 100644 WordPress/Tests/WhiteSpace/ArbitraryParenthesesSpacingUnitTest.php diff --git a/WordPress-Core/ruleset.xml b/WordPress-Core/ruleset.xml index 29fd0d05..db39b1ef 100644 --- a/WordPress-Core/ruleset.xml +++ b/WordPress-Core/ruleset.xml @@ -225,6 +225,21 @@ + + + + + + + + + + + + + + + 1, 225 => 1, 226 => 1, + 252 => 1, + 253 => 1, ); } // end getErrorList() From 3d65c3dc5640cbed95268ee972be47c37a9f65e8 Mon Sep 17 00:00:00 2001 From: JDGrimes Date: Mon, 30 Oct 2017 16:33:49 -0400 Subject: [PATCH 265/282] Naming Conventions: make exceptions for core hooks intended to be reused Some core actions and filters are intended to be called by plugins and themes, so we don't need to throw an error when they are. --- .../PrefixAllGlobalsSniff.php | 19 +++++++++++++++++++ .../PrefixAllGlobalsUnitTest.inc | 4 ++++ 2 files changed, 23 insertions(+) diff --git a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php index 9c351547..25d862ff 100644 --- a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php +++ b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php @@ -91,6 +91,18 @@ class PrefixAllGlobalsSniff extends AbstractFunctionParameterSniff { '_SESSION' => true, ); + /** + * A list of core hooks that are allowed to be called by plugins and themes. + * + * @since 0.14.0 + * + * @var array + */ + protected $whitelisted_core_hooks = array( + 'widget_title' => true, + 'add_meta_boxes' => true, + ); + /** * Returns an array of tokens this test wants to listen for. * @@ -573,6 +585,13 @@ public function process_parameters( $stackPtr, $group_name, $matched_content, $p $is_error = true; $raw_content = $this->strip_quotes( $parameters[1]['raw'] ); + if ( + 'define' !== $matched_content + && isset( $this->whitelisted_core_hooks[ $raw_content ] ) + ) { + return; + } + if ( $this->is_prefixed( $raw_content ) === true ) { return; } else { diff --git a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc index 75d0e0db..1dbc0e51 100644 --- a/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc +++ b/WordPress/Tests/NamingConventions/PrefixAllGlobalsUnitTest.inc @@ -318,3 +318,7 @@ namespace Testing { define( 'MY' . __NAMESPACE__, __FILE__ ); // Error, not actually namespaced. define( 'MY\\' . __NAMESPACE__, __FILE__ ); // OK, even though strangely setup, the constant is in a namespace. } + +// OK: whitelisted core hooks. +apply_filters( 'widget_title', $title ); +do_action( 'add_meta_boxes' ); From 484a99a7e7f5a260cd30d8f5e47f80d69f661238 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 1 Nov 2017 03:11:55 +0100 Subject: [PATCH 266/282] PreparedSQLPlaceholders: update for WP 4.8.3 changes WP 4.8.3 brings back numbered and formatted placeholders. The sniff was originally written to detect *against* those, so to prevent confusing devs terribly, something had to be done quickly. So here goes. * Allow for normal `vsprintf()` placeholders, but only for digits, floats and strings - `dfFs`. * Continue to detect unsupported placeholders, though this has now become a far more complex set to detect. * Continue to error on quoted _simple_ placeholders. * New: Throw a warning on _unquoted_ **complex** placeholders. These will not be quoted by `$wpdb->prepare()` as these are often used to pass in partial query strings. * Downgrade the mismatched placeholders vs replacements message to a `warning`. As the passing in of _partial query strings_ has been brought back, the chances of a number mismatch here have increased, so a warning seems more appropriate. The regexes are "variations on the same theme" as the regex which is used in the `WP.I18n` sniff, but with some significant differences. The first regex is not that different, except that it better protects against issues with a literal `%` (`%%`) being followed by a placeholder. It is also limited to the allowed placeholder types. The second regex has more significant differences, both in the greediness as well as the matching of "whatever comes after" the `%`. Includes updated & adjusted unit tests to test for the new reality. This should be the last PR for WPCS `0.14.0`. --- .../DB/PreparedSQLPlaceholdersSniff.php | 113 ++++++++++++++++-- .../DB/PreparedSQLPlaceholdersUnitTest.inc | 24 ++-- .../DB/PreparedSQLPlaceholdersUnitTest.php | 32 ++--- 3 files changed, 130 insertions(+), 39 deletions(-) diff --git a/WordPress/Sniffs/DB/PreparedSQLPlaceholdersSniff.php b/WordPress/Sniffs/DB/PreparedSQLPlaceholdersSniff.php index 0892afe4..4606eb1e 100644 --- a/WordPress/Sniffs/DB/PreparedSQLPlaceholdersSniff.php +++ b/WordPress/Sniffs/DB/PreparedSQLPlaceholdersSniff.php @@ -42,6 +42,77 @@ */ class PreparedSQLPlaceholdersSniff extends Sniff { + /** + * These regexes copied from http://php.net/manual/en/function.sprintf.php#93552 + * and adjusted for limitations in `$wpdb->prepare()`. + * + * Near duplicate of the one used in the WP.I18n sniff, but with less types allowed. + * + * Note: The regex delimiters and modifiers are not included to allow this regex to be + * concatenated together with other regex partials. + * + * @since 0.14.0 + * + * @var string + */ + const PREPARE_PLACEHOLDER_REGEX = '(?: + (?get_regex_quote_snippet( $prev_content, $this->tokens[ $prev ]['content'] ); // Only examine the implode if preceded by an ` IN (`. - if ( preg_match( '`\s+IN\s*\(\s*' . $regex_quote . '?$`i', $prev_content, $match ) > 0 ) { + if ( preg_match( '`\s+IN\s*\(\s*(' . $regex_quote . ')?$`i', $prev_content, $match ) > 0 ) { if ( isset( $match[1] ) && $regex_quote !== $this->regex_quote ) { $this->phpcsFile->addError( @@ -215,7 +286,7 @@ public function process_token( $stackPtr ) { unset( $stripped_content, $interpolated_vars, $vars_without_wpdb ); } - $placeholders = preg_match_all( '`(? 0 ) { $total_placeholders += $placeholders; } @@ -228,7 +299,7 @@ public function process_token( $stackPtr ) { * - Any other `LIKE` statement should be reported, either for using `LIKE` without * SQL wildcards or for not passing the SQL wildcards via the replacement. */ - $regex = '`\s+LIKE\s*(?:' . $regex_quote . '(?!%s(?:\1|$))(?P.*?)(?:\1|$)|(?:concat\((?![^\)]*%s[^\)]*\))(?P[^\)]*))\))`i'; + $regex = '`\s+LIKE\s*(?:(' . $regex_quote . ')(?!%s(?:\1|$))(?P.*?)(?:\1|$)|(?:concat\((?![^\)]*%s[^\)]*\))(?P[^\)]*))\))`i'; if ( preg_match_all( $regex, $content, $matches ) > 0 ) { $walk = array(); if ( ! empty( $matches['content'] ) ) { @@ -295,7 +366,7 @@ public function process_token( $stackPtr ) { /* * Analyse the query for unsupported placeholders. */ - if ( preg_match_all( '`(? 0 ) { + if ( preg_match_all( self::UNSUPPORTED_PLACEHOLDER_REGEX, $content, $matches ) > 0 ) { if ( ! empty( $matches[0] ) ) { foreach ( $matches[0] as $match ) { if ( '%' === $match ) { @@ -321,14 +392,14 @@ public function process_token( $stackPtr ) { /* * Analyse the query for quoted placeholders. */ - $regex = '`' . $regex_quote . '%[dfFs]\1`'; + $regex = '`(' . $regex_quote . ')%[dfFs]\1`'; if ( preg_match_all( $regex, $content, $matches ) > 0 ) { if ( ! empty( $matches[0] ) ) { foreach ( $matches[0] as $match ) { $this->phpcsFile->addError( - 'Placeholders should be unquoted in the query string in $wpdb->prepare(). Found: %s.', + 'Simple placeholders should not be quoted in the query string in $wpdb->prepare(). Found: %s.', $i, - 'QuotedPlaceholder', + 'QuotedSimplePlaceholder', array( $match ) ); } @@ -336,6 +407,26 @@ public function process_token( $stackPtr ) { unset( $match, $matches ); } + /* + * Analyse the query for unquoted complex placeholders. + */ + $regex = '`(? 0 ) { + if ( ! empty( $matches[0] ) ) { + foreach ( $matches[0] as $match ) { + if ( preg_match( '`%[dfFs]`', $match ) !== 1 ) { + $this->phpcsFile->addWarning( + 'Complex placeholders used for values in the query string in $wpdb->prepare() will NOT be quoted automagically. Found: %s.', + $i, + 'UnquotedComplexPlaceholder', + array( $match ) + ); + } + } + } + unset( $match, $matches ); + } + /* * Check for an ` IN (%s)` clause. */ @@ -431,7 +522,7 @@ public function process_token( $stackPtr ) { * Verify that the correct amount of replacements have been passed. */ if ( $total_replacements !== $total_placeholders ) { - $this->phpcsFile->addError( + $this->phpcsFile->addWarning( 'Incorrect number of replacements passed to $wpdb->prepare(). Found %d replacement parameters, expected %d.', $stackPtr, 'ReplacementsWrongNumber', @@ -462,9 +553,9 @@ protected function get_regex_quote_snippet( $stripped_content, $original_content $quote_style = $original_content[0]; if ( '"' === $quote_style ) { - $regex_quote = '(\\\\"|\')'; + $regex_quote = '\\\\"|\''; } elseif ( "'" === $quote_style ) { - $regex_quote = '("|\\\\\')'; + $regex_quote = '"|\\\\\''; } } diff --git a/WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.inc b/WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.inc index ce684d7a..d7030131 100644 --- a/WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.inc +++ b/WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.inc @@ -25,28 +25,28 @@ $sql = $wpdb->prepare( 'SELECT * FROM `table`', $something ); // Warning. /* * Test passing invalid replacement placeholder. */ -$sql = $wpdb->prepare( '%d %1$d %%% %', 1 ); // Bad x 3. +$sql = $wpdb->prepare( '%d %1$e %%% % %A %h', 1 ); // Bad x 5. $sql = $wpdb->prepare( '%%%s', 1 ); // OK. -$sql = $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %1\$d AND user_login = %2\$s", 1, "admin" ); // Bad x 2 + 1 warning. -$sql = $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %01.2f AND user_login = %10.10s", 1, "admin" ); // Bad x 2 + 1 warning. -$sql = $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %'.09d AND user_login = %1\$04d", 1, "admin" ); // Bad x 2 + 1 warning. -$sql = $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = \"%1\$d\" AND user_login = '%2\$s'", 1, "admin" ); // Bad x 2 + 1 warning. -$sql = $wpdb->prepare( 'SELECT * FROM ' . $wpdb->users . ' WHERE id = \'%1\$d\' AND user_login = "%2\$s"', 1, "admin" ); // Bad x 2 + 1 warning. +$sql = $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %1\$d AND user_login = %2\$s", 1, "admin" ); // OK. 2 x warning for unquoted complex placeholders. +$sql = $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %01.2f AND user_login = %10.10X", 1, "admin" ); // Bad x 1 + 1 warning unquoted complex placeholders + 1 warning nr of replacements. +$sql = $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = %'.09F AND user_login = %1\$04x", 1, "admin" ); // Bad x 1 + 1 warning unquoted complex placeholders + 1 warning nr of replacements. +$sql = $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE id = \"%1\$c\" AND user_login = '%2\$e'", 1, "admin" ); // Bad x 2 + 1 warning. +$sql = $wpdb->prepare( 'SELECT * FROM ' . $wpdb->users . ' WHERE id = \'%1\$b\' AND user_login = "%2\$o"', 1, "admin" ); // Bad x 2 + 1 warning. /* - * Test passing quoted replacement placeholder. + * Test passing quoted simple replacement placeholder and unquoted complex placeholder. */ $sql = $wpdb->prepare( '"%f"', 1.1 ); // Bad. $sql = $wpdb->prepare( 'SELECT * FROM `table` WHERE `field` = \'%s\'', 'string' ); // Bad. $sql = $wpdb->prepare( "SELECT * FROM `table` WHERE `id` = \"%d\"", 1 ); // Bad. $sql = $wpdb->prepare( <<users - WHERE id = '%d' - AND user_login = "%s" + FROM `%1\$s` + WHERE id = %2\$d + AND `%3\$s` = "%4\$s" EOD - , 1, "admin" -); // Bad x 2. + , $wpdb->users, 1, 'user_login', "admin" +); // Warning x 3, unquoted complex placeholder. /* * Test passing an incorrect amount of replacement parameters. diff --git a/WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.php b/WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.php index 2e81bea9..235be3ea 100644 --- a/WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.php +++ b/WordPress/Tests/DB/PreparedSQLPlaceholdersUnitTest.php @@ -27,25 +27,15 @@ class PreparedSQLPlaceholdersUnitTest extends AbstractSniffUnitTest { */ public function getErrorList() { return array( - 28 => 3, - 30 => 2, - 31 => 2, - 32 => 2, + 28 => 5, + 31 => 1, + 32 => 1, 33 => 2, 34 => 2, 39 => 1, 40 => 1, 41 => 1, - 45 => 1, - 46 => 1, 54 => 1, - 55 => 1, - 56 => 1, - 57 => 1, - 58 => 1, - 61 => 1, - 126 => 1, - 139 => 1, 141 => 1, 149 => 1, 151 => 1, @@ -82,12 +72,22 @@ public function getWarningList() { 16 => 1, 17 => 1, 23 => 1, - 30 => 1, - 31 => 1, - 32 => 1, + 30 => 2, + 31 => 2, + 32 => 2, 33 => 1, 34 => 1, + 44 => 1, + 45 => 1, + 46 => 1, + 55 => 1, + 56 => 1, + 57 => 1, + 58 => 1, + 61 => 1, 66 => 1, + 126 => 1, + 139 => 1, 160 => 2, 161 => 2, 177 => 1, From 9626e6431507f5ba1d7792c154989843f4a93253 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 1 Nov 2017 11:08:16 +0100 Subject: [PATCH 267/282] PreparedSQLPlaceholders: minor documentation update --- .../Sniffs/DB/PreparedSQLPlaceholdersSniff.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/WordPress/Sniffs/DB/PreparedSQLPlaceholdersSniff.php b/WordPress/Sniffs/DB/PreparedSQLPlaceholdersSniff.php index 4606eb1e..58af2878 100644 --- a/WordPress/Sniffs/DB/PreparedSQLPlaceholdersSniff.php +++ b/WordPress/Sniffs/DB/PreparedSQLPlaceholdersSniff.php @@ -16,9 +16,12 @@ * Check for incorrect use of the $wpdb->prepare method. * * Check the following issues: - * - As of WP 4.8.2, the only placeholders supported are: %d, %f (%F) and %s. + * - The only placeholders supported are: %d, %f (%F) and %s and their variations. * - Literal % signs need to be properly escaped as `%%`. - * - Placeholders should be left unquoted in the query string. + * - Simple placeholders (%d, %f, %F, %s) should be left unquoted in the query string. + * - Complex placeholders - numbered and formatted variants - will not be quoted + * automagically by $wpdb->prepare(), so if used for values, should be quoted in + * the query string. * - Either an array of replacements should be passed matching the number of * placeholders found or individual parameters for each placeholder should * be passed. @@ -46,7 +49,7 @@ class PreparedSQLPlaceholdersSniff extends Sniff { * These regexes copied from http://php.net/manual/en/function.sprintf.php#93552 * and adjusted for limitations in `$wpdb->prepare()`. * - * Near duplicate of the one used in the WP.I18n sniff, but with less types allowed. + * Near duplicate of the one used in the WP.I18n sniff, but with fewer types allowed. * * Note: The regex delimiters and modifiers are not included to allow this regex to be * concatenated together with other regex partials. @@ -72,7 +75,7 @@ class PreparedSQLPlaceholdersSniff extends Sniff { [0-9]+ # Width specifier. (?:\.(?:[ 0]|\'.)?[0-9]+)? # Optional precision specifier with optional padding character. ) - [dfFs] # Type specifier. + [dfFs] # Type specifier. ) )'; @@ -95,7 +98,7 @@ class PreparedSQLPlaceholdersSniff extends Sniff { | %%[dfFs] # Nor a correct literal % (%%), followed by a simple placeholder. ) - (?:[0-9]+\\\\??\$)?+ # Optional ordering of the placeholders. + (?:[0-9]+\\\\??\$)?+ # Optional ordering of the placeholders. [+-]?+ # Optional sign specifier. (?: (?:0|\'.)?+ # Optional padding specifier - excluding the space. From 35a323454424954ba74971c3bdbaee2240c55378 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 24 Oct 2017 03:49:48 +0200 Subject: [PATCH 268/282] Changelog for 0.14.0 --- CHANGELOG.md | 68 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a8ed845..965eeefd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,67 @@ This projects adheres to [Semantic Versioning](http://semver.org/) and [Keep a C _Nothing yet._ +## [0.14.0] - 2017-11-01 + +### Added +- `WordPress.Arrays.MultipleStatementAlignment` sniff to the `WordPress-Core` ruleset which will align the array assignment operator for multi-item, multi-line associative arrays. + This new sniff offers four custom properties to customize its behaviour: [`ignoreNewlines`](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#array-alignment-allow-for-new-lines), [`exact`](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#array-alignment-allow-non-exact-alignment), [`maxColumn`](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#array-alignment-maximum-column) and [`alignMultilineItems`](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#array-alignment-dealing-with-multi-line-items). +- `WordPress.DB.PreparedSQLPlaceholders` sniff to the `WordPress-Core` ruleset which will analyse the placeholders passed to `$wpdb->prepare()` for their validity, check whether queries using `IN ()` and `LIKE` statements are created correctly and will check whether a correct number of replacements are passed. + This sniff should help detect queries which are impacted by the security fixes to `$wpdb->prepare()` which shipped with WP 4.8.2 and 4.8.3. + The sniff also adds a new ["PreparedSQLPlaceholders replacement count" whitelist comment](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Whitelisting-code-which-flags-errors#preparedsql-placeholders-vs-replacements) for pertinent replacement count vs placeholder mismatches. Please consider carefully whether something could be a bug when you are tempted to use the whitelist comment and if so, [report it](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/new). +- `WordPress.PHP.DiscourageGoto` sniff to the `WordPress-Core` ruleset. +- `WordPress.PHP.RestrictedFunctions` sniff to the `WordPress-Core` ruleset which initially forbids the use of `create_function()`. + This was previous only discouraged under certain circumstances. +- `WordPress.WhiteSpace.ArbitraryParenthesesSpacing` sniff to the `WordPress-Core` ruleset which checks the spacing on the inside of arbitrary parentheses. +- `WordPress.WhiteSpace.PrecisionAlignment` sniff to the `WordPress-Core` ruleset which will throw a warning when precision alignment is detected in PHP, JS and CSS files. +- `WordPress.WhiteSpace.SemicolonSpacing` sniff to the `WordPress-Core` ruleset which will throw a (fixable) error when whitespace is found before a semi-colon, except for when the semi-colon denotes an empty `for()` condition. +- `WordPress.CodeAnalysis.AssignmentInCondition` sniff to the `WordPress-Extra` ruleset. +- `WordPress.WP.DiscouragedConstants` sniff to the `WordPress-Extra` and `WordPress-VIP` rulesets to detect usage of deprecated WordPress constants, such as `STYLESHEETPATH` and `HEADER_IMAGE`. +- Ability to pass the `minimum_supported_version` to use for the `DeprecatedFunctions`, `DeprecatedClasses` and `DeprecatedParameters` sniff in one go. You can pass a `minimum_supported_wp_version` runtime variable for this [from the command line or pass it using a `config` directive in a custom ruleset](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#setting-minimum-supported-wp-version-for-all-sniffs-in-one-go-wpcs-0140). +- `Generic.Formatting.MultipleStatementAlignment` - customized to have a `maxPadding` of `40` -, `Generic.Functions.FunctionCallArgumentSpacing` and `Squiz.WhiteSpace.ObjectOperatorSpacing` to the `WordPress-Core` ruleset. +- `Squiz.Scope.MethodScope`, `Squiz.Scope.MemberVarScope`, `Squiz.WhiteSpace.ScopeKeywordSpacing`, `PSR2.Methods.MethodDeclaration`, `Generic.Files.OneClassPerFile`, `Generic.Files.OneInterfacePerFile`, `Generic.Files.OneTraitPerFile`, `PEAR.Files.IncludingFile`, `Squiz.WhiteSpace.LanguageConstructSpacing`, `PSR2.Namespaces.NamespaceDeclaration` to the `WordPress-Extra` ruleset. +- The `is_class_constant()`, `is_class_property` and `valid_direct_scope()` utility methods to the `WordPress\Sniff` class. + +### Changed +- When passing an array property via a custom ruleset to PHP Codesniffer, spaces around the key/value are taken as intentional and parsed as part of the array key/value. In practice, this leads to confusion and WPCS does not expect any values which could be preceded/followed by a space, so for the WordPress Coding Standard native array properties, like `customAutoEscapedFunction`, `text_domain`, `prefixes`, WPCS will now trim whitespace from the keys/values received before use. +- The WPCS native whitelist comments used to only work when they were put on the _end of the line_ of the code they applied to. As of now, they will also be recognized when they are be put at the _end of the statement_ they apply to. +- The `WordPress.Arrays.ArrayDeclarationSpacing` sniff used to enforce all associative arrays to be multi-line. The handbook has been updated to only require this for multi-item associative arrays and the sniff has been updated accordingly. + [The original behaviour can still be enforced](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#arrays-forcing-single-item-associative-arrays-to-be-multi-line) by setting the new `allow_single_item_single_line_associative_arrays` property to `false` in a custom ruleset. +- The `WordPress.NamingConventions.PrefixAllGlobals` sniff will now allow for a limited list of WP core hooks which are intended to be called by plugins and themes. +- The `WordPress.PHP.DiscouragedFunctions` sniff used to include `create_function`. This check has been moved to the new `WordPress.PHP.RestrictedFunctions` sniff. +- The `WordPress.PHP.StrictInArray` sniff now has a separate error code `FoundNonStrictFalse` for when the `$strict` parameter has been set to `false`. This allows for excluding the warnings for that particular situation, which will normally be intentional, via a custom ruleset. +- The `WordPress.VIP.CronInterval` sniff now allows for customizing the minimum allowed cron interval by [setting a property in a custom ruleset](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#vip-croninterval-minimum-interval). +- The `WordPress.VIP.RestrictedFunctions` sniff used to prohibit the use of certain WP native functions, recommending the use of `wpcom_vip_get_term_link()`, `wpcom_vip_get_term_by()` and `wpcom_vip_get_category_by_slug()` instead, as the WP native functions were not being cached. As the results of the relevant WP native functions are cached as of WP 4.8, the advice has now been reversed i.e. use the WP native functions instead of `wpcom...` functions. +- The `WordPress.VIP.PostsPerPage` sniff now allows for customizing the `post_per_page` limit for which the sniff will trigger by [setting a property in a custom ruleset](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#vip-postsperpage-post-limit). +- The `WordPress.WP.I18n` sniff will now allow and actively encourage omitting the text-domain in I18n function calls if the text-domain passed via the `text_domain` property is `default`, i.e. the domain used by Core. + When `default` is one of several text-domains passed via the `text_domain` property, the error thrown when the domain is missing has been downgraded to a `warning`. +- The `WordPress.XSS.EscapeOutput` sniff now has a separate error code `OutputNotEscapedShortEcho` and the error message texts have been updated. +- Moved `Squiz.PHP.Eval` from the `WordPress-Extra` and `WordPress-VIP` to the `WordPress-Core` ruleset. +- Removed two sniffs from the `WordPress-VIP` ruleset which were already included via the `WordPress-Core` ruleset. +- The unit test suite is now compatible with PHPCS 3.1.0+ and PHPUnit 6.x. +- Some tidying up of the unit test case files. +- All sniffs are now also being tested against PHP 7.2 for consistent sniff results. +- An attempt is made to detect potential fixer conflicts early via a special build test. +- Various minor documentation fixes. +- Improved the Atom setup instructions in the Readme. +- Updated the unit testing information in Contributing. +- Updated the [custom ruleset example](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/blob/develop/phpcs.xml.dist.sample) for the changes contained in this release and to make it more explicit what is recommended versus example code. +- The minimum recommended version for the suggested `DealerDirect/phpcodesniffer-composer-installer` Composer plugin has gone up to `0.4.3`. + +### Fixed +- The `WordPress.Arrays.ArrayIndentation` sniff did not correctly handle array items with multi-line strings as a value. +- The `WordPress.Arrays.ArrayIndentation` sniff did not correctly handle array items directly after an array item with a trailing comment. +- The `WordPress.Classes.ClassInstantiation` sniff will now correctly handle detection when using `new $array['key']` or `new $array[0]`. +- The `WordPress.NamingConventions.PrefixAllGlobals` sniff did not allow for arbitrary word separators in hook names. +- The `WordPress.NamingConventions.PrefixAllGlobals` sniff did not correctly recognize namespaced constants as prefixed. +- The `WordPress.PHP.StrictInArray` sniff would erronously trigger if the `true` for `$strict` was passed in uppercase. +- The `WordPress.PHP.YodaConditions` sniff could get confused over complex ternaries containing assignments. This has been remedied. +- The `WordPress.WP.PreparedSQL` sniff would erronously throw errors about comments found within a DB function call. +- The `WordPress.WP.PreparedSQL` sniff would erronously throw errors about `(int)`, `(float)` and `(bool)` casts and would also flag the subsequent variable which had been safe casted. +- The `WordPress.XSS.EscapeOutput` sniff would erronously trigger when using a fully qualified function call - including the global namespace `\` indicator - to one of the escaping functions. +- The lists of WP global variables and WP mixed case variables have been synchronized, which fixes some false positives. + + ## [0.13.1] - 2017-08-07 ### Fixed @@ -126,9 +187,9 @@ For more detailed information on the most significant changes, please refer to P You are also encouraged to check the file history of any WPCS classes you extend. ### Added -- `WordPress.WP.DeprecatedFunctions` sniff to the `WordPress-Extra` ruleset to check for usage of deprecated WP version and show errors/warnings depending on a `minimum_supported_version` which [can be passed to the sniff from a custom ruleset](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#minimum-wp-version-to-check-for-usage-of-deprecated-functions-and-function-parameters). The default value for the `minimum_supported_version` property is three versions before the current WP version. +- `WordPress.WP.DeprecatedFunctions` sniff to the `WordPress-Extra` ruleset to check for usage of deprecated WP version and show errors/warnings depending on a `minimum_supported_version` which [can be passed to the sniff from a custom ruleset](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#minimum-wp-version-to-check-for-usage-of-deprecated-functions-classes-and-function-parameters). The default value for the `minimum_supported_version` property is three versions before the current WP version. - `WordPress.WP.I18n`: ability to check for missing _translators comments_ when a I18n function call contains translatable text strings containing placeholders. This check will also verify that the _translators comment_ is correctly placed in the code and uses the correct comment type for optimal compatibility with the various tools available to create `.pot` files. -- `WordPress.WP.I18n`: ability to pass the `text_domain` to check for [from the command line](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#setting-text_domain-from-the-command-line). +- `WordPress.WP.I18n`: ability to pass the `text_domain` to check for [from the command line](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#setting-text_domain-from-the-command-line-wpcs-0110). - `WordPress.Arrays.ArrayDeclarationSpacing`: check + fixer for single line associative arrays. The [handbook](https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#indentation) states that these should always be multi-line. - `WordPress.Files.FileName`: verification that files containing a class reflect this in the file name as per the core guidelines. This particular check can be disabled in a custom ruleset by setting the new [`strict_class_file_names` property](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#disregard-class-file-name-rules). - `WordPress.Files.FileName`: verification that files in `/wp-includes/` containing template tags - annotated with `@subpackage Template` in the file header - use the `-template` suffix. @@ -170,7 +231,7 @@ You are also encouraged to check the file history of any WPCS classes you extend - `WordPress.NamingConventions.ValidVariableName`: The `customVariablesWhitelist` property which could be passed from the ruleset has been renamed to [`customPropertiesWhitelist`](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#mixed-case-property-name-exceptions) as it is only usable to whitelist class properties. - `WordPress.WP.I18n`: now allows for an array of text domain names to be passed to the `text_domain` property from a custom ruleset. - `WordPress.WhiteSpace.CastStructureSpacing`: the error level for the checks in this sniff has been raised from `warning` to `error`. -- `WordPress.Variables.GlobalVariables`: will no longer throw errors if the global variable override is done from within a test method. Whether something is considered a "test method" is based on whether the method is in a class which extends a predefined set of known unit test classes. This list can be enhanced by setting the [`custom_test_class_whitelist` property](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#global-variable-overloads-in-unit-tests) in your ruleset. +- `WordPress.Variables.GlobalVariables`: will no longer throw errors if the global variable override is done from within a test method. Whether something is considered a "test method" is based on whether the method is in a class which extends a predefined set of known unit test classes. This list can be enhanced by setting the [`custom_test_class_whitelist` property](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#custom-unit-test-classes) in your ruleset. - The `WordPress.Arrays.ArrayDeclaration` sniff has been split into two sniffs: `WordPress.Arrays.ArrayDeclaration` and `WordPress.Arrays.ArrayDeclarationSpacing` for better compatibility with PHPCS upstream. - The `WordPress.Arrays.ArrayDeclaration` sniff has been synced with the PHPCS upstream version to get the benefit of some bug fixes and improvements which had been made upstream since the sniff was originally copied over. - The `WordPress.VIP.FileSystemWritesDisallow`, `WordPress.VIP.TimezoneChange` and `WordPress.VIP.SessionFunctionsUsage` sniffs now extend the `WordPress_AbstractFunctionRestrictionsSniff`. @@ -463,6 +524,7 @@ See the comparison for full list. Initial tagged release. [Unreleased]: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/compare/master...HEAD +[0.14.0]: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/compare/0.13.1...0.14.0 [0.13.1]: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/compare/0.13.0...0.13.1 [0.13.0]: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/compare/0.12.0...0.13.0 [0.12.0]: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/compare/0.11.0...0.12.0 From 130c0b9833e23a4bf4aebd84d9705929bcc769a9 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Wed, 25 Oct 2017 21:42:32 +0200 Subject: [PATCH 269/282] Changelog/Readme/Contributing: Use the correct parent package name. Also: clarify why suggested dependency minimum requirement got bumped (changelog 0.14.0) --- .github/CONTRIBUTING.md | 6 +++--- CHANGELOG.md | 6 +++--- README.md | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index d54bc427..21ad809e 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -65,12 +65,12 @@ When you introduce a new whitelist comment, please don't forget to update the [w ## Pre-requisites * WordPress-Coding-Standards -* PHP CodeSniffer 2.9.x or 3.x +* PHP_CodeSniffer 2.9.x or 3.x * PHPUnit 4.x, 5.x or 6.x -The WordPress Coding Standards use the PHP CodeSniffer native unit test suite for unit testing the sniffs. +The WordPress Coding Standards use the PHP_CodeSniffer native unit test suite for unit testing the sniffs. -Presuming you have installed PHP CodeSniffer and the WordPress-Coding-Standards as [noted in the README](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards#how-to-use-this), all you need now is `PHPUnit`. +Presuming you have installed PHP_CodeSniffer and the WordPress-Coding-Standards as [noted in the README](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards#how-to-use-this), all you need now is `PHPUnit`. N.B.: If you installed WPCS using Composer, make sure you used `--prefer-source` or run `composer install --prefer-source` now to make sure the unit tests are available. diff --git a/CHANGELOG.md b/CHANGELOG.md index 965eeefd..891f541f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,7 +30,7 @@ _Nothing yet._ - The `is_class_constant()`, `is_class_property` and `valid_direct_scope()` utility methods to the `WordPress\Sniff` class. ### Changed -- When passing an array property via a custom ruleset to PHP Codesniffer, spaces around the key/value are taken as intentional and parsed as part of the array key/value. In practice, this leads to confusion and WPCS does not expect any values which could be preceded/followed by a space, so for the WordPress Coding Standard native array properties, like `customAutoEscapedFunction`, `text_domain`, `prefixes`, WPCS will now trim whitespace from the keys/values received before use. +- When passing an array property via a custom ruleset to PHP_CodeSniffer, spaces around the key/value are taken as intentional and parsed as part of the array key/value. In practice, this leads to confusion and WPCS does not expect any values which could be preceded/followed by a space, so for the WordPress Coding Standard native array properties, like `customAutoEscapedFunction`, `text_domain`, `prefixes`, WPCS will now trim whitespace from the keys/values received before use. - The WPCS native whitelist comments used to only work when they were put on the _end of the line_ of the code they applied to. As of now, they will also be recognized when they are be put at the _end of the statement_ they apply to. - The `WordPress.Arrays.ArrayDeclarationSpacing` sniff used to enforce all associative arrays to be multi-line. The handbook has been updated to only require this for multi-item associative arrays and the sniff has been updated accordingly. [The original behaviour can still be enforced](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Customizable-sniff-properties#arrays-forcing-single-item-associative-arrays-to-be-multi-line) by setting the new `allow_single_item_single_line_associative_arrays` property to `false` in a custom ruleset. @@ -53,7 +53,7 @@ _Nothing yet._ - Improved the Atom setup instructions in the Readme. - Updated the unit testing information in Contributing. - Updated the [custom ruleset example](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/blob/develop/phpcs.xml.dist.sample) for the changes contained in this release and to make it more explicit what is recommended versus example code. -- The minimum recommended version for the suggested `DealerDirect/phpcodesniffer-composer-installer` Composer plugin has gone up to `0.4.3`. +- The minimum recommended version for the suggested `DealerDirect/phpcodesniffer-composer-installer` Composer plugin has gone up to `0.4.3`. This patch version fixes support for PHP 5.3. ### Fixed - The `WordPress.Arrays.ArrayIndentation` sniff did not correctly handle array items with multi-line strings as a value. @@ -77,7 +77,7 @@ _Nothing yet._ ## [0.13.0] - 2017-08-03 ### Added -- Support for PHP CodeSniffer 3.0.2+. The minimum required PHPCS version (2.9.0) stays the same. +- Support for PHP_CodeSniffer 3.0.2+. The minimum required PHPCS version (2.9.0) stays the same. - Support for the PHPCS 3 `--ignore-annotations` command line option. If you pass this option, both PHPCS native `@ignore ...` annotations as well as the WPCS specific [whitelist flags](https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/wiki/Whitelisting-code-which-flags-errors) will be ignored. ### Changed diff --git a/README.md b/README.md index c264b40b..0bde609b 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ This project is a collection of [PHP_CodeSniffer](https://github.com/squizlabs/P ### Requirements -The WordPress Coding Standards require PHP 5.3 or higher and [PHP CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) version **2.9.0** or higher. +The WordPress Coding Standards require PHP 5.3 or higher and [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) version **2.9.0** or higher. As of version 0.13.0, the WordPress Coding Standards are compatible with PHPCS 3.0.2+. In that case, the minimum PHP requirement is PHP 5.4. ### Composer @@ -124,7 +124,7 @@ You can use the following as standard names when invoking `phpcs` to select snif ### Using a custom ruleset -If you need to further customize the selection of sniffs for your project - you can create a custom ruleset file. When you name this file either `phpcs.xml` or `phpcs.xml.dist`, PHP_CodeSniffer will automatically locate it as long as it is placed in the directory from which you run the CodeSniffer or in a directory above it. If you follow these naming conventions you don't have to supply a `--standard` arg. For more info, read about [using a default configuration file](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage#using-a-default-configuration-file). See also provided [`phpcs.xml.dist.sample`](phpcs.xml.dist.sample) file and [fully annotated example](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Annotated-ruleset.xml) in the PHP CodeSniffer documentation. +If you need to further customize the selection of sniffs for your project - you can create a custom ruleset file. When you name this file either `phpcs.xml` or `phpcs.xml.dist`, PHP_CodeSniffer will automatically locate it as long as it is placed in the directory from which you run the CodeSniffer or in a directory above it. If you follow these naming conventions you don't have to supply a `--standard` arg. For more info, read about [using a default configuration file](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage#using-a-default-configuration-file). See also provided [`phpcs.xml.dist.sample`](phpcs.xml.dist.sample) file and [fully annotated example](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Annotated-ruleset.xml) in the PHP_CodeSniffer documentation. ### Customizing sniff behaviour @@ -249,7 +249,7 @@ matrix: before_install: - if [[ "$SNIFF" == "1" ]]; then export PHPCS_DIR=/tmp/phpcs; fi - if [[ "$SNIFF" == "1" ]]; then export SNIFFS_DIR=/tmp/sniffs; fi - # Install PHP CodeSniffer. + # Install PHP_CodeSniffer. - if [[ "$SNIFF" == "1" ]]; then git clone -b master --depth 1 https://github.com/squizlabs/PHP_CodeSniffer.git $PHPCS_DIR; fi # Install WordPress Coding Standards. - if [[ "$SNIFF" == "1" ]]; then git clone -b master --depth 1 https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git $SNIFFS_DIR; fi From 346a6d6436bad6f87c2e5e7f41de56c0f47661a8 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 13 Feb 2018 02:55:00 +0100 Subject: [PATCH 270/282] PrefixAllGlobals: only recognize PHP native classes, don't try and autoload If `class_exists()` and the like are called without the second `$autoload` parameter set to `false`, it could trigger a (Composer) autoload file and in certain circumstances trigger a fatal `class not found` error. If the class however is found and the file also contains side-effects, such as a typical block found at the top of a WP file(see below), it can also trigger a PHPCS process error with a `headers already send` notice. As the check is only intended to detect backfills for PHP native functionality, adding the `$autoload` parameter should fix this. ```php if ( ! function_exists( 'add_filter' ) ) { header( 'Status: 403 Forbidden' ); header( 'HTTP/1.1 403 Forbidden' ); exit(); } ``` --- .../Sniffs/NamingConventions/PrefixAllGlobalsSniff.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php index 25d862ff..82c5a1f1 100644 --- a/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php +++ b/WordPress/Sniffs/NamingConventions/PrefixAllGlobalsSniff.php @@ -247,14 +247,14 @@ public function process_token( $stackPtr ) { switch ( $this->tokens[ $stackPtr ]['type'] ) { case 'T_CLASS': - if ( class_exists( '\\' . $item_name ) ) { + if ( class_exists( '\\' . $item_name, false ) ) { // Backfill for PHP native class. return; } break; case 'T_INTERFACE': - if ( interface_exists( '\\' . $item_name ) ) { + if ( interface_exists( '\\' . $item_name, false ) ) { // Backfill for PHP native interface. return; } @@ -264,7 +264,7 @@ public function process_token( $stackPtr ) { break; case 'T_TRAIT': - if ( function_exists( '\trait_exists' ) && trait_exists( '\\' . $item_name ) ) { + if ( function_exists( '\trait_exists' ) && trait_exists( '\\' . $item_name, false ) ) { // Backfill for PHP native trait. return; } From 94585a1515faec0fea6fc3909796f67e76b400cc Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 15 Feb 2018 19:11:11 +0100 Subject: [PATCH 271/282] Release 0.14.1 This adds the changelog for the 0.14.1 which can be tagged straight after merging this PR. --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 891f541f..48278745 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ This projects adheres to [Semantic Versioning](http://semver.org/) and [Keep a C _Nothing yet._ + +## [0.14.1] - 2018-02-15 + +### Fixed +- The `WordPress.NamingConventions.PrefixAllGlobals` sniff contained a bug which could inadvertently trigger class autoloading of the project being sniffed and by extension could cause fatal errors during the PHPCS run. + ## [0.14.0] - 2017-11-01 ### Added @@ -524,6 +530,7 @@ See the comparison for full list. Initial tagged release. [Unreleased]: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/compare/master...HEAD +[0.14.1]: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/compare/0.14.0...0.14.1 [0.14.0]: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/compare/0.13.1...0.14.0 [0.13.1]: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/compare/0.13.0...0.13.1 [0.13.0]: https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/compare/0.12.0...0.13.0 From e52367ee4dc95554fb1872ecc4fae20e29657df2 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 24 May 2018 04:20:25 +0200 Subject: [PATCH 272/282] DeprecatedWPConstants: Remove sniff in favour of WPCS sniff WPCS 0.14.0 introduced a `WP.DiscouragedConstants` sniff which covers all the constants which were covered by the `DeprecatedWPConstants` sniff and does so better than the original sniff. Removed the `DeprecatedWPConstants` sniff in favour of the new upstream sniff and changing the error level from `warning` to `error` from the ruleset maintains the existing behaviour. Ref: WordPress-Coding-Standards/WordPress-Coding-Standards 1089 --- WordPress-Theme/ruleset.xml | 14 +++ .../Theme/DeprecatedWPConstantsSniff.php | 87 ------------------- .../Theme/DeprecatedWPConstantsUnitTest.inc | 23 ----- .../Theme/DeprecatedWPConstantsUnitTest.php | 49 ----------- 4 files changed, 14 insertions(+), 159 deletions(-) delete mode 100644 WordPress/Sniffs/Theme/DeprecatedWPConstantsSniff.php delete mode 100644 WordPress/Tests/Theme/DeprecatedWPConstantsUnitTest.inc delete mode 100644 WordPress/Tests/Theme/DeprecatedWPConstantsUnitTest.php diff --git a/WordPress-Theme/ruleset.xml b/WordPress-Theme/ruleset.xml index 1d096d22..b1f55116 100644 --- a/WordPress-Theme/ruleset.xml +++ b/WordPress-Theme/ruleset.xml @@ -100,4 +100,18 @@ + + + + + error + + + error + + diff --git a/WordPress/Sniffs/Theme/DeprecatedWPConstantsSniff.php b/WordPress/Sniffs/Theme/DeprecatedWPConstantsSniff.php deleted file mode 100644 index 757e8675..00000000 --- a/WordPress/Sniffs/Theme/DeprecatedWPConstantsSniff.php +++ /dev/null @@ -1,87 +0,0 @@ - 'get_stylesheet_directory()', - 'TEMPLATEPATH' => 'get_template_directory()', - 'PLUGINDIR' => 'WP_PLUGIN_DIR', - 'MUPLUGINDIR' => 'WPMU_PLUGIN_DIR', - 'HEADER_IMAGE' => 'add_theme_support( \'custom-header\' )', - 'NO_HEADER_TEXT' => 'add_theme_support( \'custom-header\' )', - 'HEADER_TEXTCOLOR' => 'add_theme_support( \'custom-header\' )', - 'HEADER_IMAGE_WIDTH' => 'add_theme_support( \'custom-header\' )', - 'HEADER_IMAGE_HEIGHT' => 'add_theme_support( \'custom-header\' )', - 'BACKGROUND_COLOR' => 'add_theme_support( \'custom-background\' )', - 'BACKGROUND_IMAGE' => 'add_theme_support( \'custom-background\' )', - ); - - /** - * Returns an array of tokens this test wants to listen for. - * - * @return array - */ - public function register() { - return array( - T_STRING, - ); - } - - /** - * Processes this test, when one of its tokens is encountered. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. - * - * @return void - */ - public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { - $tokens = $phpcsFile->getTokens(); - $token = $tokens[ $stackPtr ]; - - if ( ! isset( $this->deprecated_constants[ $tokens[ $stackPtr ]['content'] ] ) ) { - return; - } - - $prev = $phpcsFile->findPrevious( T_WHITESPACE, ( $stackPtr - 1 ), null, true ); - - if ( T_DOUBLE_COLON === $tokens[ $prev ]['code'] ) { - // Class constant of the same name. - return; - } - - if ( T_NS_SEPARATOR === $tokens[ $prev ]['code'] && T_STRING === $tokens[ ( $prev - 1 ) ]['code'] ) { - // Namespaced constant of the same name. - return; - } - - // Ok, this is really one of the deprecated constants. - $error = 'Found usage of constant "%s". Use %s instead.'; - $data = array( $tokens[ $stackPtr ]['content'], $this->deprecated_constants[ $tokens[ $stackPtr ]['content'] ] ); - $phpcsFile->addError( $error, $stackPtr, 'Found', $data ); - - } - -} // End class. diff --git a/WordPress/Tests/Theme/DeprecatedWPConstantsUnitTest.inc b/WordPress/Tests/Theme/DeprecatedWPConstantsUnitTest.inc deleted file mode 100644 index e9140dd0..00000000 --- a/WordPress/Tests/Theme/DeprecatedWPConstantsUnitTest.inc +++ /dev/null @@ -1,23 +0,0 @@ - => - */ - public function getErrorList() { - return array( - 9 => ( version_compare( PHP_VERSION, '5.3.0', '>=' ) ? 0 : 1 ), - 13 => 1, - 14 => 1, - 15 => 1, - 16 => 1, - 17 => 1, - 18 => 1, - 19 => 1, - 20 => 1, - 21 => 1, - 22 => 1, - 23 => 1, - ); - } - - /** - * Returns the lines where warnings should occur. - * - * @return array => - */ - public function getWarningList() { - return array(); - } - -} // End class. From c1498bfc9d723c6ea0a2833825eacdbe7fd29ec0 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 24 May 2018 04:39:50 +0200 Subject: [PATCH 273/282] Leverage the WordPress_Sniff class for all sniffs Most WPCS sniffs extend the WordPress_Sniff class or one of the abstract WP sniffs. However there were some which so far didn't. This PR changes that whenever possible. The affected sniffs do not necessarily need to use the WordPress_Sniff class as they don't use any of the utility methods or properties contained therein, however it will make future development slightly more intuitive as (nearly) all sniffs now follow the same pattern. This same change has been made upstream in WordPress-Coding-Standards/WordPress-Coding-Standards 967 --- WordPress/Sniffs/Theme/FileIncludeSniff.php | 18 ++++++------------ WordPress/Sniffs/Theme/NoAutoGenerateSniff.php | 15 +++++---------- WordPress/Sniffs/Theme/NoFaviconSniff.php | 15 +++++---------- 3 files changed, 16 insertions(+), 32 deletions(-) diff --git a/WordPress/Sniffs/Theme/FileIncludeSniff.php b/WordPress/Sniffs/Theme/FileIncludeSniff.php index 9f8a2bae..5924d4d9 100644 --- a/WordPress/Sniffs/Theme/FileIncludeSniff.php +++ b/WordPress/Sniffs/Theme/FileIncludeSniff.php @@ -16,7 +16,7 @@ * * @since 0.xx.0 */ -class WordPress_Sniffs_Theme_FileIncludeSniff implements PHP_CodeSniffer_Sniff { +class WordPress_Sniffs_Theme_FileIncludeSniff extends WordPress_Sniff { /** * A list of files to skip. @@ -39,20 +39,14 @@ public function register() { /** * Processes this test, when one of its tokens is encountered. * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. - * - * @return void + * @param int $stackPtr The position of the current token in the stack. */ - public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { - $tokens = $phpcsFile->getTokens(); - $token = $tokens[ $stackPtr ]; - - $file_name = basename( $phpcsFile->getFileName() ); + public function process_token( $stackPtr ) { + $token = $this->tokens[ $stackPtr ]; + $file_name = basename( $this->phpcsFile->getFileName() ); if ( ! isset( $this->file_whitelist[ $file_name ] ) ) { - $phpcsFile->addWarning( + $this->phpcsFile->addWarning( 'Check that %s is not being used to load template files. "get_template_part()" should be used to load template files.' , $stackPtr, 'FileIncludeFound', diff --git a/WordPress/Sniffs/Theme/NoAutoGenerateSniff.php b/WordPress/Sniffs/Theme/NoAutoGenerateSniff.php index 28dca3b9..39feaf88 100644 --- a/WordPress/Sniffs/Theme/NoAutoGenerateSniff.php +++ b/WordPress/Sniffs/Theme/NoAutoGenerateSniff.php @@ -14,7 +14,7 @@ * * @since 0.xx.0 */ -class WordPress_Sniffs_Theme_NoAutoGenerateSniff implements PHP_CodeSniffer_Sniff { +class WordPress_Sniffs_Theme_NoAutoGenerateSniff extends WordPress_Sniff { /** * A list of tokenizers this sniff supports. @@ -59,16 +59,11 @@ public function register() { /** * Processes this test, when one of its tokens is encountered. * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. - * - * @return void + * @param int $stackPtr The position of the current token in the stack. */ - public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { + public function process_token( $stackPtr ) { - $tokens = $phpcsFile->getTokens(); - $token = $tokens[ $stackPtr ]; + $token = $this->tokens[ $stackPtr ]; $content = trim( strtolower( $token['content'] ) ); // No need to check an empty string. @@ -85,7 +80,7 @@ public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { continue; } - $phpcsFile->addError( + $this->phpcsFile->addError( 'Auto generated themes are not allowed in the theme directory. Found: %s', $stackPtr, 'AutoGeneratedFound', diff --git a/WordPress/Sniffs/Theme/NoFaviconSniff.php b/WordPress/Sniffs/Theme/NoFaviconSniff.php index bd08cda7..7eeea575 100644 --- a/WordPress/Sniffs/Theme/NoFaviconSniff.php +++ b/WordPress/Sniffs/Theme/NoFaviconSniff.php @@ -16,7 +16,7 @@ * * @since 0.xx.0 */ -class WordPress_Sniffs_Theme_NoFaviconSniff implements PHP_CodeSniffer_Sniff { +class WordPress_Sniffs_Theme_NoFaviconSniff extends WordPress_Sniff { /** * Regex template. @@ -94,18 +94,13 @@ public function register() { /** * Processes this test, when one of its tokens is encountered. * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. - * - * @return void + * @param int $stackPtr The position of the current token in the stack. */ - public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { - $tokens = $phpcsFile->getTokens(); - $token = $tokens[ $stackPtr ]; + public function process_token( $stackPtr ) { + $token = $this->tokens[ $stackPtr ]; if ( preg_match( $this->favicon_regex, $token['content'] ) > 0 ) { - $phpcsFile->addError( 'Code for favicon found. Favicons are handled by the "Site Icon" setting in the customizer since version 4.3.' , $stackPtr, 'NoFavicon' ); + $this->phpcsFile->addError( 'Code for favicon found. Favicons are handled by the "Site Icon" setting in the customizer since version 4.3.' , $stackPtr, 'NoFavicon' ); } } From 6010d9c6baf9a1b9edce5bae5459e0cedcbb885b Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 24 May 2018 05:09:01 +0200 Subject: [PATCH 274/282] Documentation: Fix two outdated & incorrect code samples `eval` can not be sniffed for as a function as it is a language construct, not a function, so this was misleading example code. This same change has been made upstream in WordPress-Coding-Standards/WordPress-Coding-Standards 812 --- WordPress/Sniffs/Theme/NoAddAdminPagesSniff.php | 2 +- WordPress/Sniffs/Theme/PluginTerritoryFunctionsSniff.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WordPress/Sniffs/Theme/NoAddAdminPagesSniff.php b/WordPress/Sniffs/Theme/NoAddAdminPagesSniff.php index dec45d48..31254854 100644 --- a/WordPress/Sniffs/Theme/NoAddAdminPagesSniff.php +++ b/WordPress/Sniffs/Theme/NoAddAdminPagesSniff.php @@ -27,7 +27,7 @@ class WordPress_Sniffs_Theme_NoAddAdminPagesSniff extends WordPress_Sniffs_Funct * 'lambda' => array( * 'type' => 'error' | 'warning', * 'message' => 'Use anonymous functions instead please!', - * 'functions' => array( 'eval', 'create_function' ), + * 'functions' => array( 'file_get_contents', 'create_function' ), * ) * ) * diff --git a/WordPress/Sniffs/Theme/PluginTerritoryFunctionsSniff.php b/WordPress/Sniffs/Theme/PluginTerritoryFunctionsSniff.php index e48ccaf7..704b799e 100644 --- a/WordPress/Sniffs/Theme/PluginTerritoryFunctionsSniff.php +++ b/WordPress/Sniffs/Theme/PluginTerritoryFunctionsSniff.php @@ -25,7 +25,7 @@ class WordPress_Sniffs_Theme_PluginTerritoryFunctionsSniff extends WordPress_Abs * 'lambda' => array( * 'type' => 'error' | 'warning', * 'message' => 'Use anonymous functions instead please!', - * 'functions' => array( 'eval', 'create_function' ), + * 'functions' => array( 'file_get_contents', 'create_function' ), * ) * ) * From 0b3a38d9468d7577319fe855bf3302ac418686e5 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 24 May 2018 04:12:45 +0200 Subject: [PATCH 275/282] PHPCS 3.x compat: Ruleset: Make sure the complete sniff is included, not just an errorcode In PHPCS 2.x when a sniff was referenced by errorcode, this automatically included the whole sniff. As of PHPCS 3.x it is possible to selectively include just and only a specific errorcode. This allows for cross-version compat and ensures that if/when new errorcodes are added to the sniffs, they will be included as well. --- WordPress-Theme/ruleset.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WordPress-Theme/ruleset.xml b/WordPress-Theme/ruleset.xml index b1f55116..3f2a3912 100644 --- a/WordPress-Theme/ruleset.xml +++ b/WordPress-Theme/ruleset.xml @@ -58,6 +58,7 @@ once the PR has been merged and the miminmum PHPCS version has been increased. https://github.com/squizlabs/PHP_CodeSniffer/pull/1247 --> + warning @@ -77,6 +78,7 @@ once the PR has been merged and the miminmum PHPCS version has been increased. https://github.com/squizlabs/PHP_CodeSniffer/pull/1247 --> + warning From 74d055e0971b405277b74ec0b6f77c999277baa4 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 24 May 2018 03:59:24 +0200 Subject: [PATCH 276/282] PHPCS 3.x compat: Namespace all sniffs which extend from one of the WPCS base sniffs --- WordPress/Sniffs/Theme/FileIncludeSniff.php | 6 +++++- WordPress/Sniffs/Theme/NoAddAdminPagesSniff.php | 8 +++++--- WordPress/Sniffs/Theme/NoAutoGenerateSniff.php | 6 +++++- WordPress/Sniffs/Theme/NoFaviconSniff.php | 6 +++++- WordPress/Sniffs/Theme/NoTitleTagSniff.php | 6 +++++- WordPress/Sniffs/Theme/PluginTerritoryFunctionsSniff.php | 6 +++++- 6 files changed, 30 insertions(+), 8 deletions(-) diff --git a/WordPress/Sniffs/Theme/FileIncludeSniff.php b/WordPress/Sniffs/Theme/FileIncludeSniff.php index 5924d4d9..cdb1a0df 100644 --- a/WordPress/Sniffs/Theme/FileIncludeSniff.php +++ b/WordPress/Sniffs/Theme/FileIncludeSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\Theme; + +use WordPress\Sniff; + /** * Check if a theme uses include(_once) or require(_once) when get_template_part() should be used. * @@ -16,7 +20,7 @@ * * @since 0.xx.0 */ -class WordPress_Sniffs_Theme_FileIncludeSniff extends WordPress_Sniff { +class FileIncludeSniff extends Sniff { /** * A list of files to skip. diff --git a/WordPress/Sniffs/Theme/NoAddAdminPagesSniff.php b/WordPress/Sniffs/Theme/NoAddAdminPagesSniff.php index 31254854..d8fb53d8 100644 --- a/WordPress/Sniffs/Theme/NoAddAdminPagesSniff.php +++ b/WordPress/Sniffs/Theme/NoAddAdminPagesSniff.php @@ -7,9 +7,11 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\Theme; + +use WordPress\AbstractFunctionRestrictionsSniff; + /** - * WordPress_Sniffs_Theme_NoAddAdminPagesSniff. - * * Forbids the use of add_..._page() functions within Themes with the exception of `add_theme_page()`. * * @link https://make.wordpress.org/themes/handbook/review/required/theme-check-plugin/#admin-menu @@ -18,7 +20,7 @@ * * @since 0.xx.0 */ -class WordPress_Sniffs_Theme_NoAddAdminPagesSniff extends WordPress_Sniffs_Functions_FunctionRestrictionsSniff { +class NoAddAdminPagesSniff extends AbstractFunctionRestrictionsSniff { /** * Groups of functions to restrict. diff --git a/WordPress/Sniffs/Theme/NoAutoGenerateSniff.php b/WordPress/Sniffs/Theme/NoAutoGenerateSniff.php index 39feaf88..c42ba189 100644 --- a/WordPress/Sniffs/Theme/NoAutoGenerateSniff.php +++ b/WordPress/Sniffs/Theme/NoAutoGenerateSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\Theme; + +use WordPress\Sniff; + /** * Check for auto generated themes. * @@ -14,7 +18,7 @@ * * @since 0.xx.0 */ -class WordPress_Sniffs_Theme_NoAutoGenerateSniff extends WordPress_Sniff { +class NoAutoGenerateSniff extends Sniff { /** * A list of tokenizers this sniff supports. diff --git a/WordPress/Sniffs/Theme/NoFaviconSniff.php b/WordPress/Sniffs/Theme/NoFaviconSniff.php index 7eeea575..2dae4a7d 100644 --- a/WordPress/Sniffs/Theme/NoFaviconSniff.php +++ b/WordPress/Sniffs/Theme/NoFaviconSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\Theme; + +use WordPress\Sniff; + /** * Check for hardcoded favicons instead of using core implementation. * @@ -16,7 +20,7 @@ * * @since 0.xx.0 */ -class WordPress_Sniffs_Theme_NoFaviconSniff extends WordPress_Sniff { +class NoFaviconSniff extends Sniff { /** * Regex template. diff --git a/WordPress/Sniffs/Theme/NoTitleTagSniff.php b/WordPress/Sniffs/Theme/NoTitleTagSniff.php index 6f4859cc..48f39d77 100644 --- a/WordPress/Sniffs/Theme/NoTitleTagSniff.php +++ b/WordPress/Sniffs/Theme/NoTitleTagSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\Theme; + +use WordPress\Sniff; + /** * Restricts the use of the tag, unless it is within a <svg> tag. * @@ -16,7 +20,7 @@ * * @since 0.xx.0 */ -class WordPress_Sniffs_Theme_NoTitleTagSniff extends WordPress_Sniff { +class NoTitleTagSniff extends Sniff { /** * Property to keep track of whether a <svg> open tag has been encountered. diff --git a/WordPress/Sniffs/Theme/PluginTerritoryFunctionsSniff.php b/WordPress/Sniffs/Theme/PluginTerritoryFunctionsSniff.php index 704b799e..81b41acd 100644 --- a/WordPress/Sniffs/Theme/PluginTerritoryFunctionsSniff.php +++ b/WordPress/Sniffs/Theme/PluginTerritoryFunctionsSniff.php @@ -7,6 +7,10 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Sniffs\Theme; + +use WordPress\AbstractFunctionRestrictionsSniff; + /** * Restricts the use of various functions that are plugin territory. * @@ -16,7 +20,7 @@ * * @since 0.xx.0 */ -class WordPress_Sniffs_Theme_PluginTerritoryFunctionsSniff extends WordPress_AbstractFunctionRestrictionsSniff { +class PluginTerritoryFunctionsSniff extends AbstractFunctionRestrictionsSniff { /** * Groups of functions to restrict. From f3af6ac1f1aa81f6f852a04acfa9cc9e7a9440d3 Mon Sep 17 00:00:00 2001 From: jrfnl <jrfnl@users.noreply.github.com> Date: Thu, 24 May 2018 04:46:33 +0200 Subject: [PATCH 277/282] PHPCS 3.x compat: Fix all references to upstream PHPCS classes * Add use statements for all PHPCS class references. * Where possible use the PHPCS 3.x class name as a use alias to make the future change of dropping 2.x support easier. --- WordPress/Sniffs/Theme/FileIncludeSniff.php | 3 ++- WordPress/Sniffs/Theme/NoAutoGenerateSniff.php | 3 ++- WordPress/Sniffs/Theme/NoFaviconSniff.php | 3 ++- WordPress/Sniffs/Theme/NoTitleTagSniff.php | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/WordPress/Sniffs/Theme/FileIncludeSniff.php b/WordPress/Sniffs/Theme/FileIncludeSniff.php index cdb1a0df..177b7f49 100644 --- a/WordPress/Sniffs/Theme/FileIncludeSniff.php +++ b/WordPress/Sniffs/Theme/FileIncludeSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\Theme; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Check if a theme uses include(_once) or require(_once) when get_template_part() should be used. @@ -37,7 +38,7 @@ class FileIncludeSniff extends Sniff { * @return array */ public function register() { - return PHP_CodeSniffer_Tokens::$includeTokens; + return Tokens::$includeTokens; } /** diff --git a/WordPress/Sniffs/Theme/NoAutoGenerateSniff.php b/WordPress/Sniffs/Theme/NoAutoGenerateSniff.php index c42ba189..4359dacd 100644 --- a/WordPress/Sniffs/Theme/NoAutoGenerateSniff.php +++ b/WordPress/Sniffs/Theme/NoAutoGenerateSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\Theme; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Check for auto generated themes. @@ -50,7 +51,7 @@ class NoAutoGenerateSniff extends Sniff { * @return array */ public function register() { - $tokens = PHP_CodeSniffer_Tokens::$stringTokens; + $tokens = Tokens::$stringTokens; $tokens[] = T_INLINE_HTML; $tokens[] = T_HEREDOC; $tokens[] = T_STRING; // Functions named after or prefixed with the generator name. diff --git a/WordPress/Sniffs/Theme/NoFaviconSniff.php b/WordPress/Sniffs/Theme/NoFaviconSniff.php index 2dae4a7d..44044360 100644 --- a/WordPress/Sniffs/Theme/NoFaviconSniff.php +++ b/WordPress/Sniffs/Theme/NoFaviconSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\Theme; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Check for hardcoded favicons instead of using core implementation. @@ -87,7 +88,7 @@ public function register() { $this->favicon_regex = sprintf( self::REGEX_TEMPLATE, implode( '|', $regex_parts ) ); - $tokens = PHP_CodeSniffer_Tokens::$stringTokens; + $tokens = Tokens::$stringTokens; $tokens[] = T_INLINE_HTML; $tokens[] = T_HEREDOC; $tokens[] = T_NOWDOC; diff --git a/WordPress/Sniffs/Theme/NoTitleTagSniff.php b/WordPress/Sniffs/Theme/NoTitleTagSniff.php index 48f39d77..04ced8fd 100644 --- a/WordPress/Sniffs/Theme/NoTitleTagSniff.php +++ b/WordPress/Sniffs/Theme/NoTitleTagSniff.php @@ -10,6 +10,7 @@ namespace WordPress\Sniffs\Theme; use WordPress\Sniff; +use PHP_CodeSniffer_Tokens as Tokens; /** * Restricts the use of the <title> tag, unless it is within a <svg> tag. @@ -35,7 +36,7 @@ class NoTitleTagSniff extends Sniff { * @return array */ public function register() { - $tokens = PHP_CodeSniffer_Tokens::$stringTokens; + $tokens = Tokens::$stringTokens; $tokens[ T_INLINE_HTML ] = T_INLINE_HTML; $tokens[ T_HEREDOC ] = T_HEREDOC; $tokens[ T_NOWDOC ] = T_NOWDOC; From 33d0188830ad19931b4a7d2aeb46ea07df70fee0 Mon Sep 17 00:00:00 2001 From: jrfnl <jrfnl@users.noreply.github.com> Date: Thu, 24 May 2018 04:51:50 +0200 Subject: [PATCH 278/282] PHPCS 3.x compat: Add autoload directive for the alias file The `<autoload>` ruleset directive was added in PHPCS 3.0.1 in response to issue squizlabs/PHP_CodeSniffer#1469 --- WordPress-Theme/ruleset.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WordPress-Theme/ruleset.xml b/WordPress-Theme/ruleset.xml index 3f2a3912..3df97bcc 100644 --- a/WordPress-Theme/ruleset.xml +++ b/WordPress-Theme/ruleset.xml @@ -3,6 +3,8 @@ <!-- For more information: https://make.wordpress.org/themes/handbook/review/ --> <description>Standards any Theme to be published on wordpress.org should comply with.</description> + <autoload>./../WordPress/PHPCSAliases.php</autoload> + <rule ref="WordPress.Theme"/> <!-- No PHP short open tags allowed. --> From 462cc0edd60323a237954410ad4dcbb993e3a14a Mon Sep 17 00:00:00 2001 From: jrfnl <jrfnl@users.noreply.github.com> Date: Thu, 24 May 2018 04:56:20 +0200 Subject: [PATCH 279/282] PHPCS 3.x compat: Namespace all unit tests --- WordPress/Tests/Theme/FileIncludeUnitTest.php | 6 +++++- WordPress/Tests/Theme/NoAddAdminPagesUnitTest.php | 6 +++++- WordPress/Tests/Theme/NoAutoGenerateUnitTest.php | 6 +++++- WordPress/Tests/Theme/NoFaviconUnitTest.php | 6 +++++- WordPress/Tests/Theme/NoTitleTagUnitTest.php | 6 +++++- WordPress/Tests/Theme/PluginTerritoryFunctionsUnitTest.php | 6 +++++- 6 files changed, 30 insertions(+), 6 deletions(-) diff --git a/WordPress/Tests/Theme/FileIncludeUnitTest.php b/WordPress/Tests/Theme/FileIncludeUnitTest.php index 562dbe00..3f29d8b7 100644 --- a/WordPress/Tests/Theme/FileIncludeUnitTest.php +++ b/WordPress/Tests/Theme/FileIncludeUnitTest.php @@ -7,13 +7,17 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Tests\Theme; + +use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; + /** * Unit test class for the Theme_FileInclude sniff. * * @package WPCS\WordPressCodingStandards * @since 0.xx.0 */ -class WordPress_Tests_Theme_FileIncludeUnitTest extends AbstractSniffUnitTest { +class FileIncludeUnitTest extends AbstractSniffUnitTest { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/Theme/NoAddAdminPagesUnitTest.php b/WordPress/Tests/Theme/NoAddAdminPagesUnitTest.php index 7bd67cd1..a0487fd5 100644 --- a/WordPress/Tests/Theme/NoAddAdminPagesUnitTest.php +++ b/WordPress/Tests/Theme/NoAddAdminPagesUnitTest.php @@ -7,13 +7,17 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Tests\Theme; + +use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; + /** * Unit test class for the NoAddAdminPages sniff. * * @package WPCS\WordPressCodingStandards * @since 0.xx.0 */ -class WordPress_Tests_Theme_NoAddAdminPagesUnitTest extends AbstractSniffUnitTest { +class NoAddAdminPagesUnitTest extends AbstractSniffUnitTest { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/Theme/NoAutoGenerateUnitTest.php b/WordPress/Tests/Theme/NoAutoGenerateUnitTest.php index 6cea5e98..f59e22ee 100644 --- a/WordPress/Tests/Theme/NoAutoGenerateUnitTest.php +++ b/WordPress/Tests/Theme/NoAutoGenerateUnitTest.php @@ -7,13 +7,17 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Tests\Theme; + +use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; + /** * Unit test class for the Theme_NoAutoGenerate sniff. * * @package WPCS\WordPressCodingStandards * @since 0.xx.0 */ -class WordPress_Tests_Theme_NoAutoGenerateUnitTest extends AbstractSniffUnitTest { +class NoAutoGenerateUnitTest extends AbstractSniffUnitTest { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/Theme/NoFaviconUnitTest.php b/WordPress/Tests/Theme/NoFaviconUnitTest.php index 5057965a..b65fed1b 100644 --- a/WordPress/Tests/Theme/NoFaviconUnitTest.php +++ b/WordPress/Tests/Theme/NoFaviconUnitTest.php @@ -7,13 +7,17 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Tests\Theme; + +use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; + /** * Unit test class for the NoFavicon sniff. * * @package WPCS\WordPressCodingStandards * @since 0.xx.0 */ -class WordPress_Tests_Theme_NoFaviconUnitTest extends AbstractSniffUnitTest { +class NoFaviconUnitTest extends AbstractSniffUnitTest { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/Theme/NoTitleTagUnitTest.php b/WordPress/Tests/Theme/NoTitleTagUnitTest.php index e0a19f89..acf8ef67 100644 --- a/WordPress/Tests/Theme/NoTitleTagUnitTest.php +++ b/WordPress/Tests/Theme/NoTitleTagUnitTest.php @@ -7,13 +7,17 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Tests\Theme; + +use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; + /** * Unit test class for the NoTitleTag sniff. * * @package WPCS\WordPressCodingStandards * @since 0.xx.0 */ -class WordPress_Tests_Theme_NoTitleTagUnitTest extends AbstractSniffUnitTest { +class NoTitleTagUnitTest extends AbstractSniffUnitTest { /** * Returns the lines where errors should occur. diff --git a/WordPress/Tests/Theme/PluginTerritoryFunctionsUnitTest.php b/WordPress/Tests/Theme/PluginTerritoryFunctionsUnitTest.php index 5cc8d310..af55358d 100644 --- a/WordPress/Tests/Theme/PluginTerritoryFunctionsUnitTest.php +++ b/WordPress/Tests/Theme/PluginTerritoryFunctionsUnitTest.php @@ -7,13 +7,17 @@ * @license https://opensource.org/licenses/MIT MIT */ +namespace WordPress\Tests\Theme; + +use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; + /** * Unit test class for the PluginTerritoryFunctions sniff. * * @package WPCS\WordPressCodingStandards * @since 0.xx.0 */ -class WordPress_Tests_Theme_PluginTerritoryFunctionsUnitTest extends AbstractSniffUnitTest { +class PluginTerritoryFunctionsUnitTest extends AbstractSniffUnitTest { /** * Returns the lines where errors should occur. From 19de6343e9be2139c77875f6a51c0d039544b9de Mon Sep 17 00:00:00 2001 From: jrfnl <jrfnl@users.noreply.github.com> Date: Thu, 24 May 2018 05:10:11 +0200 Subject: [PATCH 280/282] PHPCS 3.x compat: Remove test conditionals for PHP 5.2 --- WordPress/Tests/Theme/NoFaviconUnitTest.php | 4 ++-- WordPress/Tests/Theme/NoTitleTagUnitTest.php | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/WordPress/Tests/Theme/NoFaviconUnitTest.php b/WordPress/Tests/Theme/NoFaviconUnitTest.php index b65fed1b..4b7f5c2c 100644 --- a/WordPress/Tests/Theme/NoFaviconUnitTest.php +++ b/WordPress/Tests/Theme/NoFaviconUnitTest.php @@ -39,8 +39,8 @@ public function getErrorList() { 21 => 1, 24 => 1, 25 => 1, - 29 => ( PHP_VERSION_ID >= 50300 ) ? 1 : 0, // PHPCS on PHP 5.2 does not recognize T_NOWDOC. - 30 => ( PHP_VERSION_ID >= 50300 ) ? 1 : 0, // PHPCS on PHP 5.2 does not recognize T_NOWDOC. + 29 => 1, + 30 => 1, ); } diff --git a/WordPress/Tests/Theme/NoTitleTagUnitTest.php b/WordPress/Tests/Theme/NoTitleTagUnitTest.php index acf8ef67..2aa284f4 100644 --- a/WordPress/Tests/Theme/NoTitleTagUnitTest.php +++ b/WordPress/Tests/Theme/NoTitleTagUnitTest.php @@ -32,14 +32,13 @@ public function getErrorList() { 24 => 1, 26 => 1, 28 => 1, - // PHP 5.2 has an issue tokenizing `<s` so splits the string into two. - 30 => ( PHP_VERSION_ID >= 50300 ) ? 1 : 2, + 30 => 1, 34 => 1, 37 => 1, 40 => 1, 43 => 1, - 47 => ( PHP_VERSION_ID >= 50300 ) ? 1 : 0, // PHPCS on PHP 5.2 does not recognize T_NOWDOC. - 50 => ( PHP_VERSION_ID >= 50300 ) ? 1 : 0, // PHPCS on PHP 5.2 does not recognize T_NOWDOC. + 47 => 1, + 50 => 1, ); } From 6624d5da63df2492ab0e331b337a8d21486f4405 Mon Sep 17 00:00:00 2001 From: jrfnl <jrfnl@users.noreply.github.com> Date: Thu, 24 May 2018 04:41:14 +0200 Subject: [PATCH 281/282] Minor code layout & code style fixes --- WordPress/Sniffs/Theme/FileIncludeSniff.php | 2 +- WordPress/Sniffs/Theme/NoAddAdminPagesSniff.php | 11 +++++------ WordPress/Sniffs/Theme/NoFaviconSniff.php | 10 +++++++--- WordPress/Sniffs/Theme/NoTitleTagSniff.php | 8 ++++++-- .../Sniffs/Theme/PluginTerritoryFunctionsSniff.php | 11 +++++------ WordPress/Tests/Theme/NoAddAdminPagesUnitTest.php | 8 ++++---- WordPress/Tests/Theme/NoFaviconUnitTest.php | 4 ++-- WordPress/Tests/Theme/NoTitleTagUnitTest.php | 6 ++---- .../Tests/Theme/PluginTerritoryFunctionsUnitTest.php | 2 -- 9 files changed, 32 insertions(+), 30 deletions(-) diff --git a/WordPress/Sniffs/Theme/FileIncludeSniff.php b/WordPress/Sniffs/Theme/FileIncludeSniff.php index 177b7f49..cb4393f4 100644 --- a/WordPress/Sniffs/Theme/FileIncludeSniff.php +++ b/WordPress/Sniffs/Theme/FileIncludeSniff.php @@ -52,7 +52,7 @@ public function process_token( $stackPtr ) { if ( ! isset( $this->file_whitelist[ $file_name ] ) ) { $this->phpcsFile->addWarning( - 'Check that %s is not being used to load template files. "get_template_part()" should be used to load template files.' , + 'Check that %s is not being used to load template files. "get_template_part()" should be used to load template files.', $stackPtr, 'FileIncludeFound', array( $token['content'] ) diff --git a/WordPress/Sniffs/Theme/NoAddAdminPagesSniff.php b/WordPress/Sniffs/Theme/NoAddAdminPagesSniff.php index d8fb53d8..162525f2 100644 --- a/WordPress/Sniffs/Theme/NoAddAdminPagesSniff.php +++ b/WordPress/Sniffs/Theme/NoAddAdminPagesSniff.php @@ -26,18 +26,17 @@ class NoAddAdminPagesSniff extends AbstractFunctionRestrictionsSniff { * Groups of functions to restrict. * * Example: groups => array( - * 'lambda' => array( - * 'type' => 'error' | 'warning', - * 'message' => 'Use anonymous functions instead please!', - * 'functions' => array( 'file_get_contents', 'create_function' ), - * ) + * 'lambda' => array( + * 'type' => 'error' | 'warning', + * 'message' => 'Use anonymous functions instead please!', + * 'functions' => array( 'file_get_contents', 'create_function' ), + * ) * ) * * @return array */ public function getGroups() { return array( - 'add_menu_pages' => array( 'type' => 'error', 'message' => 'Themes should use <strong>add_theme_page()</strong> for adding admin pages. Found %s.', diff --git a/WordPress/Sniffs/Theme/NoFaviconSniff.php b/WordPress/Sniffs/Theme/NoFaviconSniff.php index 44044360..0a689bfe 100644 --- a/WordPress/Sniffs/Theme/NoFaviconSniff.php +++ b/WordPress/Sniffs/Theme/NoFaviconSniff.php @@ -81,8 +81,8 @@ public function register() { $regex_parts = array(); foreach ( $this->attribute_blacklist as $key => $values ) { - $values = array_map( 'preg_quote', $values, array_fill( 0, count( $values ), '`' ) ); - $values = implode( '|', $values ); + $values = array_map( 'preg_quote', $values, array_fill( 0, count( $values ), '`' ) ); + $values = implode( '|', $values ); $regex_parts[] = sprintf( self::REGEX_ATTR_TEMPLATE, preg_quote( $key, '`' ), $values ); } @@ -105,7 +105,11 @@ public function process_token( $stackPtr ) { $token = $this->tokens[ $stackPtr ]; if ( preg_match( $this->favicon_regex, $token['content'] ) > 0 ) { - $this->phpcsFile->addError( 'Code for favicon found. Favicons are handled by the "Site Icon" setting in the customizer since version 4.3.' , $stackPtr, 'NoFavicon' ); + $this->phpcsFile->addError( + 'Code for favicon found. Favicons are handled by the "Site Icon" setting in the customizer since WP version 4.3.', + $stackPtr, + 'NoFavicon' + ); } } diff --git a/WordPress/Sniffs/Theme/NoTitleTagSniff.php b/WordPress/Sniffs/Theme/NoTitleTagSniff.php index 04ced8fd..8945db1a 100644 --- a/WordPress/Sniffs/Theme/NoTitleTagSniff.php +++ b/WordPress/Sniffs/Theme/NoTitleTagSniff.php @@ -82,7 +82,7 @@ public function process_token( $stackPtr ) { // Skip the next lines until the closing svg tag, but do check any content // on this line before the svg tag. $this->in_svg[ $filename ] = true; - $content = trim( substr( $content, 0, ( strpos( $content, '<svg' ) ) ) ); + $content = trim( substr( $content, 0, ( strpos( $content, '<svg' ) ) ) ); } else { // Ok, we have open and close svg tag on the same line with possibly content before and/or after. $before = trim( substr( $content, 0, ( strpos( $content, '<svg' ) ) ) ); @@ -93,7 +93,11 @@ public function process_token( $stackPtr ) { // Now let's do the check for the <title> tag. if ( false !== strpos( $content, '<title' ) ) { - $this->phpcsFile->addError( "The title tag must not be used. Use add_theme_support( 'title-tag' ) instead.", $stackPtr, 'TagFound' ); + $this->phpcsFile->addError( + "The title tag must not be used. Use add_theme_support( 'title-tag' ) instead.", + $stackPtr, + 'TagFound' + ); } } // End process(). diff --git a/WordPress/Sniffs/Theme/PluginTerritoryFunctionsSniff.php b/WordPress/Sniffs/Theme/PluginTerritoryFunctionsSniff.php index 81b41acd..e2575ed2 100644 --- a/WordPress/Sniffs/Theme/PluginTerritoryFunctionsSniff.php +++ b/WordPress/Sniffs/Theme/PluginTerritoryFunctionsSniff.php @@ -26,11 +26,11 @@ class PluginTerritoryFunctionsSniff extends AbstractFunctionRestrictionsSniff { * Groups of functions to restrict. * * Example: groups => array( - * 'lambda' => array( - * 'type' => 'error' | 'warning', - * 'message' => 'Use anonymous functions instead please!', - * 'functions' => array( 'file_get_contents', 'create_function' ), - * ) + * 'lambda' => array( + * 'type' => 'error' | 'warning', + * 'message' => 'Use anonymous functions instead please!', + * 'functions' => array( 'file_get_contents', 'create_function' ), + * ) * ) * * @return array @@ -49,7 +49,6 @@ public function getGroups() { ), ), ); - } } // End class. diff --git a/WordPress/Tests/Theme/NoAddAdminPagesUnitTest.php b/WordPress/Tests/Theme/NoAddAdminPagesUnitTest.php index a0487fd5..5f0e643d 100644 --- a/WordPress/Tests/Theme/NoAddAdminPagesUnitTest.php +++ b/WordPress/Tests/Theme/NoAddAdminPagesUnitTest.php @@ -26,10 +26,10 @@ class NoAddAdminPagesUnitTest extends AbstractSniffUnitTest { */ public function getErrorList() { return array( - 4 => 1, - 5 => 1, - 6 => 1, - 9 => 1, + 4 => 1, + 5 => 1, + 6 => 1, + 9 => 1, 12 => 1, 13 => 1, 14 => 1, diff --git a/WordPress/Tests/Theme/NoFaviconUnitTest.php b/WordPress/Tests/Theme/NoFaviconUnitTest.php index 4b7f5c2c..d8a6295b 100644 --- a/WordPress/Tests/Theme/NoFaviconUnitTest.php +++ b/WordPress/Tests/Theme/NoFaviconUnitTest.php @@ -26,8 +26,8 @@ class NoFaviconUnitTest extends AbstractSniffUnitTest { */ public function getErrorList() { return array( - 8 => 1, - 9 => 1, + 8 => 1, + 9 => 1, 10 => 1, 11 => 1, 12 => 1, diff --git a/WordPress/Tests/Theme/NoTitleTagUnitTest.php b/WordPress/Tests/Theme/NoTitleTagUnitTest.php index 2aa284f4..ad57357f 100644 --- a/WordPress/Tests/Theme/NoTitleTagUnitTest.php +++ b/WordPress/Tests/Theme/NoTitleTagUnitTest.php @@ -26,8 +26,8 @@ class NoTitleTagUnitTest extends AbstractSniffUnitTest { */ public function getErrorList() { return array( - 7 => 1, - 9 => 1, + 7 => 1, + 9 => 1, 19 => 1, 24 => 1, 26 => 1, @@ -40,7 +40,6 @@ public function getErrorList() { 47 => 1, 50 => 1, ); - } /** @@ -50,7 +49,6 @@ public function getErrorList() { */ public function getWarningList() { return array(); - } } // End class. diff --git a/WordPress/Tests/Theme/PluginTerritoryFunctionsUnitTest.php b/WordPress/Tests/Theme/PluginTerritoryFunctionsUnitTest.php index af55358d..6dc1e1c9 100644 --- a/WordPress/Tests/Theme/PluginTerritoryFunctionsUnitTest.php +++ b/WordPress/Tests/Theme/PluginTerritoryFunctionsUnitTest.php @@ -32,7 +32,6 @@ public function getErrorList() { 6 => 1, 7 => 1, ); - } /** @@ -42,7 +41,6 @@ public function getErrorList() { */ public function getWarningList() { return array(); - } } // End class. From 424dea37d339c4fb4ddcbb4e5b52ef7ae964ebd4 Mon Sep 17 00:00:00 2001 From: jrfnl <jrfnl@users.noreply.github.com> Date: Fri, 25 May 2018 01:55:23 +0200 Subject: [PATCH 282/282] Clean up: Remove `// end` comments The upstream CommentedOutCode sniff has been updated and become more accurate and now throws a number of warnings for // End ... comments. As the rule regarding end comments has been removed from the handbook anyway, we may as well remove them all and get rid of the warnings. This same change has been made upstream in WordPress-Coding-Standards/WordPress-Coding-Standards 1362 --- WordPress/Sniffs/Theme/NoAddAdminPagesSniff.php | 2 +- WordPress/Sniffs/Theme/NoTitleTagSniff.php | 5 ++--- WordPress/Sniffs/Theme/PluginTerritoryFunctionsSniff.php | 2 +- WordPress/Tests/Theme/FileIncludeUnitTest.php | 2 +- WordPress/Tests/Theme/NoAddAdminPagesUnitTest.php | 2 +- WordPress/Tests/Theme/NoAutoGenerateUnitTest.php | 2 +- WordPress/Tests/Theme/NoFaviconUnitTest.php | 2 +- WordPress/Tests/Theme/NoTitleTagUnitTest.php | 2 +- WordPress/Tests/Theme/PluginTerritoryFunctionsUnitTest.php | 2 +- 9 files changed, 10 insertions(+), 11 deletions(-) diff --git a/WordPress/Sniffs/Theme/NoAddAdminPagesSniff.php b/WordPress/Sniffs/Theme/NoAddAdminPagesSniff.php index 162525f2..60cca8cf 100644 --- a/WordPress/Sniffs/Theme/NoAddAdminPagesSniff.php +++ b/WordPress/Sniffs/Theme/NoAddAdminPagesSniff.php @@ -64,4 +64,4 @@ public function getGroups() { ); } -} // End class. +} diff --git a/WordPress/Sniffs/Theme/NoTitleTagSniff.php b/WordPress/Sniffs/Theme/NoTitleTagSniff.php index 8945db1a..de75f84a 100644 --- a/WordPress/Sniffs/Theme/NoTitleTagSniff.php +++ b/WordPress/Sniffs/Theme/NoTitleTagSniff.php @@ -99,7 +99,6 @@ public function process_token( $stackPtr ) { 'TagFound' ); } + } - } // End process(). - -} // End Class. +} diff --git a/WordPress/Sniffs/Theme/PluginTerritoryFunctionsSniff.php b/WordPress/Sniffs/Theme/PluginTerritoryFunctionsSniff.php index e2575ed2..b4a8c8a3 100644 --- a/WordPress/Sniffs/Theme/PluginTerritoryFunctionsSniff.php +++ b/WordPress/Sniffs/Theme/PluginTerritoryFunctionsSniff.php @@ -51,4 +51,4 @@ public function getGroups() { ); } -} // End class. +} diff --git a/WordPress/Tests/Theme/FileIncludeUnitTest.php b/WordPress/Tests/Theme/FileIncludeUnitTest.php index 3f29d8b7..bbb53174 100644 --- a/WordPress/Tests/Theme/FileIncludeUnitTest.php +++ b/WordPress/Tests/Theme/FileIncludeUnitTest.php @@ -44,4 +44,4 @@ public function getWarningList() { ); } -} // End class. +} diff --git a/WordPress/Tests/Theme/NoAddAdminPagesUnitTest.php b/WordPress/Tests/Theme/NoAddAdminPagesUnitTest.php index 5f0e643d..5ad1ae12 100644 --- a/WordPress/Tests/Theme/NoAddAdminPagesUnitTest.php +++ b/WordPress/Tests/Theme/NoAddAdminPagesUnitTest.php @@ -51,4 +51,4 @@ public function getWarningList() { return array(); } -} // End class. +} diff --git a/WordPress/Tests/Theme/NoAutoGenerateUnitTest.php b/WordPress/Tests/Theme/NoAutoGenerateUnitTest.php index f59e22ee..dd66f8da 100644 --- a/WordPress/Tests/Theme/NoAutoGenerateUnitTest.php +++ b/WordPress/Tests/Theme/NoAutoGenerateUnitTest.php @@ -70,4 +70,4 @@ public function getWarningList() { return array(); } -} // End class. +} diff --git a/WordPress/Tests/Theme/NoFaviconUnitTest.php b/WordPress/Tests/Theme/NoFaviconUnitTest.php index d8a6295b..ad561e73 100644 --- a/WordPress/Tests/Theme/NoFaviconUnitTest.php +++ b/WordPress/Tests/Theme/NoFaviconUnitTest.php @@ -53,4 +53,4 @@ public function getWarningList() { return array(); } -} // End class. +} diff --git a/WordPress/Tests/Theme/NoTitleTagUnitTest.php b/WordPress/Tests/Theme/NoTitleTagUnitTest.php index ad57357f..750b46bf 100644 --- a/WordPress/Tests/Theme/NoTitleTagUnitTest.php +++ b/WordPress/Tests/Theme/NoTitleTagUnitTest.php @@ -51,4 +51,4 @@ public function getWarningList() { return array(); } -} // End class. +} diff --git a/WordPress/Tests/Theme/PluginTerritoryFunctionsUnitTest.php b/WordPress/Tests/Theme/PluginTerritoryFunctionsUnitTest.php index 6dc1e1c9..02cba2e0 100644 --- a/WordPress/Tests/Theme/PluginTerritoryFunctionsUnitTest.php +++ b/WordPress/Tests/Theme/PluginTerritoryFunctionsUnitTest.php @@ -43,4 +43,4 @@ public function getWarningList() { return array(); } -} // End class. +}