Theme Check - Version 20200731.1

Version Description

Download this release

Release Info

Developer Otto42
Plugin Icon 128x128 Theme Check
Version 20200731.1
Comparing to
See all releases

Code changes from version 20200612.1 to 20200731.1

assets/style.css CHANGED
@@ -1,83 +1,83 @@
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
  }
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,5 +1,7 @@
1
- = 20200612.1 =
2
- * Release to WordPress.org plugins directory
 
 
3
 
4
  = 20200611.1 =
5
  * Added escaping checks
1
+ = 20200731.1 =
2
+ * Added add_menu_page & add_submenu_page to the allowed functions list
3
+ * Added loco.xml to the allowed files list and extend the allowlist check functionality to support an array of (possible) filenames.
4
+ * Updated error messages
5
 
6
  = 20200611.1 =
7
  * Added escaping checks
checks/admin_menu.php CHANGED
@@ -31,7 +31,11 @@ class AdminMenu implements themecheck {
31
  // Note to TGMPA: Stop trying to bypass theme check.
32
 
33
  $checks = array(
34
- '/(?<!function)[^_>:](add_[^_\'",();]+?_page)/' => __( 'Themes should use <strong>add_theme_page()</strong> for adding admin pages.', 'theme-check' )
 
 
 
 
35
  );
36
 
37
 
@@ -40,13 +44,20 @@ class AdminMenu implements themecheck {
40
  checkcount();
41
  if ( preg_match_all( $key, $phpfile, $matches ) ) {
42
  foreach ($matches[1] as $match) {
43
- if ($match == 'add_theme_page') {
44
  continue;
45
  }
46
  $filename = tc_filename( $php_key );
47
  $error = ltrim( rtrim( $match, '(' ) );
48
  $grep = tc_grep( $error, $php_key );
49
- $this->error[] = sprintf('<span class="tc-lead tc-required">'.__( 'REQUIRED', 'theme-check' ) .'</span>: <strong>%1$s</strong>. %2$s%3$s', $filename, $check, $grep);
 
 
 
 
 
 
 
50
  $ret = false;
51
  }
52
  }
31
  // Note to TGMPA: Stop trying to bypass theme check.
32
 
33
  $checks = array(
34
+ '/(?<!function)[^_>:](add_[^_\'",();]+?_page)/' => _x(
35
+ 'Themes must not use <strong>%s()</strong>.',
36
+ 'function name',
37
+ 'theme-check'
38
+ )
39
  );
40
 
41
 
44
  checkcount();
45
  if ( preg_match_all( $key, $phpfile, $matches ) ) {
46
  foreach ($matches[1] as $match) {
47
+ if ( in_array( $match, array( 'add_theme_page', 'add_menu_page', 'add_submenu_page' ), true ) ) {
48
  continue;
49
  }
50
  $filename = tc_filename( $php_key );
51
  $error = ltrim( rtrim( $match, '(' ) );
52
  $grep = tc_grep( $error, $php_key );
53
+ $notallowed = sprintf( $check, $match );
54
+
55
+ $this->error[] = sprintf(
56
+ '<span class="tc-lead tc-required">'.__( 'REQUIRED', 'theme-check' ) .'</span>: <strong>%1$s</strong>. %2$s%3$s%',
57
+ $filename,
58
+ $notallowed,
59
+ $grep
60
+ );
61
  $ret = false;
62
  }
63
  }
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> &lt;?php if ( is_singular() ) wp_enqueue_script( "comment-reply" ); ?&gt;</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> &lt;?php if ( is_singular() ) wp_enqueue_script( "comment-reply" ); ?&gt;</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/escaping.php CHANGED
@@ -1,105 +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();
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/filenames.php CHANGED
@@ -18,9 +18,12 @@ class File_Checks implements themecheck {
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' ),
@@ -53,12 +56,18 @@ class File_Checks implements themecheck {
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
  }
18
  array_push( $filenames, strtolower( basename( $php_key ) ) );
19
  }
20
 
21
+ $allowlist = array(
22
+ 'wpml-config.xml',
23
+ 'loco.xml'
24
+ );
25
 
26
+ $blocklist = array(
27
  'thumbs\.db' => __( 'Windows thumbnail store', 'theme-check' ),
28
  'desktop\.ini' => __( 'windows system file', 'theme-check' ),
29
  'project\.properties' => __( 'NetBeans Project File', 'theme-check' ),
56
 
57
  checkcount();
58
 
59
+ foreach ( $blocklist as $file => $reason ) {
60
  if ( $filename = preg_grep( '/' . $file . '/', $filenames ) ) {
61
+ $commons = array_intersect( $filename, $allowlist );
62
+ foreach ( $commons as $common ) {
63
+ if (( $allowed_key = array_search($common, $filename)) !== false) {
64
+ unset( $filename[$allowed_key] );
65
+ }
66
+ }
67
+ if ( empty( $filename ) ) {
68
  continue;
69
  }
70
+ $error = implode( ' ', array_unique( $filename ) );
71
  $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 );
72
  $ret = false;
73
  }
checks/i18n.php CHANGED
@@ -1,71 +1,70 @@
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;
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
+ $ret = true;
10
+ $error = '';
11
+ checkcount();
12
+
13
+ // make sure the tokenizer is available
14
+ if ( !function_exists( 'token_get_all' ) ) return true;
15
+
16
+ foreach ( $php_files as $php_key => $phpfile ) {
17
+ $error='';
18
+
19
+ $stmts = array();
20
+ foreach ( array('_e(', '__(', '_e (', '__ (') as $finder) {
21
+ $search = $phpfile;
22
+ while ( ( $pos = strpos($search, $finder) ) !== false ) {
23
+ $search = substr($search,$pos);
24
+ $open=1;
25
+ $i=strpos($search,'(')+1;
26
+ while( $open>0 ) {
27
+ switch($search[$i]) {
28
+ case '(':
29
+ $open++; break;
30
+ case ')':
31
+ $open--; break;
32
+ }
33
+ $i++;
34
+ }
35
+ $stmts[] = substr($search,0,$i);
36
+ $search = substr($search,$i);
37
+ }
38
+ }
39
+
40
+ foreach ( $stmts as $match ) {
41
+ $tokens = @token_get_all('<?php '.$match.';');
42
+ if (!empty($tokens)) {
43
+ foreach ($tokens as $token) {
44
+ if (is_array($token) && in_array( $token[0], array( T_VARIABLE ) ) ) {
45
+ $filename = tc_filename( $php_key );
46
+ $grep = tc_grep( ltrim( $match ), $php_key );
47
+ preg_match( '/[^\s]*\s[0-9]+/', $grep, $line);
48
+ $error = '';
49
+ if ( isset( $line[0] ) ) {
50
+ $error = ( !strpos( $error, $line[0] ) ) ? $grep : '';
51
+ }
52
+ $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'),
53
+ '<strong>' . $token[1] . '</strong>',
54
+ '<strong>' . $filename . '</strong>',
55
+ $error
56
+ );
57
+ break; // stop looking at the tokens on this line once a variable is found
58
+ }
59
+ }
60
+ }
61
+ }
62
+
63
+
64
+ }
65
+ return $ret;
66
+ }
67
+
68
+ function getError() { return $this->error; }
69
+ }
 
