171 lines
4.5 KiB
PHP
171 lines
4.5 KiB
PHP
<?php
|
|
/**
|
|
* WPThemeReview Coding Standard.
|
|
*
|
|
* @package WPTRT\WPThemeReview
|
|
* @link https://github.com/WPTRT/WPThemeReview
|
|
* @license https://opensource.org/licenses/MIT MIT
|
|
*/
|
|
|
|
namespace WPThemeReview\Sniffs\Templates;
|
|
|
|
use PHP_CodeSniffer\Sniffs\Sniff;
|
|
use PHP_CodeSniffer\Files\File;
|
|
|
|
/**
|
|
* Check if the template file is using a prefix which would cause WP to interpret it as a specialised template
|
|
* meant to apply to only one page on the site.
|
|
*
|
|
* You can check the documentation of each of the functions used in determining the template hierarchy.
|
|
*
|
|
* @link https://developer.wordpress.org/reference/functions/get_category_template
|
|
* @link https://developer.wordpress.org/reference/functions/get_author_template
|
|
* @link https://developer.wordpress.org/reference/functions/get_page_template
|
|
* @link https://developer.wordpress.org/reference/functions/get_tag_template
|
|
*
|
|
* Or you can check the in depth documentation about the template hierarchy.
|
|
*
|
|
* @link https://developer.wordpress.org/themes/basics/template-hierarchy
|
|
*
|
|
* @since 0.2.0
|
|
*/
|
|
class ReservedFileNamePrefixSniff implements Sniff {
|
|
|
|
/**
|
|
* Error message template.
|
|
*
|
|
* @since 0.2.0
|
|
*
|
|
* @var string
|
|
*/
|
|
const ERROR_MSG = 'Template files should not be slug specific. The file name used for this template will be interpreted by WP as %1$s-%2$s and only applied when a %1$s with the slug "%2$s" is loaded.';
|
|
|
|
/**
|
|
* Found prefix in a file.
|
|
*
|
|
* @since 0.2.0
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $prefix;
|
|
|
|
/**
|
|
* File slug.
|
|
*
|
|
* @since 0.2.0
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $slug;
|
|
|
|
/**
|
|
* List of reserved template file names.
|
|
*
|
|
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
|
|
* @link https://developer.wordpress.org/themes/template-files-section/partial-and-miscellaneous-template-files/#content-slug-php
|
|
* @link https://wphierarchy.com/
|
|
* @link https://en.wikipedia.org/wiki/Media_type#Naming
|
|
*
|
|
* @since 0.2.0
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $reserved_file_name_prefixes = [
|
|
'author' => true,
|
|
'category' => true,
|
|
'page' => true,
|
|
'tag' => true,
|
|
];
|
|
|
|
/**
|
|
* Returns an array of tokens this test wants to listen for.
|
|
*
|
|
* @since 0.2.0
|
|
*
|
|
* @return array
|
|
*/
|
|
public function register() {
|
|
return [
|
|
\T_OPEN_TAG,
|
|
\T_OPEN_TAG_WITH_ECHO,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Processes this test, when one of its tokens is encountered.
|
|
*
|
|
* @since 0.2.0
|
|
*
|
|
* @param \PHP_CodeSniffer\Files\File $phpcsFile The PHP_CodeSniffer file where the
|
|
* token was found.
|
|
* @param int $stackPtr The position of the current token
|
|
* in the stack.
|
|
*
|
|
* @return int StackPtr to the end of the file, this sniff needs to only
|
|
* check each file once.
|
|
*/
|
|
public function process( File $phpcsFile, $stackPtr ) {
|
|
|
|
// Usage of `strip_quotes` is to ensure `stdin_path` passed by IDEs does not include quotes.
|
|
$file = $this->strip_quotes( $phpcsFile->getFileName() );
|
|
|
|
$fileName = basename( $file );
|
|
$fileName = str_replace( [ '.inc', '.php' ], '', $fileName );
|
|
|
|
// Check if the current file has a prefix in the reserved list.
|
|
if ( ! $this->is_reserved_template_name_used( $fileName ) ) {
|
|
return ( $phpcsFile->numTokens + 1 );
|
|
}
|
|
|
|
$phpcsFile->addError(
|
|
self::ERROR_MSG,
|
|
0,
|
|
'ReservedTemplatePrefixFound',
|
|
[ $this->prefix, $this->slug ]
|
|
);
|
|
|
|
return ( $phpcsFile->numTokens + 1 );
|
|
}
|
|
|
|
/**
|
|
* Checks if the given file name starts with one of the reserved prefixes.
|
|
*
|
|
* @since 0.2.0
|
|
*
|
|
* @param string $file File name to check.
|
|
* @return boolean
|
|
*/
|
|
private function is_reserved_template_name_used( $file ) {
|
|
$file_parts = explode( '-', $file, 2 );
|
|
|
|
if ( empty( $file_parts[0] ) || empty( $file_parts[1] ) ) {
|
|
// No dash or dash at start or end of filename, i.e. `-something.php`.
|
|
return false;
|
|
}
|
|
|
|
if ( isset( $this->reserved_file_name_prefixes[ strtolower( $file_parts[0] ) ] ) ) {
|
|
$this->prefix = $file_parts[0];
|
|
$this->slug = $file_parts[1];
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Strip quotes surrounding an arbitrary string.
|
|
*
|
|
* Intended for use with the contents of a T_CONSTANT_ENCAPSED_STRING / T_DOUBLE_QUOTED_STRING.
|
|
*
|
|
* Copied from the WordPressCS\WordPress\Sniff abstract class.
|
|
*
|
|
* @since 0.2.0
|
|
*
|
|
* @param string $string The raw string.
|
|
* @return string String without quotes around it.
|
|
*/
|
|
private function strip_quotes( $string ) {
|
|
return preg_replace( '`^([\'"])(.*)\1$`Ds', '$2', $string );
|
|
}
|
|
}
|