Version Description
Download this release
Release Info
Developer | Otto42 |
Plugin | Theme Check |
Version | 20200612.1 |
Comparing to | |
See all releases |
Code changes from version 20190801.1 to 20200612.1
- assets/style.css +83 -77
- changelog.txt +44 -2
- checkbase.php +0 -47
- checks/admin_menu.php +2 -2
- checks/adminbar.php +37 -23
- checks/badthings.php +2 -2
- checks/basic.php +12 -10
- checks/cdn.php +13 -12
- checks/comment_reply.php +27 -27
- checks/customizer.php +23 -8
- checks/deprecated.php +38 -0
- checks/deregister.php +2 -3
- checks/escaping.php +105 -0
- checks/favicon.php +12 -5
- checks/filenames.php +48 -29
- checks/generated.php +2 -2
- checks/i18n.php +70 -69
- checks/included-plugins.php +1 -1
- checks/lineendings.php +3 -3
- checks/navmenu.php +49 -7
- checks/nongplsites.php +46 -0
- checks/nonprintable.php +4 -4
- checks/phpshort.php +1 -2
- checks/plugin-territory.php +106 -10
- checks/screenshot.php +6 -4
- checks/siteurl.php +54 -0
- checks/style_needed.php +2 -0
- checks/style_tags.php +41 -37
- checks/textdomain.php +1 -1
- checks/title.php +38 -28
- checks/underscores.php +57 -0
- checks/widgets.php +3 -3
- checks/worms.php +1 -1
- main.php +9 -9
- readme.txt +5 -140
- theme-check.php +3 -4
assets/style.css
CHANGED
@@ -1,77 +1,83 @@
|
|
1 |
-
.tc-box {
|
2 |
-
padding:20px 0;
|
3 |
-
border-top:1px solid #dfdfdf;
|
4 |
-
}
|
5 |
-
.tc-
|
6 |
-
color:red;
|
7 |
-
}
|
8 |
-
.tc-
|
9 |
-
color:
|
10 |
-
}
|
11 |
-
.tc-
|
12 |
-
color:
|
13 |
-
}
|
14 |
-
.tc-
|
15 |
-
|
16 |
-
}
|
17 |
-
|
18 |
-
|
19 |
-
}
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
}
|
28 |
-
|
29 |
-
margin:
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
border-radius:5px;
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
}
|
46 |
-
.theme-check
|
47 |
-
|
48 |
-
}
|
49 |
-
.theme-check
|
50 |
-
margin-left:
|
51 |
-
}
|
52 |
-
.theme-check
|
53 |
-
margin:
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
}
|
59 |
-
.theme-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.tc-box {
|
2 |
+
padding:20px 0;
|
3 |
+
border-top:1px solid #dfdfdf;
|
4 |
+
}
|
5 |
+
.tc-required, .tc-fail {
|
6 |
+
color:red;
|
7 |
+
}
|
8 |
+
.tc-warning {
|
9 |
+
color: orange;
|
10 |
+
}
|
11 |
+
.tc-recommended, .tc-pass {
|
12 |
+
color: green;
|
13 |
+
}
|
14 |
+
.tc-info {
|
15 |
+
color: blue;
|
16 |
+
}
|
17 |
+
.tc-grep span {
|
18 |
+
background: yellow;
|
19 |
+
}
|
20 |
+
pre {
|
21 |
+
white-space: pre-wrap;
|
22 |
+
}
|
23 |
+
.tc-success {
|
24 |
+
margin:0 20px 20px 20px;
|
25 |
+
background:#e6ffe2;
|
26 |
+
border:1px solid #d1eecc;
|
27 |
+
}
|
28 |
+
form {
|
29 |
+
margin: 1.5em auto;
|
30 |
+
}
|
31 |
+
.theme-check {
|
32 |
+
margin: 1em auto;
|
33 |
+
border:1px solid #dfdfdf;
|
34 |
+
-moz-border-radius:5px;
|
35 |
+
-khtml-border-radius:5px;
|
36 |
+
-webkit-border-radius:5px;
|
37 |
+
border-radius:5px;
|
38 |
+
}
|
39 |
+
.theme-check h2 {
|
40 |
+
margin: 0 0 1em 0;
|
41 |
+
padding: 1em;
|
42 |
+
background:#dfdfdf url("gray-grad.png") repeat-x left top;
|
43 |
+
font-size:20px;
|
44 |
+
border-bottom:1px solid #ccc;
|
45 |
+
}
|
46 |
+
.theme-check p {
|
47 |
+
padding:5px 20px;
|
48 |
+
}
|
49 |
+
.theme-check form {
|
50 |
+
margin-left: 1.5em;
|
51 |
+
}
|
52 |
+
.theme-check ul {
|
53 |
+
margin-left:20px;
|
54 |
+
}
|
55 |
+
.theme-check h3 {
|
56 |
+
margin:0 0 10px 20px;
|
57 |
+
padding:0;
|
58 |
+
}
|
59 |
+
.theme-check ul {
|
60 |
+
margin-bottom:10px;
|
61 |
+
}
|
62 |
+
.theme-info {
|
63 |
+
padding: 1em;
|
64 |
+
border:1px solid #dfdfdf;
|
65 |
+
margin: 1em 1em 0 1em;
|
66 |
+
}
|
67 |
+
.theme-info p {
|
68 |
+
padding:0;
|
69 |
+
margin-bottom:10px;
|
70 |
+
}
|
71 |
+
.theme-info label {
|
72 |
+
float:left;
|
73 |
+
width:100px;
|
74 |
+
font-weight:bold;
|
75 |
+
display:block;
|
76 |
+
}
|
77 |
+
.theme-info span.info {
|
78 |
+
margin-left:100px;
|
79 |
+
display:block;
|
80 |
+
}
|
81 |
+
.theme-check input[name="s_info"] {
|
82 |
+
margin-left: 0.5em;
|
83 |
+
}
|
changelog.txt
CHANGED
@@ -1,3 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
= 20140929.1 =
|
2 |
* Added new checks and updates from Frank Klein at Automattic. Thanks Frank!
|
3 |
* Updated deprecated function listings
|
@@ -48,11 +90,11 @@
|
|
48 |
* Add check for wp_link_pages() + fix eval() check
|
49 |
|
50 |
= 20110219.2 =
|
51 |
-
* Merged new UI props Gua Bob [1](http://guabob.com/)
|
52 |
* Last tested theme is always pre-selected in the themes list.
|
53 |
* Fixed php error in admin_menu.php
|
54 |
|
55 |
-
= 20110219.1 =
|
56 |
* See [commit log](https://github.com/Pross/theme-check/commits/) for changes.
|
57 |
|
58 |
= 20110201.2 =
|
1 |
+
= 20200612.1 =
|
2 |
+
* Release to WordPress.org plugins directory
|
3 |
+
|
4 |
+
= 20200611.1 =
|
5 |
+
* Added escaping checks
|
6 |
+
* Added tested up to and Requires PHP checks for the style.css
|
7 |
+
* Added register_block_type to plugin territory check
|
8 |
+
* Check for remove_action wp_head
|
9 |
+
* Changed some checks from errors to warnings
|
10 |
+
* Updated error messages
|
11 |
+
* Updated regex for non printable characters
|
12 |
+
* Fixed parse errors
|
13 |
+
* Removed unused functions
|
14 |
+
|
15 |
+
= 20200504.1 =
|
16 |
+
* Contributor and URI adjustments
|
17 |
+
* site_url checks
|
18 |
+
* smarter nav menu and favicon checks
|
19 |
+
* additional filename blacklist checks
|
20 |
+
* developer files added to github (phpcs, composer, attributes, gitignore, etc)
|
21 |
+
* improvements to existing checks, move some warnings to required to reflect updated guidelines
|
22 |
+
* check for themes being copies of underscores
|
23 |
+
* check for non-gpl-compatible sites used for images
|
24 |
+
* Add warnings for demo content
|
25 |
+
* Update links in messages to point to new development and documentation locations
|
26 |
+
* disallow dashboard widgets in themes
|
27 |
+
|
28 |
+
= 20190801.1 =
|
29 |
+
* Fix missing nonce and nonce check on admin page. props Steven Stern for reporting the issue to the plugins team. Though this is technically a CSRF, there is no vulnerability arising from it, as the only thing that could be done with the form is to scan a theme.
|
30 |
+
|
31 |
+
= 20190208.1 =
|
32 |
+
* Add new styles for the block editor. See https://meta.trac.wordpress.org/ticket/3921
|
33 |
+
|
34 |
+
= 20160523.1 =
|
35 |
+
* Fix for theme-names with dashes in them
|
36 |
+
* Comments stripping changes
|
37 |
+
* Many changes by the theme review team and others. See Github for full change list.
|
38 |
+
|
39 |
+
= 20151211.1 =
|
40 |
+
* Full sync with Github and all the changes that have happened there.
|
41 |
+
* Release for 4.4 deprecated functions.
|
42 |
+
|
43 |
= 20140929.1 =
|
44 |
* Added new checks and updates from Frank Klein at Automattic. Thanks Frank!
|
45 |
* Updated deprecated function listings
|
90 |
* Add check for wp_link_pages() + fix eval() check
|
91 |
|
92 |
= 20110219.2 =
|
93 |
+
* Merged new UI props Gua Bob [1](http://guabob.com/)
|
94 |
* Last tested theme is always pre-selected in the themes list.
|
95 |
* Fixed php error in admin_menu.php
|
96 |
|
97 |
+
= 20110219.1 =
|
98 |
* See [commit log](https://github.com/Pross/theme-check/commits/) for changes.
|
99 |
|
100 |
= 20110201.2 =
|
checkbase.php
CHANGED
@@ -124,22 +124,6 @@ function tc_preg( $preg, $file ) {
|
|
124 |
return str_replace( $error, '<span class="tc-grep">' . $error . '</span>', $bad_lines );
|
125 |
}
|
126 |
|
127 |
-
function tc_strxchr($haystack, $needle, $l_inclusive = 0, $r_inclusive = 0){
|
128 |
-
if(strrpos($haystack, $needle)){
|
129 |
-
//Everything before last $needle in $haystack.
|
130 |
-
$left = substr($haystack, 0, strrpos($haystack, $needle) + $l_inclusive);
|
131 |
-
//Switch value of $r_inclusive from 0 to 1 and viceversa.
|
132 |
-
$r_inclusive = ($r_inclusive == 0) ? 1 : 0;
|
133 |
-
//Everything after last $needle in $haystack.
|
134 |
-
$right = substr(strrchr($haystack, $needle), $r_inclusive);
|
135 |
-
//Return $left and $right into an array.
|
136 |
-
return array($left, $right);
|
137 |
-
} else {
|
138 |
-
if(strrchr($haystack, $needle)) return array('', substr(strrchr($haystack, $needle), $r_inclusive));
|
139 |
-
else return false;
|
140 |
-
}
|
141 |
-
}
|
142 |
-
|
143 |
function tc_filename( $file ) {
|
144 |
$filename = ( preg_match( '/themes\/[a-z0-9-]*\/(.*)/', $file, $out ) ) ? $out[1] : basename( $file );
|
145 |
return $filename;
|
@@ -170,37 +154,6 @@ function listdir( $dir ) {
|
|
170 |
return $files;
|
171 |
}
|
172 |
|
173 |
-
function old_listdir( $start_dir='.' ) {
|
174 |
-
$files = array();
|
175 |
-
if ( is_dir( $start_dir ) ) {
|
176 |
-
$fh = opendir( $start_dir );
|
177 |
-
while ( ( $file = readdir( $fh ) ) !== false ) {
|
178 |
-
# loop through the files, skipping . and .., and recursing if necessary
|
179 |
-
if ( strcmp( $file, '.' )==0 || strcmp( $file, '..' )==0 ) continue;
|
180 |
-
$filepath = $start_dir . '/' . $file;
|
181 |
-
if ( is_dir( $filepath ) )
|
182 |
-
$files = array_merge( $files, listdir( $filepath ) );
|
183 |
-
else
|
184 |
-
array_push( $files, $filepath );
|
185 |
-
}
|
186 |
-
closedir( $fh );
|
187 |
-
|
188 |
-
} else {
|
189 |
-
|
190 |
-
# false if the function was called with an invalid non-directory argument
|
191 |
-
$files = false;
|
192 |
-
}
|
193 |
-
return $files;
|
194 |
-
}
|
195 |
-
|
196 |
-
function tc_print_r( $data ) {
|
197 |
-
$out = "\n<pre class='html-print-r'";
|
198 |
-
$out .= " style='border: 1px solid #ccc; padding: 7px;'>\n";
|
199 |
-
$out .= esc_html( print_r( $data, TRUE ) );
|
200 |
-
$out .= "\n</pre>\n";
|
201 |
-
echo $out;
|
202 |
-
}
|
203 |
-
|
204 |
function get_theme_data_from_contents( $theme_data ) {
|
205 |
$themes_allowed_tags = array(
|
206 |
'a' => array(
|
124 |
return str_replace( $error, '<span class="tc-grep">' . $error . '</span>', $bad_lines );
|
125 |
}
|
126 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
function tc_filename( $file ) {
|
128 |
$filename = ( preg_match( '/themes\/[a-z0-9-]*\/(.*)/', $file, $out ) ) ? $out[1] : basename( $file );
|
129 |
return $filename;
|
154 |
return $files;
|
155 |
}
|
156 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
function get_theme_data_from_contents( $theme_data ) {
|
158 |
$themes_allowed_tags = array(
|
159 |
'a' => array(
|
checks/admin_menu.php
CHANGED
@@ -10,8 +10,8 @@ class AdminMenu implements themecheck {
|
|
10 |
//check for levels deprecated in 2.0 in creating menus.
|
11 |
|
12 |
$checks = array(
|
13 |
-
'/([^_](add_(admin|submenu|menu|dashboard|posts|media|links|pages|comments|theme|plugins|users|management|options)_page)\s?\([^,]*,[^,]*,\s[\'|"]?(level_[0-9]|[0-9])[^;|\r|\r\n]*)/' => __( 'User levels were deprecated in <strong>2.0</strong>. Please see <a href="https://
|
14 |
-
'/[^a-z0-9](current_user_can\s?\(\s?[\'\"]level_[0-9][\'\"]\s?\))[^\r|\r\n]*/' => __( 'User levels were deprecated in <strong>2.0</strong>. Please see <a href="https://
|
15 |
);
|
16 |
|
17 |
foreach ( $php_files as $php_key => $phpfile ) {
|
10 |
//check for levels deprecated in 2.0 in creating menus.
|
11 |
|
12 |
$checks = array(
|
13 |
+
'/([^_](add_(admin|submenu|menu|dashboard|posts|media|links|pages|comments|theme|plugins|users|management|options)_page)\s?\([^,]*,[^,]*,\s[\'|"]?(level_[0-9]|[0-9])[^;|\r|\r\n]*)/' => __( 'User levels were deprecated in <strong>2.0</strong>. Please see <a href="https://wordpress.org/support/article/roles-and-capabilities/">Roles_and_Capabilities</a>', 'theme-check' ),
|
14 |
+
'/[^a-z0-9](current_user_can\s?\(\s?[\'\"]level_[0-9][\'\"]\s?\))[^\r|\r\n]*/' => __( 'User levels were deprecated in <strong>2.0</strong>. Please see <a href="https://wordpress.org/support/article/roles-and-capabilities/">Roles_and_Capabilities</a>', 'theme-check' )
|
15 |
);
|
16 |
|
17 |
foreach ( $php_files as $php_key => $phpfile ) {
|
checks/adminbar.php
CHANGED
@@ -1,41 +1,55 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* This checks
|
4 |
**/
|
5 |
class NoHiddenAdminBar implements themecheck {
|
6 |
protected $error = array();
|
7 |
|
8 |
-
|
9 |
-
|
10 |
-
checkcount();
|
11 |
-
$php_regex = "/(add_filter(\s*)\((\s*)(\"|')show_admin_bar(\"|')(\s*)(.*))|(([^\S])show_admin_bar(\s*)\((.*))/";
|
12 |
-
$css_regex = "/(#wpadminbar)/";
|
13 |
|
14 |
-
|
15 |
-
|
16 |
|
17 |
-
|
|
|
|
|
18 |
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
$ret = false;
|
23 |
-
}
|
24 |
-
}
|
25 |
|
26 |
-
|
27 |
-
|
28 |
|
29 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
}
|
35 |
}
|
|
|
|
|
36 |
return $ret;
|
37 |
}
|
38 |
|
39 |
function getError() { return $this->error; }
|
40 |
}
|
41 |
-
|
|
1 |
<?php
|
2 |
/**
|
3 |
+
* This checks if the admin bar gets hidden by the theme.
|
4 |
**/
|
5 |
class NoHiddenAdminBar implements themecheck {
|
6 |
protected $error = array();
|
7 |
|
8 |
+
function check( $php_files, $css_files, $other_files ) {
|
9 |
+
$ret = true;
|
|
|
|
|
|
|
10 |
|
11 |
+
$php_regex = "/(add_filter(\s*)\((\s*)(\"|')show_admin_bar(\"|')(\s*)(.*))|(([^\S])show_admin_bar(\s*)\((.*))/";
|
12 |
+
$css_regex = "/(#wpadminbar)/";
|
13 |
|
14 |
+
checkcount();
|
15 |
+
// Check php files for filter show_admin_bar, show_admin_bar_front, and show_admin_bar().
|
16 |
+
foreach ( $php_files as $file_path => $file_content ) {
|
17 |
|
18 |
+
$filename = tc_filename( $file_path );
|
19 |
+
|
20 |
+
if ( preg_match( $php_regex, $file_content, $matches ) ) {
|
|
|
|
|
|
|
21 |
|
22 |
+
$error = '/show_admin_bar/';
|
23 |
+
$grep = tc_preg( $error, $file_path );
|
24 |
|
25 |
+
$this->error[] = sprintf( '<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check' ) . '</span>: ' . __( '%1$s Themes are not allowed to hide the admin bar. This warning must be manually checked.', 'theme-check' ),
|
26 |
+
'<strong>' . $filename . '</strong>' ) . $grep;
|
27 |
+
}
|
28 |
+
}
|
29 |
+
|
30 |
+
checkcount();
|
31 |
+
// Check CSS Files for #wpadminbar.
|
32 |
+
foreach ( $css_files as $file_path => $file_content ) {
|
33 |
+
|
34 |
+
$filename = tc_filename( $file_path );
|
35 |
+
$error = '/#wpadminbar/';
|
36 |
+
// Don't print minified files.
|
37 |
+
if ( strpos( $filename, '.min.' ) === false ) {
|
38 |
+
$grep = tc_preg( $error, $file_path );
|
39 |
+
} else {
|
40 |
+
$grep = '';
|
41 |
+
}
|
42 |
|
43 |
+
if ( preg_match( $css_regex, $file_content, $matches ) ) {
|
44 |
+
$this->error[] = sprintf( '<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check' ) . '</span>: ' . __( 'The theme is using `#wpadminbar` in %1$s. Hiding the admin bar is not allowed. This warning must be manually checked.', 'theme-check' ),
|
45 |
+
'<strong>' . $filename . '</strong>' ) . $grep;
|
|
|
46 |
}
|
47 |
+
}
|
48 |
+
|
49 |
return $ret;
|
50 |
}
|
51 |
|
52 |
function getError() { return $this->error; }
|
53 |
}
|
54 |
+
|
55 |
+
$themechecks[] = new NoHiddenAdminBar();
|
checks/badthings.php
CHANGED
@@ -26,7 +26,7 @@ class Bad_Checks implements themecheck {
|
|
26 |
$filename = tc_filename( $php_key );
|
27 |
$error = ltrim( trim( $matches[0], '(' ) );
|
28 |
$grep = tc_grep( $error, $php_key );
|
29 |
-
$this->error[] = sprintf('<span class="tc-lead tc-
|
30 |
$ret = false;
|
31 |
}
|
32 |
}
|
@@ -45,7 +45,7 @@ class Bad_Checks implements themecheck {
|
|
45 |
$filename = tc_filename( $php_key );
|
46 |
$error = ltrim( rtrim( $matches[0],'(' ) );
|
47 |
$grep = tc_grep( $error, $php_key );
|
48 |
-
$this->error[] = sprintf(__('<span class="tc-lead tc-
|
49 |
$ret = false;
|
50 |
}
|
51 |
}
|
26 |
$filename = tc_filename( $php_key );
|
27 |
$error = ltrim( trim( $matches[0], '(' ) );
|
28 |
$grep = tc_grep( $error, $php_key );
|
29 |
+
$this->error[] = sprintf('<span class="tc-lead tc-required">'. __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( 'Found %1$s in the file %2$s. %3$s. %4$s', 'theme-check' ), '<strong>' . $error . '</strong>', '<strong>' . $filename . '</strong>', $check, $grep );
|
30 |
$ret = false;
|
31 |
}
|
32 |
}
|
45 |
$filename = tc_filename( $php_key );
|
46 |
$error = ltrim( rtrim( $matches[0],'(' ) );
|
47 |
$grep = tc_grep( $error, $php_key );
|
48 |
+
$this->error[] = sprintf(__('<span class="tc-lead tc-required">REQUIRED</span>: Found <strong>%1$s</strong> in the file <strong>%2$s</strong>. %3$s.%4$s', 'theme-check'), $error, $filename, $check, $grep);
|
49 |
$ret = false;
|
50 |
}
|
51 |
}
|
checks/basic.php
CHANGED
@@ -12,17 +12,18 @@ class Basic_Checks implements themecheck {
|
|
12 |
|
13 |
$checks = array(
|
14 |
'DOCTYPE' => __( 'See: <a href="https://codex.wordpress.org/HTML_to_XHTML">https://codex.wordpress.org/HTML_to_XHTML</a><pre><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"<br />"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"?></pre>', 'theme-check' ),
|
15 |
-
'
|
16 |
-
'
|
17 |
-
'
|
|
|
18 |
'charset' => __( 'There must be a charset defined in the Content-Type or the meta charset tag in the head.', 'theme-check' ),
|
19 |
-
'add_theme_support\s*\(\s?("|\')automatic-feed-links("|\')\s?\)' => __( 'See: <a href="https://
|
20 |
-
'comments_template\s*\(' => __( 'See: <a href="https://
|
21 |
-
'wp_list_comments\s*\(' => __( 'See: <a href="https://
|
22 |
-
'comment_form\s*\(' => __( 'See: <a href="https://
|
23 |
-
'body_class\s*\(' => __( 'See: <a href="https://
|
24 |
-
'wp_link_pages\s*\(' => __( 'See: <a href="https://
|
25 |
-
'post_class\s*\(' => __( 'See: <a href="https://
|
26 |
);
|
27 |
|
28 |
foreach ($checks as $key => $check) {
|
@@ -30,6 +31,7 @@ class Basic_Checks implements themecheck {
|
|
30 |
if ( !preg_match( '/' . $key . '/i', $php ) ) {
|
31 |
if ( $key === 'add_theme_support\s*\(\s?("|\')automatic-feed-links("|\')\s?\)' ) $key = __( 'add_theme_support( \'automatic-feed-links\' )', 'theme-check');
|
32 |
if ( $key === 'body_class\s*\(' ) $key = __( 'body_class call in body tag', 'theme-check');
|
|
|
33 |
$key = str_replace( '\s*\(', '', $key );
|
34 |
$this->error[] = sprintf( '<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('Could not find %1$s. %2$s', 'theme-check' ), '<strong>' . $key . '</strong>', $check );
|
35 |
$ret = false;
|
12 |
|
13 |
$checks = array(
|
14 |
'DOCTYPE' => __( 'See: <a href="https://codex.wordpress.org/HTML_to_XHTML">https://codex.wordpress.org/HTML_to_XHTML</a><pre><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"<br />"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"?></pre>', 'theme-check' ),
|
15 |
+
'(wp_body_open\s*\()|(do_action\s*\(\s*["\']wp_body_open)' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/wp_body_open/">wp_body_open</a><pre> <?php wp_body_open(); ?></pre>', 'theme-check' ),
|
16 |
+
'wp_footer\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/wp_footer/">wp_footer</a><pre> <?php wp_footer(); ?></pre>', 'theme-check' ),
|
17 |
+
'wp_head\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/wp_head/">wp_head</a><pre> <?php wp_head(); ?></pre>', 'theme-check' ),
|
18 |
+
'language_attributes' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/language_attributes/">language_attributes</a><pre><html <?php language_attributes(); ?></pre>', 'theme-check' ),
|
19 |
'charset' => __( 'There must be a charset defined in the Content-Type or the meta charset tag in the head.', 'theme-check' ),
|
20 |
+
'add_theme_support\s*\(\s?("|\')automatic-feed-links("|\')\s?\)' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/add_theme_support/">add_theme_support</a><pre> <?php add_theme_support( $feature ); ?></pre>', 'theme-check' ),
|
21 |
+
'comments_template\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/comments_template/">comments_template</a><pre> <?php comments_template( $file, $separate_comments ); ?></pre>', 'theme-check' ),
|
22 |
+
'wp_list_comments\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/wp_list_comments/">wp_list_comments</a><pre> <?php wp_list_comments( $args ); ?></pre>', 'theme-check' ),
|
23 |
+
'comment_form\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/comment_form/">comment_form</a><pre> <?php comment_form(); ?></pre>', 'theme-check' ),
|
24 |
+
'body_class\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/body_class/">body_class</a><pre> <?php body_class( $class ); ?></pre>', 'theme-check' ),
|
25 |
+
'wp_link_pages\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/wp_link_pages/">wp_link_pages</a><pre> <?php wp_link_pages( $args ); ?></pre>', 'theme-check' ),
|
26 |
+
'post_class\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/post_class/">post_class</a><pre> <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>></pre>', 'theme-check' )
|
27 |
);
|
28 |
|
29 |
foreach ($checks as $key => $check) {
|
31 |
if ( !preg_match( '/' . $key . '/i', $php ) ) {
|
32 |
if ( $key === 'add_theme_support\s*\(\s?("|\')automatic-feed-links("|\')\s?\)' ) $key = __( 'add_theme_support( \'automatic-feed-links\' )', 'theme-check');
|
33 |
if ( $key === 'body_class\s*\(' ) $key = __( 'body_class call in body tag', 'theme-check');
|
34 |
+
if ( $key === '(wp_body_open\s*\()|(do_action\s*\(\s*["\']wp_body_open)' ) $key = __( 'wp_body_open action or function call at the very top of the body just after the opening body tag', 'theme-check');
|
35 |
$key = str_replace( '\s*\(', '', $key );
|
36 |
$this->error[] = sprintf( '<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('Could not find %1$s. %2$s', 'theme-check' ), '<strong>' . $key . '</strong>', $check );
|
37 |
$ret = false;
|
checks/cdn.php
CHANGED
@@ -1,5 +1,4 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
/**
|
4 |
* Checks for resources being loaded from CDNs.
|
5 |
*/
|
@@ -17,22 +16,24 @@ class CDNCheck implements themecheck {
|
|
17 |
checkcount();
|
18 |
|
19 |
$cdn_list = array(
|
20 |
-
'bootstrap-maxcdn' => 'maxcdn.bootstrapcdn.com
|
21 |
-
'bootstrap-netdna' => 'netdna.bootstrapcdn.com
|
22 |
-
'
|
23 |
-
'
|
24 |
-
'
|
25 |
-
'
|
26 |
-
'html5shiv-google' => 'html5shiv.googlecode.com/svn/trunk/html5.js',
|
27 |
-
'html5shiv-maxcdn' => 'oss.maxcdn.com/libs/html5shiv',
|
28 |
'jquery' => 'code.jquery.com/jquery-',
|
29 |
-
'
|
|
|
|
|
|
|
|
|
30 |
);
|
31 |
|
32 |
foreach( $cdn_list as $cdn_slug => $cdn_url ) {
|
33 |
if ( false !== strpos( $all_code, $cdn_url ) ) {
|
34 |
-
$this->error[] = '<span class="tc-lead tc-
|
35 |
-
|
36 |
}
|
37 |
}
|
38 |
|
1 |
<?php
|
|
|
2 |
/**
|
3 |
* Checks for resources being loaded from CDNs.
|
4 |
*/
|
16 |
checkcount();
|
17 |
|
18 |
$cdn_list = array(
|
19 |
+
'bootstrap-maxcdn' => 'maxcdn.bootstrapcdn.com',
|
20 |
+
'bootstrap-netdna' => 'netdna.bootstrapcdn.com',
|
21 |
+
'bootstrap-stackpath' => 'stackpath.bootstrapcdn.com',
|
22 |
+
'fontawesome' => 'kit.fontawesome.com',
|
23 |
+
'googlecode' => 'googlecode.com/svn/',
|
24 |
+
'oss.maxcdn' => 'oss.maxcdn.com',
|
|
|
|
|
25 |
'jquery' => 'code.jquery.com/jquery-',
|
26 |
+
'aspnetcdn' => 'aspnetcdn.com',
|
27 |
+
'cloudflare' => 'cloudflare.com',
|
28 |
+
'keycdn' => 'keycdn.com',
|
29 |
+
'pxgcdn' => 'pxgcdn.com',
|
30 |
+
'vimeocdn' => 'vimeocdn.com', //usually in JS files
|
31 |
);
|
32 |
|
33 |
foreach( $cdn_list as $cdn_slug => $cdn_url ) {
|
34 |
if ( false !== strpos( $all_code, $cdn_url ) ) {
|
35 |
+
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED','theme-check' ) . '</span>: ' . sprintf( __( 'Found the URL of a CDN in the code: %s. You should not load CSS or Javascript resources from a CDN, please bundle them with the theme.', 'theme-check' ), '<code>' . esc_html( $cdn_url ) . '</code>' );
|
36 |
+
$ret = false;
|
37 |
}
|
38 |
}
|
39 |
|
checks/comment_reply.php
CHANGED
@@ -1,27 +1,27 @@
|
|
1 |
-
<?php
|
2 |
-
class Comment_Reply implements themecheck {
|
3 |
-
protected $error = array();
|
4 |
-
|
5 |
-
function check( $php_files, $css_files, $other_files) {
|
6 |
-
|
7 |
-
$php = implode( ' ', $php_files );
|
8 |
-
$ret = true;
|
9 |
-
|
10 |
-
checkcount();
|
11 |
-
|
12 |
-
if ( ! preg_match( '/wp_enqueue_script\(\s?("|\')comment-reply("|\')/i', $php ) ) {
|
13 |
-
if ( ! preg_match( '/comment-reply/', $php ) ) {
|
14 |
-
$check = __( 'See: <a href="https://codex.wordpress.org/Migrating_Plugins_and_Themes_to_2.7/Enhanced_Comment_Display">Migrating Plugins and Themes to 2.7/Enhanced Comment Display</a><pre> <?php if ( is_singular() ) wp_enqueue_script( "comment-reply" ); ?></pre>', 'theme-check' );
|
15 |
-
$this->error[] = sprintf('<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('Could not find the <strong>comment-reply</strong> script enqueued. %1$s', 'theme-check'), $check);
|
16 |
-
$ret = false;
|
17 |
-
} else {
|
18 |
-
$this->error[] = '<span class="tc-lead tc-info">'.__('INFO','theme-check').'</span>: '.__('Could not find the <strong>comment-reply</strong> script enqueued, however a reference to \'comment-reply\' was found. Make sure that the comment-reply script is being enqueued properly on singular pages.', 'theme-check');
|
19 |
-
}
|
20 |
-
}
|
21 |
-
return $ret;
|
22 |
-
}
|
23 |
-
|
24 |
-
function getError() { return $this->error; }
|
25 |
-
}
|
26 |
-
|
27 |
-
$themechecks[] = new Comment_Reply;
|
1 |
+
<?php
|
2 |
+
class Comment_Reply implements themecheck {
|
3 |
+
protected $error = array();
|
4 |
+
|
5 |
+
function check( $php_files, $css_files, $other_files) {
|
6 |
+
|
7 |
+
$php = implode( ' ', $php_files );
|
8 |
+
$ret = true;
|
9 |
+
|
10 |
+
checkcount();
|
11 |
+
|
12 |
+
if ( ! preg_match( '/wp_enqueue_script\(\s?("|\')comment-reply("|\')/i', $php ) ) {
|
13 |
+
if ( ! preg_match( '/comment-reply/', $php ) ) {
|
14 |
+
$check = __( 'See: <a href="https://codex.wordpress.org/Migrating_Plugins_and_Themes_to_2.7/Enhanced_Comment_Display">Migrating Plugins and Themes to 2.7/Enhanced Comment Display</a><pre> <?php if ( is_singular() ) wp_enqueue_script( "comment-reply" ); ?></pre>', 'theme-check' );
|
15 |
+
$this->error[] = sprintf('<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('Could not find the <strong>comment-reply</strong> script enqueued. %1$s', 'theme-check'), $check);
|
16 |
+
$ret = false;
|
17 |
+
} else {
|
18 |
+
$this->error[] = '<span class="tc-lead tc-info">'.__('INFO','theme-check').'</span>: '.__('Could not find the <strong>comment-reply</strong> script enqueued, however a reference to \'comment-reply\' was found. Make sure that the comment-reply script is being enqueued properly on singular pages.', 'theme-check');
|
19 |
+
}
|
20 |
+
}
|
21 |
+
return $ret;
|
22 |
+
}
|
23 |
+
|
24 |
+
function getError() { return $this->error; }
|
25 |
+
}
|
26 |
+
|
27 |
+
$themechecks[] = new Comment_Reply;
|
checks/customizer.php
CHANGED
@@ -1,5 +1,4 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
/**
|
4 |
* Checks for the Customizer.
|
5 |
*/
|
@@ -7,7 +6,7 @@
|
|
7 |
class CustomizerCheck implements themecheck {
|
8 |
protected $error = array();
|
9 |
|
10 |
-
function check( $php_files, $css_files, $other_files) {
|
11 |
|
12 |
$ret = true;
|
13 |
|
@@ -17,18 +16,33 @@ class CustomizerCheck implements themecheck {
|
|
17 |
* Check whether every Customizer setting has a sanitization callback set.
|
18 |
*/
|
19 |
foreach ( $php_files as $file_path => $file_content ) {
|
20 |
-
// Get the arguments passed to the add_setting method
|
21 |
if ( preg_match_all( '/\$wp_customize->add_setting\(([^;]+)/', $file_content, $matches ) ) {
|
22 |
-
// The full match is in [0], the match group in [1]
|
23 |
foreach ( $matches[1] as $match ) {
|
24 |
-
// Check if we have sanitize_callback or sanitize_js_callback
|
25 |
if ( false === strpos( $match, 'sanitize_callback' ) && false === strpos( $match, 'sanitize_js_callback' ) ) {
|
26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
$ret = false;
|
28 |
} else {
|
29 |
// There's a callback, check that no empty parameter is passed.
|
30 |
if ( preg_match( '/[\'"](?:sanitize_callback|sanitize_js_callback)[\'"]\s*=>\s*[\'"]\s*[\'"]/', $match ) ) {
|
31 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
$ret = false;
|
33 |
}
|
34 |
}
|
@@ -41,4 +55,5 @@ class CustomizerCheck implements themecheck {
|
|
41 |
|
42 |
function getError() { return $this->error; }
|
43 |
}
|
44 |
-
|
|
1 |
<?php
|
|
|
2 |
/**
|
3 |
* Checks for the Customizer.
|
4 |
*/
|
6 |
class CustomizerCheck implements themecheck {
|
7 |
protected $error = array();
|
8 |
|
9 |
+
function check( $php_files, $css_files, $other_files ) {
|
10 |
|
11 |
$ret = true;
|
12 |
|
16 |
* Check whether every Customizer setting has a sanitization callback set.
|
17 |
*/
|
18 |
foreach ( $php_files as $file_path => $file_content ) {
|
19 |
+
// Get the arguments passed to the add_setting method.
|
20 |
if ( preg_match_all( '/\$wp_customize->add_setting\(([^;]+)/', $file_content, $matches ) ) {
|
21 |
+
// The full match is in [0], the match group in [1].
|
22 |
foreach ( $matches[1] as $match ) {
|
23 |
+
// Check if we have sanitize_callback or sanitize_js_callback.
|
24 |
if ( false === strpos( $match, 'sanitize_callback' ) && false === strpos( $match, 'sanitize_js_callback' ) ) {
|
25 |
+
/* Clean up our match to be able to present the results better. */
|
26 |
+
$match = preg_split( '/,/', $match );
|
27 |
+
$filename = tc_filename( $file_path );
|
28 |
+
$grep = tc_preg( $match[0], $file_path );
|
29 |
+
$grep = preg_split( '/,/', $grep );
|
30 |
+
$this->error[] = sprintf( '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( 'Found a Customizer setting called %1$s in %2$s that did not have a sanitization callback function. ', 'theme-check' ) . __( 'Every call to the <strong>add_setting()</strong> method needs to have a sanitization callback function passed.', 'theme-check' ),
|
31 |
+
'<strong>' . $match[0] . '</strong>',
|
32 |
+
'<strong>' . $filename . '</strong>'
|
33 |
+
) . $grep[0];
|
34 |
$ret = false;
|
35 |
} else {
|
36 |
// There's a callback, check that no empty parameter is passed.
|
37 |
if ( preg_match( '/[\'"](?:sanitize_callback|sanitize_js_callback)[\'"]\s*=>\s*[\'"]\s*[\'"]/', $match ) ) {
|
38 |
+
$match = preg_split( '/,/', $match );
|
39 |
+
$filename = tc_filename( $file_path );
|
40 |
+
$grep = tc_preg( '/[\'"](?:sanitize_callback|sanitize_js_callback)[\'"]\s*=>\s*[\'"]\s*[\'"]/', $file_path );
|
41 |
+
$grep = preg_split( '/,/', $grep );
|
42 |
+
$this->error[] = sprintf( '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( 'Found a Customizer setting called %1$s in %2$s that had an empty value passed as sanitization callback. You need to pass a function name as sanitization callback.', 'theme-check' ),
|
43 |
+
'<strong>' . $match[0] . '</strong>',
|
44 |
+
'<strong>' . $filename . '</strong>'
|
45 |
+
) . $grep[0];
|
46 |
$ret = false;
|
47 |
}
|
48 |
}
|
55 |
|
56 |
function getError() { return $this->error; }
|
57 |
}
|
58 |
+
|
59 |
+
$themechecks[] = new CustomizerCheck();
|
checks/deprecated.php
CHANGED
@@ -254,7 +254,13 @@ class Deprecated implements themecheck {
|
|
254 |
array( 'prepreview_added_widget_instance' => 'customize_dynamic_setting_args', '4.2' ),
|
255 |
array( 'remove_prepreview_filters' => 'customize_dynamic_setting_args', '4.2' ),
|
256 |
|
|
|
|
|
|
|
|
|
257 |
array( 'wp_get_http' => 'WP_Http', '4.4' ),
|
|
|
|
|
258 |
|
259 |
array( 'is_comments_popup' => '', '4.5' ),
|
260 |
array( 'add_object_page' => 'add_menu_page', '4.5' ),
|
@@ -264,6 +270,38 @@ class Deprecated implements themecheck {
|
|
264 |
array( 'popuplinks' => '', '4.5' ),
|
265 |
array( 'get_currentuserinfo' => 'wp_get_current_user', '4.5' ),
|
266 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
267 |
);
|
268 |
foreach ( $php_files as $php_key => $phpfile ) {
|
269 |
foreach ( $checks as $alt => $check ) {
|
254 |
array( 'prepreview_added_widget_instance' => 'customize_dynamic_setting_args', '4.2' ),
|
255 |
array( 'remove_prepreview_filters' => 'customize_dynamic_setting_args', '4.2' ),
|
256 |
|
257 |
+
array( 'wp_htmledit_pre' => 'format_for_editor', '4.3' ),
|
258 |
+
array( 'wp_richedit_pre' => 'format_for_editor', '4.3' ),
|
259 |
+
array( 'preview_theme' => '', '4.3' ),
|
260 |
+
|
261 |
array( 'wp_get_http' => 'WP_Http', '4.4' ),
|
262 |
+
array( 'post_permalink' => 'get_permalink', '4.4' ),
|
263 |
+
array( 'force_ssl_login' => 'force_ssl_admin', '4.4' ),
|
264 |
|
265 |
array( 'is_comments_popup' => '', '4.5' ),
|
266 |
array( 'add_object_page' => 'add_menu_page', '4.5' ),
|
270 |
array( 'popuplinks' => '', '4.5' ),
|
271 |
array( 'get_currentuserinfo' => 'wp_get_current_user', '4.5' ),
|
272 |
|
273 |
+
array( 'wp_embed_handler_googlevideo' => '', '4.6' ),
|
274 |
+
array( 'wp_get_sites' => 'get_sites', '4.6' ),
|
275 |
+
array( 'post_form_autocomplete_off' => '', '4.6' ),
|
276 |
+
|
277 |
+
array( 'wp_die_handler' => '', '4.7' ),
|
278 |
+
array( 'wp_redirect_status' => '', '4.7' ),
|
279 |
+
array( 'customize_preview_override_404_status' => '', '4.7' ),
|
280 |
+
array( 'customize_preview_base' => '', '4.7' ),
|
281 |
+
array( 'customize_preview_html5' => '', '4.7' ),
|
282 |
+
array( 'customize_preview_signature' => '', '4.7' ),
|
283 |
+
array( 'remove_preview_signature' => '', '4.7' ),
|
284 |
+
array( '_cmp_priority' => 'wp_list_sort', '4.7' ),
|
285 |
+
array( 'reinit' => 'WP_Roles::for_site()', '4.7' ),
|
286 |
+
array( 'get_paged_template' => '', '4.7' ),
|
287 |
+
array( 'wp_kses_js_entities' => '', '4.7' ),
|
288 |
+
array( 'wp_get_network' => 'get_network()', '4.7' ),
|
289 |
+
array( '_sort_menus_by_orderby' => 'wp_list_sort', '4.7' ),
|
290 |
+
|
291 |
+
array( 'wp_dashboard_plugins_output' => '', '4.8' ),
|
292 |
+
|
293 |
+
array( '_init' => 'WP_Roles::for_site()', '4.9' ),
|
294 |
+
array( '_init_caps' => 'WP_User::for_site()', '4.9' ),
|
295 |
+
array( 'for_blog' => 'WP_User::for_site()', '4.9' ),
|
296 |
+
array( 'get_shortcut_link' => '', '4.9' ),
|
297 |
+
array( 'wp_ajax_press_this_save_post' => '', '4.9' ),
|
298 |
+
array( 'wp_ajax_press_this_add_category' => '', '4.9' ),
|
299 |
+
array( 'is_user_option_local' => '', '4.9' ),
|
300 |
+
array( 'maybe_log_events_response' => '', '4.9' ),
|
301 |
+
|
302 |
+
array( 'insert_blog' => 'wp_insert_site()', '5.1' ),
|
303 |
+
array( 'install_blog' => '', '5.1' ),
|
304 |
+
|
305 |
);
|
306 |
foreach ( $php_files as $php_key => $phpfile ) {
|
307 |
foreach ( $checks as $alt => $check ) {
|
checks/deregister.php
CHANGED
@@ -17,8 +17,7 @@ class DeregisterCheck implements themecheck {
|
|
17 |
$grep = tc_preg( $error, $file_path );
|
18 |
|
19 |
$this->error[] = sprintf( '<span class="tc-lead tc-warning">' . __('WARNING','theme-check') . '</span>: ' . __( 'Found wp_deregister_script in %1$s. Themes must not deregister core scripts.', 'theme-check' ),
|
20 |
-
'<strong>' . $filename . '</strong>') . $grep;
|
21 |
-
$ret = false;
|
22 |
}
|
23 |
}
|
24 |
return $ret;
|
@@ -27,4 +26,4 @@ class DeregisterCheck implements themecheck {
|
|
27 |
|
28 |
function getError() { return $this->error; }
|
29 |
}
|
30 |
-
$themechecks[] = new DeregisterCheck;
|
17 |
$grep = tc_preg( $error, $file_path );
|
18 |
|
19 |
$this->error[] = sprintf( '<span class="tc-lead tc-warning">' . __('WARNING','theme-check') . '</span>: ' . __( 'Found wp_deregister_script in %1$s. Themes must not deregister core scripts.', 'theme-check' ),
|
20 |
+
'<strong>' . $filename . '</strong>') . $grep;
|
|
|
21 |
}
|
22 |
}
|
23 |
return $ret;
|
26 |
|
27 |
function getError() { return $this->error; }
|
28 |
}
|
29 |
+
$themechecks[] = new DeregisterCheck;
|
checks/escaping.php
ADDED
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php // phpcs:ignore WordPress.Files.FileName
|
2 |
+
/**
|
3 |
+
* Checks for common escaping issues.
|
4 |
+
*
|
5 |
+
* @link https://make.wordpress.org/themes/handbook/review/required/#code
|
6 |
+
*/
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Checks for common escaping issues.
|
10 |
+
*/
|
11 |
+
class EscapingCheck implements themecheck {
|
12 |
+
/**
|
13 |
+
* Error messages, warnings and info notices.
|
14 |
+
*
|
15 |
+
* @var array $error
|
16 |
+
*/
|
17 |
+
protected $error = array();
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
|
21 |
+
*
|
22 |
+
* @param array $php_files File paths and content for PHP files.
|
23 |
+
* @param array $css_files File paths and content for CSS files.
|
24 |
+
* @param array $other_files Folder names, file paths and content for other files.
|
25 |
+
*/
|
26 |
+
public function check( $php_files, $css_files, $other_files ) {
|
27 |
+
|
28 |
+
$ret = true;
|
29 |
+
|
30 |
+
$warnings = array(
|
31 |
+
'/="<\?php esc_html_e/' => __( 'Use esc_attr_e() inside HTML attributes, and esc_url() for link attributes', 'theme-check' ),
|
32 |
+
'/="<\?php echo esc_html__/' => __( 'Use esc_attr__() inside HTML attributes, and esc_url() for link attributes', 'theme-check' ),
|
33 |
+
'/="<\?php esc_html\(/' => __( 'Use esc_attr() inside HTML attributes, and esc_url() for link attributes', 'theme-check' ),
|
34 |
+
'/><\?php echo esc_attr\(/' => __( 'Only use esc_attr() inside HTML attributes. Use esc_html() between HTML tags', 'theme-check' ),
|
35 |
+
'/><\?php echo esc_attr__/' => __( 'Only use esc_attr__() inside HTML attributes. Use esc_html__() between HTML tags', 'theme-check' ),
|
36 |
+
'/><\?php esc_attr_e/' => __( 'Only use esc_attr_e() inside HTML attributes. Use esc_html_e() between HTML tags', 'theme-check' ),
|
37 |
+
);
|
38 |
+
|
39 |
+
$required = array (
|
40 |
+
'/echo home_url/' => __( 'home_url() must be escaped. Use esc_url() for link attributes', 'theme-check' ),
|
41 |
+
'/echo get_template_directory_uri/' => __( 'get_template_directory_uri() must be escaped when output as part of a link or image source. Use esc_url() for link attributes', 'theme-check' ),
|
42 |
+
);
|
43 |
+
|
44 |
+
foreach ( $php_files as $php_key => $phpfile ) {
|
45 |
+
|
46 |
+
checkcount();
|
47 |
+
if ( false !== strpos( $phpfile, 'echo get_theme_mod' ) ) {
|
48 |
+
$filename = tc_filename( $php_key );
|
49 |
+
$error = 'echo get_theme_mod';
|
50 |
+
$grep = tc_grep( $error, $php_key );
|
51 |
+
$this->error[] = sprintf(
|
52 |
+
'<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check' ) . '</span>: ' . __( 'Found %1$s in %2$s. <a href="%3$s" target="_blank">Theme options must be escaped (Opens in a new window).</a>. ', 'theme-check' ),
|
53 |
+
'<code>' . esc_html( $error ) . '</code>',
|
54 |
+
'<strong>' . $filename . '</strong>',
|
55 |
+
'https://developer.wordpress.org/themes/theme-security/data-sanitization-escaping/#escaping-securing-output'
|
56 |
+
) . $grep;
|
57 |
+
|
58 |
+
}
|
59 |
+
|
60 |
+
foreach ( $warnings as $key => $check ) {
|
61 |
+
checkcount();
|
62 |
+
if ( preg_match( $key, $phpfile, $matches ) ) {
|
63 |
+
$filename = tc_filename( $php_key );
|
64 |
+
$error = $matches[0];
|
65 |
+
$grep = tc_grep( $error, $php_key );
|
66 |
+
$this->error[] = sprintf(
|
67 |
+
'<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check' ) . '</span>: ' . __( 'Found %1$s in %2$s. %3$s. A manual review is needed.', 'theme-check' ),
|
68 |
+
'<code>' . esc_html( $error ) . '</code>',
|
69 |
+
'<strong>' . $filename . '</strong>',
|
70 |
+
$check
|
71 |
+
) . $grep;
|
72 |
+
}
|
73 |
+
}
|
74 |
+
|
75 |
+
foreach ( $required as $key => $check ) {
|
76 |
+
checkcount();
|
77 |
+
if ( preg_match( $key, $phpfile, $matches ) ) {
|
78 |
+
$filename = tc_filename( $php_key );
|
79 |
+
$error = $matches[0];
|
80 |
+
$grep = tc_grep( $error, $php_key );
|
81 |
+
$this->error[] = sprintf(
|
82 |
+
'<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( 'Found %1$s in %2$s. %3$s. A manual review is needed.', 'theme-check' ),
|
83 |
+
'<code>' . esc_html( $error ) . '</code>',
|
84 |
+
'<strong>' . $filename . '</strong>',
|
85 |
+
$check
|
86 |
+
) . $grep;
|
87 |
+
|
88 |
+
$ret = false;
|
89 |
+
}
|
90 |
+
}
|
91 |
+
}
|
92 |
+
return $ret;
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Get error messages from the checks.
|
97 |
+
*
|
98 |
+
* @return array Error message.
|
99 |
+
*/
|
100 |
+
public function getError() {
|
101 |
+
return $this->error;
|
102 |
+
}
|
103 |
+
}
|
104 |
+
|
105 |
+
$themechecks[] = new EscapingCheck();
|
checks/favicon.php
CHANGED
@@ -1,4 +1,8 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
2 |
|
3 |
class FaviconCheck implements themecheck {
|
4 |
protected $error = array();
|
@@ -6,16 +10,18 @@ class FaviconCheck implements themecheck {
|
|
6 |
function check( $php_files, $css_files, $other_files ) {
|
7 |
|
8 |
$ret = true;
|
9 |
-
|
10 |
checkcount();
|
11 |
|
12 |
foreach ( $php_files as $file_path => $file_content ) {
|
13 |
|
14 |
$filename = tc_filename( $file_path );
|
15 |
|
16 |
-
if ( preg_match( '/(<link rel=[\'"]icon[\'"])|(<link rel=[\'"]apple-touch-icon
|
17 |
-
$this->error[] = sprintf( '<span class="tc-lead tc-
|
18 |
-
'<strong>' . $filename . '</strong>'
|
|
|
|
|
19 |
}
|
20 |
}
|
21 |
return $ret;
|
@@ -23,4 +29,5 @@ class FaviconCheck implements themecheck {
|
|
23 |
|
24 |
function getError() { return $this->error; }
|
25 |
}
|
26 |
-
|
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Checks for favicons.
|
4 |
+
* Note that the check for the icon file is in filenames.php.
|
5 |
+
*/
|
6 |
|
7 |
class FaviconCheck implements themecheck {
|
8 |
protected $error = array();
|
10 |
function check( $php_files, $css_files, $other_files ) {
|
11 |
|
12 |
$ret = true;
|
13 |
+
|
14 |
checkcount();
|
15 |
|
16 |
foreach ( $php_files as $file_path => $file_content ) {
|
17 |
|
18 |
$filename = tc_filename( $file_path );
|
19 |
|
20 |
+
if ( preg_match( '/(<link rel=[\'"]icon[\'"])|(<link rel=[\'"]shortcut icon[\'"])|(<link rel=[\'"]apple-touch-icon.*[\'"])|(<meta name=[\'"]msapplication-TileImage[\'"])/i', $file_content, $matches ) ) {
|
21 |
+
$this->error[] = sprintf( '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( 'Possible Favicon found in %1$s. Favicons are handled by the Site Icon setting in the customizer since version 4.3.', 'theme-check' ),
|
22 |
+
'<strong>' . $filename . '</strong>'
|
23 |
+
);
|
24 |
+
$ret = false;
|
25 |
}
|
26 |
}
|
27 |
return $ret;
|
29 |
|
30 |
function getError() { return $this->error; }
|
31 |
}
|
32 |
+
|
33 |
+
$themechecks[] = new FaviconCheck();
|
checks/filenames.php
CHANGED
@@ -17,45 +17,63 @@ class File_Checks implements themecheck {
|
|
17 |
foreach ( $css_files as $php_key => $phpfile ) {
|
18 |
array_push( $filenames, strtolower( basename( $php_key ) ) );
|
19 |
}
|
|
|
|
|
|
|
20 |
$blacklist = array(
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
|
36 |
-
$musthave = array( 'index.php', 'style.css' );
|
37 |
-
$rechave
|
38 |
|
39 |
checkcount();
|
40 |
|
41 |
-
foreach( $blacklist as $file => $reason ) {
|
42 |
-
if ( $filename
|
43 |
-
$error
|
44 |
-
|
45 |
-
|
|
|
|
|
|
|
46 |
}
|
47 |
}
|
48 |
|
49 |
-
foreach( $musthave as $file ) {
|
50 |
-
if ( !in_array( $file, $filenames ) ) {
|
51 |
-
$this->error[] = sprintf('<span class="tc-lead tc-
|
52 |
-
$ret
|
53 |
}
|
54 |
}
|
55 |
|
56 |
-
foreach( $rechave as $file => $reason ) {
|
57 |
-
if ( !in_array( $file, $filenames ) ) {
|
58 |
-
$this->error[] = sprintf('<span class="tc-lead tc-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__('Could not find the file %1$s in the theme. %2$s', 'theme-check'), '<strong>' . $file . '</strong>', $reason );
|
59 |
}
|
60 |
}
|
61 |
|
@@ -64,4 +82,5 @@ class File_Checks implements themecheck {
|
|
64 |
|
65 |
function getError() { return $this->error; }
|
66 |
}
|
67 |
-
|
|
17 |
foreach ( $css_files as $php_key => $phpfile ) {
|
18 |
array_push( $filenames, strtolower( basename( $php_key ) ) );
|
19 |
}
|
20 |
+
|
21 |
+
$whitelist = 'wpml-config.xml';
|
22 |
+
|
23 |
$blacklist = array(
|
24 |
+
'thumbs\.db' => __( 'Windows thumbnail store', 'theme-check' ),
|
25 |
+
'desktop\.ini' => __( 'windows system file', 'theme-check' ),
|
26 |
+
'project\.properties' => __( 'NetBeans Project File', 'theme-check' ),
|
27 |
+
'project\.xml' => __( 'NetBeans Project File', 'theme-check' ),
|
28 |
+
'\.kpf' => __( 'Komodo Project File', 'theme-check' ),
|
29 |
+
'^\.+[a-zA-Z0-9]' => __( 'Hidden Files or Folders', 'theme-check' ),
|
30 |
+
'php\.ini' => __( 'PHP server settings file', 'theme-check' ),
|
31 |
+
'dwsync\.xml' => __( 'Dreamweaver project file', 'theme-check' ),
|
32 |
+
'error_log' => __( 'PHP error log', 'theme-check' ),
|
33 |
+
'web\.config' => __( 'Server settings file', 'theme-check' ),
|
34 |
+
'\.sql' => __( 'SQL dump file', 'theme-check' ),
|
35 |
+
'__MACOSX' => __( 'OSX system file', 'theme-check' ),
|
36 |
+
'\.lubith' => __( 'Lubith theme generator file', 'theme-check' ),
|
37 |
+
'\.wie' => __( 'Widget import file', 'theme-check' ),
|
38 |
+
'\.dat' => __( 'Customizer import file', 'theme-check' ),
|
39 |
+
'phpcs\.xml\.dist' => __( 'PHPCS file', 'theme-check' ),
|
40 |
+
'phpcs\.xml' => __( 'PHPCS file', 'theme-check' ),
|
41 |
+
'\.xml' => __( 'XML file', 'theme-check' ),
|
42 |
+
'\.sh' => __( 'Shell script file', 'theme-check' ),
|
43 |
+
'postcss\.config\.js' => __( 'PostCSS config file', 'theme-check' ),
|
44 |
+
'\.editorconfig.' => __( 'Editor config file', 'theme-check' ),
|
45 |
+
'\.stylelintrc\.json' => __( 'Stylelint config file', 'theme-check' ),
|
46 |
+
'\.map' => __( 'Map file', 'theme-check' ),
|
47 |
+
'\.eslintrc' => __( 'ES lint config file', 'theme-check' ),
|
48 |
+
'favicon\.ico' => __( 'Favicon', 'theme-check' ),
|
49 |
+
);
|
50 |
|
51 |
+
$musthave = array( 'index.php', 'style.css', 'readme.txt' );
|
52 |
+
$rechave = array();
|
53 |
|
54 |
checkcount();
|
55 |
|
56 |
+
foreach ( $blacklist as $file => $reason ) {
|
57 |
+
if ( $filename = preg_grep( '/' . $file . '/', $filenames ) ) {
|
58 |
+
$error = implode( ' ', array_unique( $filename ) );
|
59 |
+
if ( $error === $whitelist ) {
|
60 |
+
continue;
|
61 |
+
}
|
62 |
+
$this->error[] = sprintf( '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( '%1$s %2$s found. This file must not be in a theme.', 'theme-check' ), '<strong>' . $error . '</strong>', $reason );
|
63 |
+
$ret = false;
|
64 |
}
|
65 |
}
|
66 |
|
67 |
+
foreach ( $musthave as $file ) {
|
68 |
+
if ( ! in_array( $file, $filenames ) ) {
|
69 |
+
$this->error[] = sprintf( '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( 'Could not find the file %s in the theme.', 'theme-check' ), '<strong>' . $file . '</strong>' );
|
70 |
+
$ret = false;
|
71 |
}
|
72 |
}
|
73 |
|
74 |
+
foreach ( $rechave as $file => $reason ) {
|
75 |
+
if ( ! in_array( $file, $filenames ) ) {
|
76 |
+
$this->error[] = sprintf( '<span class="tc-lead tc-recommended">' . __( 'RECOMMENDED', 'theme-check' ) . '</span>: ' . __( 'Could not find the file %1$s in the theme. %2$s', 'theme-check' ), '<strong>' . $file . '</strong>', $reason );
|
77 |
}
|
78 |
}
|
79 |
|
82 |
|
83 |
function getError() { return $this->error; }
|
84 |
}
|
85 |
+
|
86 |
+
$themechecks[] = new File_Checks();
|
checks/generated.php
CHANGED
@@ -30,7 +30,7 @@ class GeneratedCheck implements themecheck {
|
|
30 |
//wpthemegenerator
|
31 |
|| strpos ( $php, "wptg_") !== false
|
32 |
) {
|
33 |
-
$this->error[] = "<span class='tc-lead tc-
|
34 |
$ret = false;
|
35 |
}
|
36 |
|
@@ -39,4 +39,4 @@ class GeneratedCheck implements themecheck {
|
|
39 |
|
40 |
function getError() { return $this->error; }
|
41 |
}
|
42 |
-
$themechecks[] = new GeneratedCheck;
|
30 |
//wpthemegenerator
|
31 |
|| strpos ( $php, "wptg_") !== false
|
32 |
) {
|
33 |
+
$this->error[] = "<span class='tc-lead tc-required'>" . __('REQUIRED', 'theme-check' ). "</span>: " . __( 'This theme appears to have been auto-generated. Generated themes are not allowed in the themes directory.', 'theme-check' );
|
34 |
$ret = false;
|
35 |
}
|
36 |
|
39 |
|
40 |
function getError() { return $this->error; }
|
41 |
}
|
42 |
+
$themechecks[] = new GeneratedCheck;
|
checks/i18n.php
CHANGED
@@ -1,70 +1,71 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
// check for various I18N errors
|
4 |
-
|
5 |
-
class I18NCheck implements themecheck {
|
6 |
-
protected $error = array();
|
7 |
-
|
8 |
-
function check( $php_files, $css_files, $other_files ) {
|
9 |
-
|
10 |
-
$
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
$
|
25 |
-
$
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
$
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
$
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
'<strong>' . $
|
55 |
-
$
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
}
|
|
|
70 |
$themechecks[] = new I18NCheck;
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// check for various I18N errors
|
4 |
+
|
5 |
+
class I18NCheck implements themecheck {
|
6 |
+
protected $error = array();
|
7 |
+
|
8 |
+
function check( $php_files, $css_files, $other_files ) {
|
9 |
+
|
10 |
+
$ret = true;
|
11 |
+
$error = '';
|
12 |
+
checkcount();
|
13 |
+
|
14 |
+
// make sure the tokenizer is available
|
15 |
+
if ( !function_exists( 'token_get_all' ) ) return true;
|
16 |
+
|
17 |
+
foreach ( $php_files as $php_key => $phpfile ) {
|
18 |
+
$error='';
|
19 |
+
|
20 |
+
$stmts = array();
|
21 |
+
foreach ( array('_e(', '__(', '_e (', '__ (') as $finder) {
|
22 |
+
$search = $phpfile;
|
23 |
+
while ( ( $pos = strpos($search, $finder) ) !== false ) {
|
24 |
+
$search = substr($search,$pos);
|
25 |
+
$open=1;
|
26 |
+
$i=strpos($search,'(')+1;
|
27 |
+
while( $open>0 ) {
|
28 |
+
switch($search[$i]) {
|
29 |
+
case '(':
|
30 |
+
$open++; break;
|
31 |
+
case ')':
|
32 |
+
$open--; break;
|
33 |
+
}
|
34 |
+
$i++;
|
35 |
+
}
|
36 |
+
$stmts[] = substr($search,0,$i);
|
37 |
+
$search = substr($search,$i);
|
38 |
+
}
|
39 |
+
}
|
40 |
+
|
41 |
+
foreach ( $stmts as $match ) {
|
42 |
+
$tokens = @token_get_all('<?php '.$match.';');
|
43 |
+
if (!empty($tokens)) {
|
44 |
+
foreach ($tokens as $token) {
|
45 |
+
if (is_array($token) && in_array( $token[0], array( T_VARIABLE ) ) ) {
|
46 |
+
$filename = tc_filename( $php_key );
|
47 |
+
$grep = tc_grep( ltrim( $match ), $php_key );
|
48 |
+
preg_match( '/[^\s]*\s[0-9]+/', $grep, $line);
|
49 |
+
$error = '';
|
50 |
+
if ( isset( $line[0] ) ) {
|
51 |
+
$error = ( !strpos( $error, $line[0] ) ) ? $grep : '';
|
52 |
+
}
|
53 |
+
$this->error[] = sprintf('<span class="tc-lead tc-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__('Possible variable %1$s found in translation function in %2$s. Translation function calls must NOT contain PHP variables. %3$s','theme-check'),
|
54 |
+
'<strong>' . $token[1] . '</strong>',
|
55 |
+
'<strong>' . $filename . '</strong>',
|
56 |
+
$error
|
57 |
+
);
|
58 |
+
break; // stop looking at the tokens on this line once a variable is found
|
59 |
+
}
|
60 |
+
}
|
61 |
+
}
|
62 |
+
}
|
63 |
+
|
64 |
+
|
65 |
+
}
|
66 |
+
return $ret;
|
67 |
+
}
|
68 |
+
|
69 |
+
function getError() { return $this->error; }
|
70 |
+
}
|
71 |
$themechecks[] = new I18NCheck;
|
checks/included-plugins.php
CHANGED
@@ -19,7 +19,7 @@ class IncludedPlugins implements themecheck {
|
|
19 |
|
20 |
foreach ( $blacklist as $file => $reason ) {
|
21 |
if ( $filename = preg_grep( '/' . $file . '/', $filenames ) ) {
|
22 |
-
$error = implode( array_unique( $filename )
|
23 |
$this->error[] = sprintf( '<span class="tc-lead tc-required">' . __( 'REQUIRED','theme-check' ) . '</span>: ' . __( '<strong>Zip file found.</strong> Plugins are not allowed in themes. The zip file found was <em>%s</em>.', 'theme-check' ), $error );
|
24 |
$ret = false;
|
25 |
}
|
19 |
|
20 |
foreach ( $blacklist as $file => $reason ) {
|
21 |
if ( $filename = preg_grep( '/' . $file . '/', $filenames ) ) {
|
22 |
+
$error = implode( ' ', array_unique( $filename ) );
|
23 |
$this->error[] = sprintf( '<span class="tc-lead tc-required">' . __( 'REQUIRED','theme-check' ) . '</span>: ' . __( '<strong>Zip file found.</strong> Plugins are not allowed in themes. The zip file found was <em>%s</em>.', 'theme-check' ), $error );
|
24 |
$ret = false;
|
25 |
}
|
checks/lineendings.php
CHANGED
@@ -8,7 +8,7 @@ class LineEndingsCheck implements themecheck {
|
|
8 |
if (preg_match("/\r\n/",$phpfile)) {
|
9 |
if (preg_match("/[^\r]\n/",$phpfile)) {
|
10 |
$filename = tc_filename( $php_key );
|
11 |
-
$this->error[] = sprintf('<span class="tc-lead tc-
|
12 |
$ret = false;
|
13 |
}
|
14 |
}
|
@@ -17,7 +17,7 @@ class LineEndingsCheck implements themecheck {
|
|
17 |
if (preg_match("/\r\n/",$cssfile)) {
|
18 |
if (preg_match("/[^\r]\n/",$cssfile)) {
|
19 |
$filename = tc_filename( $css_key );
|
20 |
-
$this->error[] = sprintf('<span class="tc-lead tc-
|
21 |
$ret = false;
|
22 |
}
|
23 |
}
|
@@ -28,7 +28,7 @@ class LineEndingsCheck implements themecheck {
|
|
28 |
if (preg_match("/\r\n/",$othfile)) {
|
29 |
if (preg_match("/[^\r]\n/",$othfile)) {
|
30 |
$filename = tc_filename( $oth_key );
|
31 |
-
$this->error[] = sprintf('<span class="tc-lead tc-
|
32 |
$ret = false;
|
33 |
}
|
34 |
}
|
8 |
if (preg_match("/\r\n/",$phpfile)) {
|
9 |
if (preg_match("/[^\r]\n/",$phpfile)) {
|
10 |
$filename = tc_filename( $php_key );
|
11 |
+
$this->error[] = sprintf('<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('Both DOS and UNIX style line endings were found in the file %1$s. This causes a problem with SVN repositories and must be corrected before the theme can be accepted. Please change the file to use only one style of line endings.', 'theme-check'), '<strong>' . $filename . '</strong>' );
|
12 |
$ret = false;
|
13 |
}
|
14 |
}
|
17 |
if (preg_match("/\r\n/",$cssfile)) {
|
18 |
if (preg_match("/[^\r]\n/",$cssfile)) {
|
19 |
$filename = tc_filename( $css_key );
|
20 |
+
$this->error[] = sprintf('<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('Both DOS and UNIX style line endings were found in the file %1$s. This causes a problem with SVN repositories and must be corrected before the theme can be accepted. Please change the file to use only one style of line endings.', 'theme-check'), '<strong>' . $filename . '</strong>' );
|
21 |
$ret = false;
|
22 |
}
|
23 |
}
|
28 |
if (preg_match("/\r\n/",$othfile)) {
|
29 |
if (preg_match("/[^\r]\n/",$othfile)) {
|
30 |
$filename = tc_filename( $oth_key );
|
31 |
+
$this->error[] = sprintf('<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('Both DOS and UNIX style line endings were found in the file %1$s. This causes a problem with SVN repositories and must be corrected before the theme can be accepted. Please change the file to use only one style of line endings.', 'theme-check'), '<strong>' . $filename . '</strong>' );
|
32 |
$ret = false;
|
33 |
}
|
34 |
}
|
checks/navmenu.php
CHANGED
@@ -5,21 +5,63 @@ class NavMenuCheck implements themecheck {
|
|
5 |
|
6 |
function check( $php_files, $css_files, $other_files ) {
|
7 |
|
8 |
-
$ret
|
|
|
|
|
|
|
9 |
|
10 |
-
// combine all the php files into one string to make it easier to search
|
11 |
-
$php = implode( ' ', $php_files );
|
12 |
checkcount();
|
13 |
if ( strpos( $php, 'nav_menu' ) === false ) {
|
14 |
-
$this->error[] = '<span class="tc-lead tc-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__("No reference to nav_menu's was found in the theme. Note that if your theme has a menu bar, it is required to use the WordPress nav_menu functionality for it.", 'theme-check' );
|
15 |
}
|
16 |
|
17 |
// Look for add_theme_support( 'menus' ).
|
18 |
checkcount();
|
19 |
if ( preg_match( '/add_theme_support\s*\(\s?("|\')menus("|\')\s?\)/', $php ) ) {
|
20 |
/* translators: 1: function found, 2: function to be used */
|
21 |
-
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check') . '</span>: ' . sprintf( __( 'Reference to %1$s was found in the theme. This should be removed and %2$s used instead.', 'theme-check' ), '<strong>add_theme_support( "menus" )</strong>', '<a href="https://developer.wordpress.org/reference/functions/register_nav_menus/">register_nav_menus()</a>' );
|
22 |
-
$ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
}
|
24 |
|
25 |
return $ret;
|
@@ -28,4 +70,4 @@ class NavMenuCheck implements themecheck {
|
|
28 |
function getError() { return $this->error; }
|
29 |
}
|
30 |
|
31 |
-
$themechecks[] = new NavMenuCheck;
|
5 |
|
6 |
function check( $php_files, $css_files, $other_files ) {
|
7 |
|
8 |
+
$ret = true;
|
9 |
+
$name_check = false;
|
10 |
+
|
11 |
+
$php = implode( ' ', $php_files );
|
12 |
|
|
|
|
|
13 |
checkcount();
|
14 |
if ( strpos( $php, 'nav_menu' ) === false ) {
|
15 |
+
$this->error[] = '<span class="tc-lead tc-recommended">' . __( 'RECOMMENDED', 'theme-check' ) . '</span>: ' . __( "No reference to nav_menu's was found in the theme. Note that if your theme has a menu bar, it is required to use the WordPress nav_menu functionality for it.", 'theme-check' );
|
16 |
}
|
17 |
|
18 |
// Look for add_theme_support( 'menus' ).
|
19 |
checkcount();
|
20 |
if ( preg_match( '/add_theme_support\s*\(\s?("|\')menus("|\')\s?\)/', $php ) ) {
|
21 |
/* translators: 1: function found, 2: function to be used */
|
22 |
+
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . sprintf( __( 'Reference to %1$s was found in the theme. This should be removed and %2$s used instead.', 'theme-check' ), '<strong>add_theme_support( "menus" )</strong>', '<a href="https://developer.wordpress.org/reference/functions/register_nav_menus/">register_nav_menus()</a>' );
|
23 |
+
$ret = false;
|
24 |
+
}
|
25 |
+
|
26 |
+
foreach ( $php_files as $file_path => $file_content ) {
|
27 |
+
$filename = tc_filename( $file_path );
|
28 |
+
|
29 |
+
// We are checking for wp_nav_menu( specifically, to allow wp_nav_menu and wp_nav_menu_item in filters etc.
|
30 |
+
if ( strpos( $file_content, 'wp_nav_menu(' ) !== false ) {
|
31 |
+
$menu_part = explode( 'wp_nav_menu(', $file_content );
|
32 |
+
$menu_part = explode( ';', $menu_part[1] );
|
33 |
+
|
34 |
+
// If there is a menu, check for a theme location, which is required.
|
35 |
+
// Check if the arguments are placed outside wp_nav_menu.
|
36 |
+
checkcount();
|
37 |
+
if ( strpos( $menu_part[0], '$' ) !== false && strpos( $menu_part[0], 'theme_location' ) === false ) {
|
38 |
+
$menu_args = explode( '$', $menu_part[0], 1 );
|
39 |
+
$name = explode( ')', $menu_args[0] );
|
40 |
+
$this->error[] = '<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check' ) . '</span>: ' . sprintf( __( 'A menu without a theme_location was found in %1$s. %2$s is used inside wp_nav_menu(). You must manually check if the theme_location is included.', 'theme-check' ),
|
41 |
+
'<strong>' . $filename . '</strong>',
|
42 |
+
'<code>' . $name[0] . '</code>'
|
43 |
+
);
|
44 |
+
$name_check = true;
|
45 |
+
} else {
|
46 |
+
checkcount();
|
47 |
+
if ( strpos( $menu_part[0], 'theme_location' ) === false ) {
|
48 |
+
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . sprintf( __( 'A menu without a theme_location was found in %1$s.', 'theme-check' ),
|
49 |
+
'<strong>' . $filename . '</strong>'
|
50 |
+
);
|
51 |
+
$ret = false;
|
52 |
+
$name_check = true;
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
// We only need to warn for the menu name if theme location is not set.
|
57 |
+
checkcount();
|
58 |
+
if ( $name_check === true && preg_match( '/("|\')menu("|\').*?=>/', $menu_part[0] ) ) {
|
59 |
+
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . sprintf( __( 'A menu name is being used for a menu in %1$s. By using menu name, the menu would be required to have the exact same name in the WordPress admin area. Use a theme_location instead.', 'theme-check' ),
|
60 |
+
'<strong>' . $filename . '</strong>'
|
61 |
+
);
|
62 |
+
$ret = false;
|
63 |
+
}
|
64 |
+
}
|
65 |
}
|
66 |
|
67 |
return $ret;
|
70 |
function getError() { return $this->error; }
|
71 |
}
|
72 |
|
73 |
+
$themechecks[] = new NavMenuCheck();
|
checks/nongplsites.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Checks if the theme includes resoruces from websites that does not use a GPL compatible license.
|
4 |
+
*/
|
5 |
+
class NonGPLCheck implements themecheck {
|
6 |
+
protected $error = array();
|
7 |
+
|
8 |
+
function check( $php_files, $css_files, $other_files ) {
|
9 |
+
|
10 |
+
$ret = true;
|
11 |
+
$code = implode( ' ', $other_files ); // The references are usually in the readme.
|
12 |
+
|
13 |
+
checkcount();
|
14 |
+
|
15 |
+
$link_list = array(
|
16 |
+
'unsplash' => 'https://unsplash.com/license',
|
17 |
+
'pixabay' => 'https://pixabay.com/service/license/',
|
18 |
+
'freeimages' => 'https://www.freeimages.com/license',
|
19 |
+
'photopin' => 'http://photopin.com/faq',
|
20 |
+
'splitshire' => 'https://www.splitshire.com/licence/',
|
21 |
+
'freepik' => 'https://www.freepikcompany.com/legal',
|
22 |
+
'flaticon' => 'https://www.freepikcompany.com/legal',
|
23 |
+
'pikwizard' => 'https://pikwizard.com/standard-license',
|
24 |
+
'stock.adobe' => 'https://stock.adobe.com/license-terms',
|
25 |
+
'elements.envato' => 'https://elements.envato.com/license-terms',
|
26 |
+
'undraw.co' => 'https://undraw.co/licenses',
|
27 |
+
);
|
28 |
+
|
29 |
+
foreach ( $link_list as $link_slug => $link_url ) {
|
30 |
+
if ( false !== stripos( $code, $link_slug ) ) {
|
31 |
+
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' .
|
32 |
+
sprintf(
|
33 |
+
__( 'Found a reference to %s. Images from this website does not use a license that is compatible with GPL.', 'theme-check' ),
|
34 |
+
'<code>' . esc_html( $link_slug ) . '</code>'
|
35 |
+
)
|
36 |
+
. ' <a href="' . esc_url( $link_url ) . '" target="_blank">' . __( 'View license (opens in a new window).', 'theme-check' ) . '</a>';
|
37 |
+
}
|
38 |
+
}
|
39 |
+
|
40 |
+
return $ret;
|
41 |
+
}
|
42 |
+
|
43 |
+
function getError() { return $this->error; }
|
44 |
+
}
|
45 |
+
|
46 |
+
$themechecks[] = new NonGPLCheck;
|
checks/nonprintable.php
CHANGED
@@ -10,10 +10,10 @@ class NonPrintableCheck implements themecheck {
|
|
10 |
// 09 = tab
|
11 |
// 0A = line feed
|
12 |
// 0D = new line
|
13 |
-
if ( preg_match('/[\x00-\x08\x0B-\x0C\x0E-\x1F
|
14 |
$filename = tc_filename( $name );
|
15 |
-
$non_print = tc_preg( '/[\x00-\x08\x0B-\x0C\x0E-\x1F
|
16 |
-
$this->error[] = sprintf('<span class="tc-lead tc-
|
17 |
}
|
18 |
}
|
19 |
|
@@ -24,4 +24,4 @@ class NonPrintableCheck implements themecheck {
|
|
24 |
function getError() { return $this->error; }
|
25 |
}
|
26 |
|
27 |
-
$themechecks[] = new NonPrintableCheck;
|
10 |
// 09 = tab
|
11 |
// 0A = line feed
|
12 |
// 0D = new line
|
13 |
+
if ( preg_match('/[\x00-\x08\x0B-\x0C\x0E-\x1F]/', $content, $matches ) ) {
|
14 |
$filename = tc_filename( $name );
|
15 |
+
$non_print = tc_preg( '/[\x00-\x08\x0B-\x0C\x0E-\x1F]/', $name );
|
16 |
+
$this->error[] = sprintf('<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check' ) . '</span>: ' . __( 'Non-printable characters were found in the %1$s file. You may want to check this file for errors.%2$s', 'theme-check' ), '<strong>' . $filename . '</strong>', $non_print);
|
17 |
}
|
18 |
}
|
19 |
|
24 |
function getError() { return $this->error; }
|
25 |
}
|
26 |
|
27 |
+
$themechecks[] = new NonPrintableCheck;
|
checks/phpshort.php
CHANGED
@@ -12,7 +12,6 @@ class PHPShortTagsCheck implements themecheck {
|
|
12 |
$filename = tc_filename( $php_key );
|
13 |
$grep = tc_preg( '/<\?(\=?)(?!php|xml)/', $php_key );
|
14 |
$this->error[] = sprintf('<span class="tc-lead tc-warning">'.__('WARNING','theme-check').'</span>: '.__('Found PHP short tags in file %1$s.%2$s', 'theme-check'), '<strong>' . $filename . '</strong>', $grep);
|
15 |
-
$ret = false;
|
16 |
}
|
17 |
}
|
18 |
|
@@ -22,4 +21,4 @@ class PHPShortTagsCheck implements themecheck {
|
|
22 |
function getError() { return $this->error; }
|
23 |
}
|
24 |
|
25 |
-
$themechecks[] = new PHPShortTagsCheck;
|
12 |
$filename = tc_filename( $php_key );
|
13 |
$grep = tc_preg( '/<\?(\=?)(?!php|xml)/', $php_key );
|
14 |
$this->error[] = sprintf('<span class="tc-lead tc-warning">'.__('WARNING','theme-check').'</span>: '.__('Found PHP short tags in file %1$s.%2$s', 'theme-check'), '<strong>' . $filename . '</strong>', $grep);
|
|
|
15 |
}
|
16 |
}
|
17 |
|
21 |
function getError() { return $this->error; }
|
22 |
}
|
23 |
|
24 |
+
$themechecks[] = new PHPShortTagsCheck;
|
checks/plugin-territory.php
CHANGED
@@ -1,14 +1,29 @@
|
|
1 |
-
<?php
|
2 |
/**
|
3 |
* Checks for Plugin Territory Guidelines.
|
4 |
*
|
5 |
-
*
|
6 |
*/
|
7 |
|
|
|
|
|
|
|
8 |
class Plugin_Territory implements themecheck {
|
|
|
|
|
|
|
|
|
|
|
9 |
protected $error = array();
|
10 |
|
11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
$ret = true;
|
13 |
$php = implode( ' ', $php_files );
|
14 |
|
@@ -16,26 +31,107 @@ class Plugin_Territory implements themecheck {
|
|
16 |
$forbidden_functions = array(
|
17 |
'register_post_type',
|
18 |
'register_taxonomy',
|
|
|
|
|
19 |
);
|
20 |
|
21 |
foreach ( $forbidden_functions as $function ) {
|
22 |
checkcount();
|
23 |
if ( preg_match( '/[\s?]' . $function . '\s?\(/', $php ) ) {
|
24 |
-
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check').'</span>: ' . sprintf( __( 'The theme uses the %s function, which is plugin-territory functionality.', 'theme-check' ), '<strong>' . esc_html( $function ) . '()</strong>' )
|
25 |
-
$ret
|
26 |
}
|
27 |
}
|
28 |
|
29 |
// Shortcodes can't be used in the post content, so warn about them.
|
30 |
-
if ( false !== strpos( $php, 'add_shortcode' ) ) {
|
31 |
checkcount();
|
32 |
-
$this->error[] = '<span class="tc-lead tc-
|
33 |
-
$ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
}
|
35 |
|
36 |
return $ret;
|
37 |
}
|
38 |
|
39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
}
|
41 |
-
|
|
1 |
+
<?php // phpcs:ignore WordPress.Files.FileName
|
2 |
/**
|
3 |
* Checks for Plugin Territory Guidelines.
|
4 |
*
|
5 |
+
* @link https://make.wordpress.org/themes/handbook/review/required/#presentation-vs-functionality
|
6 |
*/
|
7 |
|
8 |
+
/**
|
9 |
+
* Checks for Plugin Territory
|
10 |
+
*/
|
11 |
class Plugin_Territory implements themecheck {
|
12 |
+
/**
|
13 |
+
* Error messages, warnings and info notices.
|
14 |
+
*
|
15 |
+
* @var array $error
|
16 |
+
*/
|
17 |
protected $error = array();
|
18 |
|
19 |
+
/**
|
20 |
+
* Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
|
21 |
+
*
|
22 |
+
* @param array $php_files File paths and content for PHP files.
|
23 |
+
* @param array $css_files File paths and content for CSS files.
|
24 |
+
* @param array $other_files Folder names, file paths and content for other files.
|
25 |
+
*/
|
26 |
+
public function check( $php_files, $css_files, $other_files ) {
|
27 |
$ret = true;
|
28 |
$php = implode( ' ', $php_files );
|
29 |
|
31 |
$forbidden_functions = array(
|
32 |
'register_post_type',
|
33 |
'register_taxonomy',
|
34 |
+
'wp_add_dashboard_widget',
|
35 |
+
'register_block_type',
|
36 |
);
|
37 |
|
38 |
foreach ( $forbidden_functions as $function ) {
|
39 |
checkcount();
|
40 |
if ( preg_match( '/[\s?]' . $function . '\s?\(/', $php ) ) {
|
41 |
+
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . sprintf( __( 'The theme uses the %s function, which is plugin-territory functionality.', 'theme-check' ), '<strong>' . esc_html( $function ) . '()</strong>' );
|
42 |
+
$ret = false;
|
43 |
}
|
44 |
}
|
45 |
|
46 |
// Shortcodes can't be used in the post content, so warn about them.
|
47 |
+
if ( false !== strpos( $php, 'add_shortcode(' ) ) {
|
48 |
checkcount();
|
49 |
+
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . sprintf( __( 'The theme uses the %s function. Custom post-content shortcodes are plugin-territory functionality.', 'theme-check' ), '<strong>add_shortcode()</strong>' );
|
50 |
+
$ret = false;
|
51 |
+
}
|
52 |
+
|
53 |
+
// Hooks (actions & filters) that are required to be removed from the theme.
|
54 |
+
$forbidden_hooks = array(
|
55 |
+
'filter' => array(
|
56 |
+
'mime_types',
|
57 |
+
'upload_mimes',
|
58 |
+
'user_contactmethods',
|
59 |
+
),
|
60 |
+
'action' => array(
|
61 |
+
'wp_dashboard_setup',
|
62 |
+
),
|
63 |
+
);
|
64 |
+
|
65 |
+
foreach ( $forbidden_hooks as $type => $hooks ) {
|
66 |
+
foreach ( $hooks as $hook ) {
|
67 |
+
checkcount();
|
68 |
+
if ( preg_match( '/[\s?]add_' . $type . '\s*\(\s*([\'"])' . $hook . '([\'"])\s*,/', $php ) ) {
|
69 |
+
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . sprintf( __( 'The theme uses the %1$s %2$s, which is plugin-territory functionality.', 'theme-check' ), '<strong>' . esc_html( $hook ) . '</strong>', esc_html( $type ) );
|
70 |
+
$ret = false;
|
71 |
+
}
|
72 |
+
}
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Check for removal of non presentational hooks.
|
77 |
+
* Removing emojis is also not allowed.
|
78 |
+
*/
|
79 |
+
$blacklist = array(
|
80 |
+
'wp_head' => array(
|
81 |
+
'wp_generator', // @link https://developer.wordpress.org/reference/functions/wp_generator/
|
82 |
+
'feed_links', // @link https://developer.wordpress.org/reference/functions/feed_links/
|
83 |
+
'feed_links_extra', // @link https://developer.wordpress.org/reference/functions/feed_links_extra/
|
84 |
+
'print_emoji_detection_script', // @link https://developer.wordpress.org/reference/functions/print_emoji_detection_script/
|
85 |
+
'wp_resource_hints', // @link https://developer.wordpress.org/reference/functions/wp_resource_hints/
|
86 |
+
'adjacent_posts_rel_link_wp_head', // @link https://developer.wordpress.org/reference/functions/adjacent_posts_rel_link_wp_head/
|
87 |
+
'wp_shortlink_wp_head', // @link https://developer.wordpress.org/reference/functions/wp_shortlink_wp_head/
|
88 |
+
'_admin_bar_bump_cb', // @link https://developer.wordpress.org/reference/functions/_admin_bar_bump_cb/
|
89 |
+
'rsd_link', // @link https://developer.wordpress.org/reference/functions/rsd_link/
|
90 |
+
'rest_output_link_wp_head', // @link https://developer.wordpress.org/reference/functions/rest_output_link_wp_head/
|
91 |
+
'wp_oembed_add_discovery_links', // @link https://developer.wordpress.org/reference/functions/wp_oembed_add_discovery_links/
|
92 |
+
'wp_oembed_add_host_js', // @link https://developer.wordpress.org/reference/functions/wp_oembed_add_host_js/
|
93 |
+
'rel_canonical', // @link https://developer.wordpress.org/reference/functions/rel_canonical/
|
94 |
+
),
|
95 |
+
'wp_print_styles' => array(
|
96 |
+
'print_emoji_styles', // @link https://developer.wordpress.org/reference/functions/print_emoji_styles/
|
97 |
+
),
|
98 |
+
'admin_print_scripts' => array(
|
99 |
+
'print_emoji_detection_script', //@link https://developer.wordpress.org/reference/functions/print_emoji_detection_script/
|
100 |
+
),
|
101 |
+
'admin_print_styles' => array(
|
102 |
+
'print_emoji_styles', // @link https://developer.wordpress.org/reference/functions/print_emoji_styles/
|
103 |
+
),
|
104 |
+
'template_redirect' => array(
|
105 |
+
'rest_output_link_header', // @link https://developer.wordpress.org/reference/functions/rest_output_link_header/
|
106 |
+
'wp_shortlink_header', // @link https://developer.wordpress.org/reference/functions/wp_shortlink_header/
|
107 |
+
'redirect_canonical', // @link https://developer.wordpress.org/reference/functions/redirect_canonical/
|
108 |
+
),
|
109 |
+
);
|
110 |
+
|
111 |
+
foreach ( $blacklist as $hook => $functions ) {
|
112 |
+
foreach ( $functions as $function ) {
|
113 |
+
checkcount();
|
114 |
+
if ( preg_match( '/[\s?]remove_action\s*\(\s*([\'"])' . $hook . '([\'"])\s*,\s*([\'"])' . $function . '([\'"])/', $php ) ) {
|
115 |
+
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . sprintf( __( 'The theme uses <strong>remove_action %1$s %2$s</strong>, which is plugin-territory functionality.', 'theme-check' ),
|
116 |
+
esc_html( $hook ),
|
117 |
+
esc_html( $function )
|
118 |
+
);
|
119 |
+
$ret = false;
|
120 |
+
}
|
121 |
+
}
|
122 |
}
|
123 |
|
124 |
return $ret;
|
125 |
}
|
126 |
|
127 |
+
/**
|
128 |
+
* Get error messages from the checks.
|
129 |
+
*
|
130 |
+
* @return array Error message.
|
131 |
+
*/
|
132 |
+
public function getError() {
|
133 |
+
return $this->error;
|
134 |
+
}
|
135 |
}
|
136 |
+
|
137 |
+
$themechecks[] = new Plugin_Territory();
|
checks/screenshot.php
CHANGED
@@ -18,13 +18,15 @@ class Screenshot_Checks implements themecheck {
|
|
18 |
foreach ( $other_files as $other_key => $otherfile ) {
|
19 |
|
20 |
if ( ( basename( $other_key ) === 'screenshot.png' || basename( $other_key ) === 'screenshot.jpg' ) && preg_match( '/.*themes\/[^\/]*\/screenshot\.(png|jpg)/', $other_key ) ) {
|
21 |
-
// we have
|
22 |
$image = getimagesize( $other_key );
|
23 |
if ( $image[0] > 1200 || $image[1] > 900 ) {
|
24 |
-
$this->error[] = sprintf('<span class="tc-lead tc-
|
|
|
25 |
}
|
26 |
if ( $image[1] / $image[0] != 0.75 ) {
|
27 |
-
$this->error[] = '<span class="tc-lead tc-
|
|
|
28 |
}
|
29 |
if ( $image[0] != 1200 || $image[1] != 900 ) {
|
30 |
$this->error[] = '<span class="tc-lead tc-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__('Screenshot size should be 1200x900, to account for HiDPI displays. Any 4:3 image size is acceptable, but 1200x900 is preferred.', 'theme-check');
|
@@ -32,7 +34,7 @@ class Screenshot_Checks implements themecheck {
|
|
32 |
}
|
33 |
}
|
34 |
} else {
|
35 |
-
$this->error[] = '<span class="tc-lead tc-
|
36 |
$ret = false;
|
37 |
}
|
38 |
return $ret;
|
18 |
foreach ( $other_files as $other_key => $otherfile ) {
|
19 |
|
20 |
if ( ( basename( $other_key ) === 'screenshot.png' || basename( $other_key ) === 'screenshot.jpg' ) && preg_match( '/.*themes\/[^\/]*\/screenshot\.(png|jpg)/', $other_key ) ) {
|
21 |
+
// we have our screenshot!
|
22 |
$image = getimagesize( $other_key );
|
23 |
if ( $image[0] > 1200 || $image[1] > 900 ) {
|
24 |
+
$this->error[] = sprintf('<span class="tc-lead tc-required">'. __( 'REQUIRED','theme-check' ) . '</span>: ' . __( 'Screenshot is wrong size! Detected: %1$sx%2$spx. Maximum allowed size is 1200x900px.', 'theme-check' ), '<strong>' . $image[0], $image[1] . '</strong>' );
|
25 |
+
$ret = false;
|
26 |
}
|
27 |
if ( $image[1] / $image[0] != 0.75 ) {
|
28 |
+
$this->error[] = '<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('Screenshot dimensions are wrong! Ratio of width to height should be 4:3.', 'theme-check');
|
29 |
+
$ret = false;
|
30 |
}
|
31 |
if ( $image[0] != 1200 || $image[1] != 900 ) {
|
32 |
$this->error[] = '<span class="tc-lead tc-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__('Screenshot size should be 1200x900, to account for HiDPI displays. Any 4:3 image size is acceptable, but 1200x900 is preferred.', 'theme-check');
|
34 |
}
|
35 |
}
|
36 |
} else {
|
37 |
+
$this->error[] = '<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('No screenshot detected! Please include a screenshot.png or screenshot.jpg.', 'theme-check' );
|
38 |
$ret = false;
|
39 |
}
|
40 |
return $ret;
|
checks/siteurl.php
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php // phpcs:ignore WordPress.Files.FileName
|
2 |
+
/**
|
3 |
+
* Checks if site_url is used, and adds an info.
|
4 |
+
*
|
5 |
+
* @link https://developer.wordpress.org/reference/functions/site_url/
|
6 |
+
*/
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Check for site_url
|
10 |
+
*/
|
11 |
+
class SiteUrlCheck implements themecheck {
|
12 |
+
/**
|
13 |
+
* Error messages, warnings and info notices.
|
14 |
+
*
|
15 |
+
* @var array $error
|
16 |
+
*/
|
17 |
+
protected $error = array();
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
|
21 |
+
*
|
22 |
+
* @param array $php_files File paths and content for PHP files.
|
23 |
+
* @param array $css_files File paths and content for CSS files.
|
24 |
+
* @param array $other_files Folder names, file paths and content for other files.
|
25 |
+
*/
|
26 |
+
public function check( $php_files, $css_files, $other_files ) {
|
27 |
+
|
28 |
+
$ret = true;
|
29 |
+
|
30 |
+
checkcount();
|
31 |
+
foreach ( $php_files as $file_path => $file_content ) {
|
32 |
+
$filename = tc_filename( $file_path );
|
33 |
+
|
34 |
+
if ( strpos( $file_content, 'site_url' ) !== false ) {
|
35 |
+
$this->error[] = sprintf(
|
36 |
+
'<span class="tc-lead tc-info">' . __( 'INFO', 'theme-check' ) . '</span>: ' . __( 'site_url() or get_site_url() was found in %1$s. site_url() references the URL where the WordPress files are located. Use home_url() if the intention is to point to the site address (home page), and in the search form.', 'theme-check' ),
|
37 |
+
'<strong>' . $filename . '</strong>'
|
38 |
+
);
|
39 |
+
}
|
40 |
+
}
|
41 |
+
return $ret;
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Get error messages from the checks.
|
46 |
+
*
|
47 |
+
* @return array Error message.
|
48 |
+
*/
|
49 |
+
public function getError() {
|
50 |
+
return $this->error;
|
51 |
+
}
|
52 |
+
}
|
53 |
+
|
54 |
+
$themechecks[] = new SiteUrlCheck();
|
checks/style_needed.php
CHANGED
@@ -15,6 +15,8 @@ class Style_Needed implements themecheck {
|
|
15 |
'[ \t\/*#]*License:' => __( '<strong>License:</strong> is missing from your style.css header.', 'theme-check' ),
|
16 |
'[ \t\/*#]*License URI:' => __( '<strong>License URI:</strong> is missing from your style.css header.', 'theme-check' ),
|
17 |
'[ \t\/*#]*Text Domain:' => __( '<strong>Text Domain:</strong> is missing from your style.css header.', 'theme-check' ),
|
|
|
|
|
18 |
'\.sticky' => __( '<strong>.sticky</strong> css class is needed in your theme css.', 'theme-check' ),
|
19 |
'\.bypostauthor' => __( '<strong>.bypostauthor</strong> css class is needed in your theme css.', 'theme-check' ),
|
20 |
'\.alignleft' => __( '<strong>.alignleft</strong> css class is needed in your theme css.', 'theme-check' ),
|
15 |
'[ \t\/*#]*License:' => __( '<strong>License:</strong> is missing from your style.css header.', 'theme-check' ),
|
16 |
'[ \t\/*#]*License URI:' => __( '<strong>License URI:</strong> is missing from your style.css header.', 'theme-check' ),
|
17 |
'[ \t\/*#]*Text Domain:' => __( '<strong>Text Domain:</strong> is missing from your style.css header.', 'theme-check' ),
|
18 |
+
'[ \t\/*#]*Tested up to:' => __( '<strong>Tested up to:</strong> is missing from your style.css header. Also, this should be numbers only, so <em>5.0</em> and not <em>WP 5.0</em>', 'theme-check' ),
|
19 |
+
'[ \t\/*#]*Requires PHP:' => __( '<strong>Requires PHP:</strong> is missing from your style.css header.', 'theme-check' ),
|
20 |
'\.sticky' => __( '<strong>.sticky</strong> css class is needed in your theme css.', 'theme-check' ),
|
21 |
'\.bypostauthor' => __( '<strong>.bypostauthor</strong> css class is needed in your theme css.', 'theme-check' ),
|
22 |
'\.alignleft' => __( '<strong>.alignleft</strong> css class is needed in your theme css.', 'theme-check' ),
|
checks/style_tags.php
CHANGED
@@ -9,51 +9,55 @@ class Style_Tags implements themecheck {
|
|
9 |
$filenames = array();
|
10 |
|
11 |
foreach( $css_files as $cssfile => $content ) {
|
12 |
-
if ( basename( $cssfile ) === 'style.css' )
|
13 |
-
|
14 |
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
|
|
24 |
|
25 |
-
|
26 |
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
|
|
39 |
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
}
|
50 |
}
|
51 |
-
|
52 |
-
}
|
53 |
-
|
54 |
-
if ( $subject_tags_count > 3 ) {
|
55 |
-
$this->error[] = '<span class="tc-lead tc-required">'. __('REQUIRED','theme-check'). '</span>: ' . sprintf( __('A maximum of 3 subject tags are allowed. The theme has %1$u subjects tags ( %2$s ). Please remove the subject tags, which do not directly apply to the theme.', 'theme-check'), $subject_tags_count, '<strong>' . rtrim( $subject_tags_name, ', ' ) . '</strong>' ) . ' ' . '<a target="_blank" href="https://make.wordpress.org/themes/handbook/review/required/theme-tags/">' . __( 'See Theme Tags', 'theme-check' ) . '</a>';
|
56 |
-
$ret = false;
|
57 |
}
|
58 |
|
59 |
return $ret;
|
9 |
$filenames = array();
|
10 |
|
11 |
foreach( $css_files as $cssfile => $content ) {
|
12 |
+
if ( basename( $cssfile ) === 'style.css' ) {
|
13 |
+
$data = get_theme_data_from_contents( $content );
|
14 |
|
15 |
+
if ( !$data[ 'Tags' ] ) {
|
16 |
+
$this->error[] = '<span class="tc-lead tc-recommended">' . __('RECOMMENDED','theme-check') . '</span>: ' . __( '<strong>Tags:</strong> is either empty or missing in style.css header.', 'theme-check' )
|
17 |
+
. ' ('. basename( dirname( $cssfile)) . ')';
|
18 |
+
}
|
19 |
+
else {
|
20 |
+
$deprecated_tags = array("flexible-width","fixed-width","black","blue","brown","gray","green","orange","pink","purple","red","silver","tan","white","yellow","dark","light","fixed-layout","fluid-layout","responsive-layout","blavatar","holiday","photoblogging","seasonal");
|
21 |
+
$allowed_tags = array('grid-layout',"one-column","two-columns","three-columns","four-columns","left-sidebar","right-sidebar","wide-blocks","flexible-header",'footer-widgets',"accessibility-ready","block-styles","buddypress","custom-background","custom-colors","custom-header","custom-menu","custom-logo","editor-style","featured-image-header","featured-images","front-page-post-form","full-width-template","microformats","post-formats","rtl-language-support","sticky-post","theme-options","threaded-comments","translation-ready",'blog','e-commerce','education','entertainment','food-and-drink','holiday','news','photography','portfolio');
|
22 |
+
$subject_tags = array('blog','e-commerce','education','entertainment','food-and-drink','holiday','news','photography','portfolio');
|
23 |
+
$subject_tags_count = 0;
|
24 |
+
$subject_tags_name = "";
|
25 |
|
26 |
+
foreach( $data[ 'Tags' ] as $tag ) {
|
27 |
|
28 |
+
if ( strpos( strtolower( $tag ), "accessibility-ready") !== false ) {
|
29 |
+
$this->error[] = '<span class="tc-lead tc-info">'. __('INFO','theme-check'). '</span>: ' . __( 'Themes that use the tag accessibility-ready will need to undergo an accessibility review.','theme-check' ) . ' ' . __('See <a href="https://make.wordpress.org/themes/handbook/review/accessibility/">https://make.wordpress.org/themes/handbook/review/accessibility/</a>', 'theme-check' );
|
30 |
+
}
|
31 |
|
32 |
+
if ( ! in_array( strtolower( $tag ), $allowed_tags ) ) {
|
33 |
+
if ( in_array( strtolower( $tag ), $deprecated_tags ) ) {
|
34 |
+
$this->error[] = '<span class="tc-lead tc-required">'. __('REQUIRED','theme-check'). '</span>: ' . sprintf( __('The tag %s has been deprecated, please remove it from your style.css header.', 'theme-check'), '<strong>' . $tag . '</strong>' );
|
35 |
+
$ret = false;
|
36 |
+
} else {
|
37 |
+
$this->error[] = '<span class="tc-lead tc-required">'. __('REQUIRED','theme-check'). '</span>: ' . sprintf( __('Found wrong tag, remove %s from your style.css header.', 'theme-check'), '<strong>' . $tag . '</strong>' );
|
38 |
+
$ret = false;
|
39 |
+
}
|
40 |
+
}
|
41 |
|
42 |
+
if ( in_array( strtolower( $tag ), $subject_tags ) ) {
|
43 |
+
$subject_tags_name .= strtolower( $tag ) . ', ';
|
44 |
+
$subject_tags_count++;
|
45 |
+
}
|
46 |
+
|
47 |
+
if ( in_array( strtolower( $tag ), $allowed_tags ) ) {
|
48 |
+
if ( count( array_keys ($data[ 'Tags' ], $tag ) ) > 1) {
|
49 |
+
$this->error[] = '<span class="tc-lead tc-required">'. __('REQUIRED','theme-check'). '</span>: ' . sprintf( __('The tag %s is being used more than once, please remove it from your style.css header.', 'theme-check'), '<strong>' . $tag . '</strong>' );
|
50 |
+
$ret = false;
|
51 |
+
}
|
52 |
+
}
|
53 |
+
}
|
54 |
|
55 |
+
if ( $subject_tags_count > 3 ) {
|
56 |
+
$this->error[] = '<span class="tc-lead tc-required">'. __('REQUIRED','theme-check'). '</span>: ' . sprintf( __('A maximum of 3 subject tags are allowed. The theme has %1$u subjects tags ( %2$s ). Please remove the subject tags, which do not directly apply to the theme.', 'theme-check'), $subject_tags_count, '<strong>' . rtrim( $subject_tags_name, ', ' ) . '</strong>' ) . ' ' . '<a target="_blank" href="https://make.wordpress.org/themes/handbook/review/required/theme-tags/">' . __( 'See Theme Tags', 'theme-check' ) . '</a>';
|
57 |
+
$ret = false;
|
58 |
+
}
|
59 |
}
|
60 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
}
|
62 |
|
63 |
return $ret;
|
checks/textdomain.php
CHANGED
@@ -140,7 +140,7 @@ class TextDomainCheck implements themecheck {
|
|
140 |
}
|
141 |
|
142 |
if ( $domainscount > 1 ) {
|
143 |
-
$this->error[] = '<span class="tc-lead tc-warning">' . __( '
|
144 |
. __( 'More than one text-domain is being used in this theme. This means the theme will not be compatible with WordPress.org language packs.', 'theme-check' )
|
145 |
. '<br>'
|
146 |
. sprintf( __( 'The domains found are %s', 'theme-check'), '<strong>' . $domainlist . '</strong>' );
|
140 |
}
|
141 |
|
142 |
if ( $domainscount > 1 ) {
|
143 |
+
$this->error[] = '<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check' ) . '</span>: '
|
144 |
. __( 'More than one text-domain is being used in this theme. This means the theme will not be compatible with WordPress.org language packs.', 'theme-check' )
|
145 |
. '<br>'
|
146 |
. sprintf( __( 'The domains found are %s', 'theme-check'), '<strong>' . $domainlist . '</strong>' );
|
checks/title.php
CHANGED
@@ -5,49 +5,59 @@
|
|
5 |
* Is there a call to wp_title()?
|
6 |
* There can't be any hardcoded text in the <title> tag.
|
7 |
*
|
8 |
-
* See:
|
9 |
*/
|
10 |
class Title_Checks implements themecheck {
|
11 |
-
|
12 |
|
13 |
function check( $php_files, $css_files, $other_files ) {
|
14 |
$ret = true;
|
15 |
$php = implode( ' ', $php_files );
|
16 |
|
17 |
-
// Look for add_theme_support( 'title-tag' ) first
|
18 |
$titletag = true;
|
19 |
if ( ! preg_match( '#add_theme_support\s?\(\s?[\'|"]title-tag#', $php ) ) {
|
20 |
-
$this->error[] = '<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('No reference to <strong>add_theme_support( "title-tag" )</strong> was found in the theme.', 'theme-check' );
|
21 |
-
$titletag
|
22 |
-
$ret
|
23 |
}
|
24 |
|
25 |
-
|
26 |
-
checkcount();
|
27 |
-
if ( ( 0 <= strpos( $php, '<title>' ) || 0 <= strpos( $php, '</title>' ) ) && !$titletag ) {
|
28 |
-
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check').'</span>: ' . __( 'The theme must not used the <strong><title></strong> tags.', 'theme-check' );
|
29 |
-
$ret = false;
|
30 |
-
}
|
31 |
|
32 |
-
|
33 |
-
checkcount();
|
34 |
-
if ( 0 <= strpos( $php, 'wp_title(' ) && !$titletag ) {
|
35 |
-
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check').'</span>: ' . __( 'The theme must not call to <strong>wp_title()</strong>.', 'theme-check' );
|
36 |
-
$ret = false;
|
37 |
-
}
|
38 |
|
39 |
-
|
40 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
|
42 |
-
|
43 |
-
|
44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
|
46 |
-
// First looks ahead to see of there's <title>...</title>
|
47 |
-
// Then performs a negative look ahead for <title> wp_title(...); </title>
|
48 |
if ( preg_match( '/(?=<title>(.*)<\/title>)(?!<title>\s*<\?php\s*wp_title\([^\)]*\);?\s*\?>\s*<\/title>)/s', $file_content ) ) {
|
49 |
-
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check').'</span>: ' . __( 'The <strong><title></strong> tags can only contain a call to <strong>wp_title()</strong>. Use the
|
50 |
-
|
|
|
|
|
51 |
}
|
52 |
}
|
53 |
|
@@ -57,4 +67,4 @@ class Title_Checks implements themecheck {
|
|
57 |
function getError() { return $this->error; }
|
58 |
}
|
59 |
|
60 |
-
$themechecks[] = new Title_Checks;
|
5 |
* Is there a call to wp_title()?
|
6 |
* There can't be any hardcoded text in the <title> tag.
|
7 |
*
|
8 |
+
* See: https://make.wordpress.org/themes/handbook/review/required/theme-check-plugin/
|
9 |
*/
|
10 |
class Title_Checks implements themecheck {
|
11 |
+
protected $error = array();
|
12 |
|
13 |
function check( $php_files, $css_files, $other_files ) {
|
14 |
$ret = true;
|
15 |
$php = implode( ' ', $php_files );
|
16 |
|
17 |
+
// Look for add_theme_support( 'title-tag' ) first.
|
18 |
$titletag = true;
|
19 |
if ( ! preg_match( '#add_theme_support\s?\(\s?[\'|"]title-tag#', $php ) ) {
|
20 |
+
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( 'No reference to <strong>add_theme_support( "title-tag" )</strong> was found in the theme.', 'theme-check' );
|
21 |
+
$titletag = false;
|
22 |
+
$ret = false;
|
23 |
}
|
24 |
|
25 |
+
foreach ( $php_files as $file_path => $file_content ) {
|
|
|
|
|
|
|
|
|
|
|
26 |
|
27 |
+
$filename = tc_filename( $file_path );
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
+
// Look for <title> and </title> tags.
|
30 |
+
checkcount();
|
31 |
+
if ( ( 0 <= strpos( $php, '<title>' ) || 0 <= strpos( $php, '</title>' ) ) && ! $titletag ) {
|
32 |
+
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . sprintf( __( 'The theme must not use the <strong><title></strong> tags. Found the tag in %1$s.', 'theme-check' ),
|
33 |
+
'<strong>' . $filename . '</strong>'
|
34 |
+
);
|
35 |
+
$ret = false;
|
36 |
+
}
|
37 |
|
38 |
+
// Check whether there is a call to wp_title().
|
39 |
+
checkcount();
|
40 |
+
if ( 0 <= strpos( $php, 'wp_title(' ) && ! $titletag ) {
|
41 |
+
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . sprintf( __( 'The theme must not call to <strong>wp_title()</strong>. Found wp_title() in %1$s.', 'theme-check' ),
|
42 |
+
'<strong>' . $filename . '</strong>'
|
43 |
+
);
|
44 |
+
$ret = false;
|
45 |
+
}
|
46 |
+
|
47 |
+
// Check whether the the <title> tag contains something besides a call to wp_title().
|
48 |
+
checkcount();
|
49 |
+
// Look for anything that looks like <svg>...</svg> and exclude it (inline svg's have titles too).
|
50 |
+
$file_content = preg_replace( '/<svg.*>.*<\/svg>/s', '', $file_content );
|
51 |
+
// First looks ahead to see of there's <title>...</title>.
|
52 |
+
// Then performs a negative look ahead for <title> wp_title(...); </title>.
|
53 |
+
$error = '/<title>/';
|
54 |
+
$grep = tc_preg( $error, $file_path );
|
55 |
|
|
|
|
|
56 |
if ( preg_match( '/(?=<title>(.*)<\/title>)(?!<title>\s*<\?php\s*wp_title\([^\)]*\);?\s*\?>\s*<\/title>)/s', $file_content ) ) {
|
57 |
+
$this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check').'</span>: ' . sprintf( __( '%1$s: The <strong><title></strong> tags can only contain a call to <strong>wp_title()</strong>. Use the <strong>wp_title filter</strong> to modify the output.', 'theme-check' ),
|
58 |
+
'<strong>' . $filename . '</strong>'
|
59 |
+
) . $grep;
|
60 |
+
$ret = false;
|
61 |
}
|
62 |
}
|
63 |
|
67 |
function getError() { return $this->error; }
|
68 |
}
|
69 |
|
70 |
+
$themechecks[] = new Title_Checks();
|
checks/underscores.php
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|