-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Warning for using include or require #67
Warning for using include or require #67
Conversation
if ( 'functions.php' !== $fileName ) { | ||
foreach ( $checks as $check ) { | ||
if ( false !== strpos( $token['content'], $check ) ) { | ||
$phpcsFile->addWarning( 'The theme appears to use include or require. If these are being used to include separate sections of a template from independent files, then <strong>get_template_part()</strong> should be used instead.' , $stackPtr, 'FileIncludeCheck' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'Check that ' . $check . ' is not being used to load template files. <strong>get_template_part()</strong> should be used to load template files.'
|
||
$fileName = basename( $phpcsFile->getFileName() ); | ||
|
||
$checks = array( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be good to rename the variable to make it clearer like $includes
$fileName = basename( $phpcsFile->getFileName() ); | ||
|
||
$checks = array( | ||
'include"', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there supposed to be a "
at the end?
* @package PHP_CodeSniffer | ||
* @author khacoder | ||
*/ | ||
class WordPress_Sniffs_Theme_FileIncludeSniff extends WordPress_AbstractThemeSniff { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this class need to extend the WordPress_AbstractThemeSniff
?
563cd1d
to
6671823
Compare
|
||
$fileName = basename( $phpcsFile->getFileName() ); | ||
|
||
$checks = array( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This array can be removed. Just like the foreach/strpos below.
You are sniffing for the correct tokens, so no need to check their content.
); | ||
|
||
if ( 'functions.php' !== $fileName ) { | ||
foreach ( $checks as $check ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for this foreach nor for the strpos()
* @category PHP | ||
* @package PHP_CodeSniffer | ||
* @link https://make.wordpress.org/core/handbook/best-practices/coding-standards/ | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update the doc block to comply with the current standards.
* @category PHP | ||
* @package PHP_CodeSniffer | ||
* @author khacoder | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update the doc block to comply with the current standards.
* @category PHP | ||
* @package PHP_CodeSniffer | ||
* @link https://make.wordpress.org/core/handbook/best-practices/coding-standards/ | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update the doc block to comply with the current standards.
* @category PHP | ||
* @package PHP_CodeSniffer | ||
* @author khacoder | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update the doc block to comply with the current standards.
* should represent the number of errors that should occur on that line. | ||
* | ||
* @return array(int => int) | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update the doc block to comply with the current standards.
* should represent the number of warnings that should occur on that line. | ||
* | ||
* @return array(int => int) | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update the doc block to comply with the current standards.
'require_once', | ||
); | ||
|
||
if ( 'functions.php' !== $fileName ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would make functions.php
a protected property in the form of an array ( array( 'functions.php' => true, )
). That way if at some point other files should be excluded, the sniff is already prepared for that.
You can then change this to a ! isset()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't fully understand what you mean with ! isset()
.
I would have done
$files = array(
'functions.php',
);
if ( in_array( $fileName, $files ) ) {
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are two reasons for this comment:
- Other similar arrays in WPCS already follow the pattern I described, so it's better to stay in line with that.
- The reason WPCS does this is code-technical.
isset()
is a language construct which is blazing fast.in_array()
is a function call. So to leverageìsset()
, the array key needs to be what you are actually looking for, which is why you'd use an array pattern like this:
$class_property = array(
'functions.php' => true,
);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you share how the if statement should be?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course - as in this case we want to show the error if the file is not in the file whitelist:
if ( ! isset( $this->class_property[ $filename ] ) ) {
// Show error.
}
For the property name, $file_whitelist
might be a good one ;-)
*/ | ||
public function register() { | ||
return array( | ||
T_REQUIRE, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more: you probably should use PHP_CodeSniffer_Tokens::$includeTokens
here. You can just straight return it.
I have made the requested changes. |
@grappler Nearly there.
Secondly, it is not a blacklist, but a whitelist. If the file name is in the whitelist of files which are logical places/in which a |
Issue #66 Check for use of include or require and if used issue a warning to check if get_template_part() is more appropriate.
I hope it is all good now 😄 |
* | ||
* @var array | ||
*/ | ||
public $file_whitelist = array( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The property should have either protected
or private
as visibility as any properties which are public
in a PHPCS sniff can be changed/overruled from the ruleset.
I can imagine a situation where we would allow people to add more files, but in that case, this would still need to be a protected/private property and we would add a $custom_whitelist
property which people could pass via the ruleset and which would then be merged.
* | ||
* @var array | ||
*/ | ||
public $supportedTokenizers = array( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to change this, but as a general remark - I believe the default in PHPCS is PHP
and adding the property is only needed when you want to sniff JS/CSS or a combination of these, though I'd have to double check the default to be sure.
(If it is the default, then there is no need for the property)
$file_name = basename( $phpcsFile->getFileName() ); | ||
|
||
if ( ! isset( $this->file_whitelist[ $file_name ] ) ) { | ||
$phpcsFile->addWarning( 'Check that ' . $token['content'] . ' is not being used to load template files. <strong>get_template_part()</strong> should be used to load template files.' , $stackPtr, 'FileIncludeFound' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Must have missed this earlier. Sorry.
The addWarning()
/addError()
methods have native sprintf()
functionality build in. To use it all you need to do is use the normal %s
placeholders in the error message and pass an array of replacements as the fourth parameter to the methods.
Also: as the output is generally command line, using HTML in the error message is confusing.
Like so:
$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',
array( $token['content'] )
);
include('/file.ext'); | ||
include_once('/file.ext'); | ||
require('/file.ext'); | ||
require_once('/file.ext'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
include
and require
are language constructs and do not need parenthesis, so it might be good to have some examples with more syntax variations:
include dirname( __FILE__ ) . '/myfile.php';
require_once $path_to_file;
Nearly there, just dotting the i's now... |
Getting closer minute by minute. |
*/ | ||
public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { | ||
$tokens = $phpcsFile->getTokens(); | ||
$token = $tokens[ $stackPtr ]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need those two variables until line 55, so they could go into the if
instead of always being created.
Issue #66
Check if include(_once) or require(_once) is used, and issue a warning to see if get_template_part() or locate_template() is more appropriate.