70
  $themechecks[] = new I18NCheck;
checks/included-plugins.php CHANGED
@@ -11,13 +11,13 @@ class IncludedPlugins implements themecheck {
11
  array_push( $filenames, strtolower( basename( $other_key ) ) );
12
  }
13
 
14
- $blacklist = array(
15
  '\.zip' => __( 'Zipped Plugin', 'theme-check' ),
16
  );
17
 
18
  checkcount();
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 );
11
  array_push( $filenames, strtolower( basename( $other_key ) ) );
12
  }
13
 
14
+ $blocklist = array(
15
  '\.zip' => __( 'Zipped Plugin', 'theme-check' ),
16
  );
17
 
18
  checkcount();
19
 
20
+ foreach ( $blocklist 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 );
checks/nongplsites.php CHANGED
@@ -1,46 +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;
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/plugin-territory.php CHANGED
@@ -76,7 +76,7 @@ class Plugin_Territory implements themecheck {
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/
@@ -108,7 +108,7 @@ class Plugin_Territory implements themecheck {
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 ) ) {
76
  * Check for removal of non presentational hooks.
77
  * Removing emojis is also not allowed.
78
  */
79
+ $blocklist = 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/
108
  ),
109
  );
110
 
111
+ foreach ( $blocklist as $hook => $functions ) {
112
  foreach ( $functions as $function ) {
113
  checkcount();
114
  if ( preg_match( '/[\s?]remove_action\s*\(\s*([\'"])' . $hook . '([\'"])\s*,\s*([\'"])' . $function . '([\'"])/', $php ) ) {
checks/siteurl.php CHANGED
@@ -1,54 +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();
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/underscores.php CHANGED
@@ -1,57 +1,57 @@
1
- <?php
2
- /**
3
- * Check if:
4
- * Theme or author URI refers to _s
5
- * The readme is a copy of _s
6
- * footer credit link refers to _s
7
- */
8
- class UnderscoresCheck implements themecheck {
9
- protected $error = array();
10
-
11
- function check( $php_files, $css_files, $other_files ) {
12
-
13
- $ret = true;
14
- global $data;
15
-
16
- checkcount();
17
- if ( ! empty( $data['AuthorURI'] ) || ! empty( $data['URI'] ) ) {
18
-
19
- if ( stripos( $data['URI'], 'underscores.me' ) || stripos( $data['AuthorURI'], 'underscores.me' ) ) {
20
- $this->error[] .= __( '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( 'Using underscores.me as Theme URI or Autor URI is not allowed.', 'theme-check' ) );
21
- $ret = false;
22
- }
23
- }
24
-
25
- checkcount();
26
- foreach ( $other_files as $file_path => $file_content ) {
27
- $filename = tc_filename( $file_path );
28
- if ( preg_match( "/Hi. I'm a starter theme called `_s`, or `underscores`, if you like./", $file_content ) || preg_match( "/Hi. I'm a starter theme called <code>_s<\/code>, or <em>underscores<\/em>, if/", $file_content ) ) {
29
- $error = "/Hi. I'm a starter theme called/";
30
- $grep = tc_preg( $error, $file_path );
31
- $this->error[] = sprintf( '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( 'Found a copy of Underscores. See %1$s. <a href="https://github.com/Automattic/_s" target="_new">Learn how to update the files for your own theme.</a>', 'theme-check' ),
32
- '<strong>' . $filename . '</strong>' ) . $grep;
33
- $ret = false;
34
- }
35
- }
36
-
37
- /**
38
- * This check is limited to footer.php, since we are looking for clones of underscores.
39
- */
40
- checkcount();
41
- foreach ( $php_files as $file_path => $file_content ) {
42
- $filename = tc_filename( $file_path );
43
- if ( 'footer.php' === $filename && preg_match( '/Underscores.me/', $file_content ) ) {
44
- $error = '/Underscores.me/';
45
- $grep = tc_preg( $error, $file_path );
46
- $this->error[] = sprintf( '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( 'Found a copy of Underscores. See %1$s. Update the files for your own theme.', 'theme-check' ),
47
- '<strong>' . $filename . '</strong>' ) . $grep;
48
- $ret = false;
49
- }
50
- }
51
-
52
- return $ret;
53
- }
54
-
55
- function getError() { return $this->error; }
56
- }
57
- $themechecks[] = new UnderscoresCheck();
1
+ <?php
2
+ /**
3
+ * Check if:
4
+ * Theme or author URI refers to _s
5
+ * The readme is a copy of _s
6
+ * footer credit link refers to _s
7
+ */
8
+ class UnderscoresCheck implements themecheck {
9
+ protected $error = array();
10
+
11
+ function check( $php_files, $css_files, $other_files ) {
12
+
13
+ $ret = true;
14
+ global $data;
15
+
16
+ checkcount();
17
+ if ( ! empty( $data['AuthorURI'] ) || ! empty( $data['URI'] ) ) {
18
+
19
+ if ( stripos( $data['URI'], 'underscores.me' ) || stripos( $data['AuthorURI'], 'underscores.me' ) ) {
20
+ $this->error[] .= __( '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( 'Using underscores.me as Theme URI or Autor URI is not allowed.', 'theme-check' ) );
21
+ $ret = false;
22
+ }
23
+ }
24
+
25
+ checkcount();
26
+ foreach ( $other_files as $file_path => $file_content ) {
27
+ $filename = tc_filename( $file_path );
28
+ if ( preg_match( "/Hi. I'm a starter theme called `_s`, or `underscores`, if you like./", $file_content ) || preg_match( "/Hi. I'm a starter theme called <code>_s<\/code>, or <em>underscores<\/em>, if/", $file_content ) ) {
29
+ $error = "/Hi. I'm a starter theme called/";
30
+ $grep = tc_preg( $error, $file_path );
31
+ $this->error[] = sprintf( '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( 'Found a copy of Underscores. See %1$s. <a href="https://github.com/Automattic/_s" target="_new">Learn how to update the files for your own theme.</a>', 'theme-check' ),
32
+ '<strong>' . $filename . '</strong>' ) . $grep;
33
+ $ret = false;
34
+ }
35
+ }
36
+
37
+ /**
38
+ * This check is limited to footer.php, since we are looking for clones of underscores.
39
+ */
40
+ checkcount();
41
+ foreach ( $php_files as $file_path => $file_content ) {
42
+ $filename = tc_filename( $file_path );
43
+ if ( 'footer.php' === $filename && preg_match( '/Underscores.me/', $file_content ) ) {
44
+ $error = '/Underscores.me/';
45
+ $grep = tc_preg( $error, $file_path );
46
+ $this->error[] = sprintf( '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( 'Found a copy of Underscores. See %1$s. Update the files for your own theme.', 'theme-check' ),
47
+ '<strong>' . $filename . '</strong>' ) . $grep;
48
+ $ret = false;
49
+ }
50
+ }
51
+
52
+ return $ret;
53
+ }
54
+
55
+ function getError() { return $this->error; }
56
+ }
57
+ $themechecks[] = new UnderscoresCheck();
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: Otto42, pross, poena, dingo-d, acosmin, joyously
3
  Requires at Least: 3.7
4
  Tested Up To: 5.4
5
- Tags: template, theme, check, checker, tool, wordpress, wordpress.org, upload, uploader, test, guideline, review
6
- Stable tag: 20200612.1
7
 
8
  A simple and easy way to test your theme for all the latest WordPress standards and practices. A great theme development tool!
9
 
2
  Contributors: Otto42, pross, poena, dingo-d, acosmin, joyously
3
  Requires at Least: 3.7
4
  Tested Up To: 5.4
5
+ Tags: template, theme, check, checker, tool, wordpress.org, upload, uploader, test, guideline, review
6
+ Stable tag: 20200731.1
7
 
8
  A simple and easy way to test your theme for all the latest WordPress standards and practices. A great theme development tool!
9
 
theme-check.php CHANGED
@@ -3,8 +3,8 @@
3
  Plugin Name: Theme Check
4
  Plugin URI: https://github.com/WordPress/theme-check/
5
  Description: A simple and easy way to test your theme for all the latest WordPress standards and practices. A great theme development tool!
6
- Author: Theme Review Team
7
- Version: 20200612.1
8
  Text Domain: theme-check
9
  License: GPLv2
10
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
3
  Plugin Name: Theme Check
4
  Plugin URI: https://github.com/WordPress/theme-check/
5
  Description: A simple and easy way to test your theme for all the latest WordPress standards and practices. A great theme development tool!
6
+ Author: The WordPress Theme Review Team
7
+ Version: 20200731.1
8
  Text Domain: theme-check
9
  License: GPLv2
10
  License URI: https://www.gnu.org/licenses/gpl-2.0.html