diff --git a/WPThemeReview/Sniffs/CoreFunctionality/PrefixAllGlobalsSniff.php b/WPThemeReview/Sniffs/CoreFunctionality/PrefixAllGlobalsSniff.php new file mode 100644 index 00000000..b50716d8 --- /dev/null +++ b/WPThemeReview/Sniffs/CoreFunctionality/PrefixAllGlobalsSniff.php @@ -0,0 +1,188 @@ + true, + 'archive.php' => true, + 'home.php' => true, + 'index.php' => true, + 'page.php' => true, + 'search.php' => true, + 'single.php' => true, + 'singular.php' => true, + + // Plain secondary template file names. + 'attachment.php' => true, + 'author.php' => true, + 'category.php' => true, + 'date.php' => true, + 'embed.php' => true, + 'front-page.php' => true, + 'single-post.php' => true, + 'tag.php' => true, + 'taxonomy.php' => true, + + // Plain partial and miscellaneous template file names. + 'comments.php' => true, + 'footer.php' => true, + 'header.php' => true, + 'sidebar.php' => true, + + // Top-leve mime types. + 'application.php' => true, + 'audio.php' => true, + 'example.php' => true, + 'font.php' => true, + 'image.php' => true, + 'message.php' => true, + 'model.php' => true, + 'multipart.php' => true, + 'text.php' => true, + 'video.php' => true, + ]; + + /** + * Check that defined global variables are prefixed. + * + * This overloads the parent method to allow for non-prefixed variables to be declared + * in template files as those are included from within a function and therefore would be + * local to that function. + * + * @since 0.2.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 ) { + + // Usage of `strip_quotes` is to ensure `stdin_path` passed by IDEs does not include quotes. + $file = $this->strip_quotes( $this->phpcsFile->getFileName() ); + + $fileName = basename( $file ); + + if ( \defined( '\PHP_CODESNIFFER_IN_TESTS' ) ) { + $fileName = str_replace( '.inc', '.php', $fileName ); + } + + // Don't process in case of a template file or folder. + if ( isset( $this->simple_theme_template_file_names[ $fileName ] ) === true ) { + return; + } + + if ( preg_match( self::COMPLEX_THEME_TEMPLATE_NAME_REGEX, $fileName ) === 1 ) { + return; + } + + if ( $this->is_from_allowed_folder( $file ) ) { + return; + } + + // Not a typical template file name, defer to the prefix checking in the parent sniff. + return parent::process_variable_assignment( $stackPtr ); + } + + /** + * Checks if the given file path is located in the $allowed_folders array. + * + * @since 0.2.0 + * + * @param string $path Full path of the sniffed file. + * @return boolean + */ + private function is_from_allowed_folder( $path ) { + if ( empty( $this->allowed_folders ) || ! is_array( $this->allowed_folders ) ) { + return false; + } + + foreach ( $this->allowed_folders as $folder ) { + if ( strrpos( $path, DIRECTORY_SEPARATOR . $folder . DIRECTORY_SEPARATOR ) !== false ) { + return true; + } + } + + return false; + } +} diff --git a/WPThemeReview/Tests/CoreFunctionality/PrefixAllGlobalsTests/attachment.inc b/WPThemeReview/Tests/CoreFunctionality/PrefixAllGlobalsTests/attachment.inc new file mode 100644 index 00000000..317016b0 --- /dev/null +++ b/WPThemeReview/Tests/CoreFunctionality/PrefixAllGlobalsTests/attachment.inc @@ -0,0 +1,7 @@ +// phpcs:set WPThemeReview.CoreFunctionality.PrefixAllGlobals prefixes[] my_theme + => + */ + public function getErrorList( $testFile = '' ) { + switch ( $testFile ) { + case 'footer_widgets.inc': + case 'social-share.inc': + return array( + 5 => 1, + ); + + default: + return array(); + } + } + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array(); + } + +} diff --git a/WPThemeReview/ruleset.xml b/WPThemeReview/ruleset.xml index a609652b..d1b0e3ba 100644 --- a/WPThemeReview/ruleset.xml +++ b/WPThemeReview/ruleset.xml @@ -127,8 +127,17 @@ - - + + + + + + + + + + +