Skip to content

Commit

Permalink
No Favicon (#78)
Browse files Browse the repository at this point in the history
Check for hardcoded favicons instead of using core implementation.

@see https://make.wordpress.org/themes/handbook/review/required/#core-functionality-and-features

Fixes #70
  • Loading branch information
kevinhaig authored and jrfnl committed Oct 24, 2016
1 parent d660bf8 commit 6cbc3d9
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 0 deletions.
97 changes: 97 additions & 0 deletions WordPress/Sniffs/Theme/NoFaviconSniff.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php
/**
* WordPress Coding Standard.
*
* @package WPCS\WordPressCodingStandards
* @link https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards
* @license https://opensource.org/licenses/MIT MIT
*/

/**
* Check for hardcoded favicons instead of using core implementation.
*
* @link https://make.wordpress.org/themes/handbook/review/required/#core-functionality-and-features
*
* @package WPCS\WordPressCodingStandards
*
* @since 0.xx.0
*/
class WordPress_Sniffs_Theme_NoFaviconSniff implements PHP_CodeSniffer_Sniff {

const REGEX_TEMPLATE = '` (?:%s)`i';

const REGEX_ATTR_TEMPLATE = '%1$s=[\'"](?:%2$s)[\'"]';

/**
* List of link and meta attributes that are blacklisted.
*
* @var array
*/
protected $attribute_blacklist = array(
'rel' => array(
'icon',
'shortcut icon',
'bookmark icon',
'apple-touch-icon',
'apple-touch-icon-precomposed',
),
'name' => array(
'msapplication-config',
'msapplication-TileImage',
'msapplication-square70x70logo',
'msapplication-square150x150logo',
'msapplication-wide310x150logo',
'msapplication-square310x310logo',
),
);

/**
* The regex to catch the blacklisted attributes.
*
* @var string
*/
protected $favicon_regex;

/**
* Returns an array of tokens this test wants to listen for.
*
* @return array
*/
public function register() {
// Build the regex to be used only once.
$regex_parts = array();

foreach ( $this->attribute_blacklist as $key => $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 );
}

$this->favicon_regex = sprintf( self::REGEX_TEMPLATE, implode( '|', $regex_parts ) );

$tokens = PHP_CodeSniffer_Tokens::$stringTokens;
$tokens[] = T_INLINE_HTML;

return $tokens;
}

/**
* 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 ( 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' );
}

}

}
21 changes: 21 additions & 0 deletions WordPress/Tests/Theme/NoFaviconUnitTest.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

<html <?php language_attributes(); ?> class="no-js"> // OK.
<meta charset="<?php bloginfo( 'charset' ); ?>"> // OK.
<meta name="viewport" content="width=device-width, initial-scale=1"> // OK.
<link rel="profile" href="http://gmpg.org/xfn/11"> // OK.


<link rel="shortcut icon" href="http://example.com/favicon.ico"> // Error.
<link rel="icon" href="<?php esc_url( favicon_url( 'link' ) ); ?>"> // Error.
<link rel='apple-touch-icon' href="<?php esc_url( favicon_url( 'link' ) ); ?>"> // Error.
<link href="<?php esc_url( favicon_url( 'link' ) ); ?>" rel="apple-touch-icon-precomposed"> // Error.
<meta name="msapplication-TileImage" href="<?php esc_url( favicon_url( 'link' ) ); ?>"> // Error.

<?php
echo '
<meta name="msapplication-config" content="/my/path/browserconfig.xml" />
<meta name="msapplication-TileImage" content="', esc_url( get_template_directory() . 'images/icons/mstile-144x144.png?v=' . self::VERSION ), '" />
<meta name="msapplication-square70x70logo" content="', esc_url( get_template_directory() . 'images/icons/tiny.png?v=' . self::VERSION ), '" />
<meta name="msapplication-square150x150logo" content="', esc_url( get_template_directory() . 'images/icons/square.png?v=' . self::VERSION ), '" />
<meta name="msapplication-wide310x150logo" content="', esc_url( get_template_directory() . 'images/icons/wide.png?v=' . self::VERSION, __FILE__ ) ), '" />
<meta name="msapplication-square310x310logo" content="', esc_url( get_template_directory() . 'images/icons/large.png?v=' . self::VERSION ), '" />';
48 changes: 48 additions & 0 deletions WordPress/Tests/Theme/NoFaviconUnitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php
/**
* Unit test class for WordPress Coding Standard.
*
* @package WPCS\WordPressCodingStandards
* @link https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards
* @license https://opensource.org/licenses/MIT MIT
*/

/**
* Unit test class for the NoFavicon sniff.
*
* @package WPCS\WordPressCodingStandards
* @since 0.xx.0
*/
class WordPress_Tests_Theme_NoFaviconUnitTest extends AbstractSniffUnitTest {

/**
* Returns the lines where errors should occur.
*
* @return array <int line number> => <int number of errors>
*/
public function getErrorList() {
return array(
8 => 1,
9 => 1,
10 => 1,
11 => 1,
12 => 1,
16 => 1,
17 => 1,
18 => 1,
19 => 1,
20 => 1,
21 => 1,
);
}

/**
* Returns the lines where warnings should occur.
*
* @return array <int line number> => <int number of warnings>
*/
public function getWarningList() {
return array();
}

} // End class.

0 comments on commit 6cbc3d9

Please sign in to comment.