Theme Check - Version 20210617

Version Description

Download this release

Release Info

Developer githubsync
Plugin Icon 128x128 Theme Check
Version 20210617
Comparing to
See all releases

Code changes from version 20200922.1 to 20210617

Files changed (105) hide show
  1. README.md +54 -0
  2. checkbase.php +170 -135
  3. checks/admin_menu.php +0 -73
  4. checks/adminbar.php +0 -55
  5. checks/badthings.php +0 -60
  6. checks/basic.php +0 -47
  7. checks/cdn.php +0 -45
  8. checks/class-admin-menu-check.php +107 -0
  9. checks/class-bad-things-check.php +114 -0
  10. checks/class-basic-check.php +84 -0
  11. checks/class-block-patterns-check.php +62 -0
  12. checks/class-cdn-check.php +79 -0
  13. checks/class-comment-pagination-check.php +62 -0
  14. checks/class-comment-reply-check.php +63 -0
  15. checks/class-comments-check.php +67 -0
  16. checks/class-constants-check.php +83 -0
  17. checks/class-customizer-check.php +99 -0
  18. checks/class-deprecated-check.php +1201 -0
  19. checks/{more_deprecated.php → class-deprecated-param-check.php} +43 -9
  20. checks/class-deregister-check.php +45 -0
  21. checks/class-directories-check.php +73 -0
  22. checks/class-editor-style-check.php +55 -0
  23. checks/{escaping.php → class-escaping-check.php} +122 -105
  24. checks/class-favicon-check.php +66 -0
  25. checks/{filenames.php → class-file-check.php} +53 -18
  26. checks/class-filesystem-http-check.php +81 -0
  27. checks/class-fse-required-files-check.php +63 -0
  28. checks/class-generated-check.php +74 -0
  29. checks/class-gravatar-check.php +56 -0
  30. checks/class-i18n-check.php +103 -0
  31. checks/class-iframe-check.php +70 -0
  32. checks/class-include-check.php +69 -0
  33. checks/class-included-zip-check.php +69 -0
  34. checks/class-line-endings-check.php +92 -0
  35. checks/class-link-check.php +93 -0
  36. checks/class-nav-menu-check.php +127 -0
  37. checks/class-no-hidden-admin-bar-check.php +86 -0
  38. checks/class-non-gpl-check.php +75 -0
  39. checks/class-non-printable-check.php +61 -0
  40. checks/class-php-short-tags-check.php +58 -0
  41. checks/{plugin-territory.php → class-plugin-territory-check.php} +39 -10
  42. checks/class-post-format-check.php +77 -0
  43. checks/class-post-pagination-check.php +60 -0
  44. checks/class-post-thumbnail-check.php +63 -0
  45. checks/class-screen-reader-text-check.php +60 -0
  46. checks/class-screenshot-check.php +102 -0
  47. checks/class-script-tag-check.php +64 -0
  48. checks/class-search-form-check.php +86 -0
  49. checks/{siteurl.php → class-site-url-check.php} +59 -54
  50. checks/class-style-css-header-check.php +68 -0
  51. checks/class-style-tags-check.php +238 -0
  52. checks/class-suggested-styles-check.php +78 -0
  53. checks/class-tag-check.php +41 -0
  54. checks/class-theme-support-check.php +64 -0
  55. checks/class-theme-support-title-tag.php +53 -0
  56. checks/class-time-date-check.php +67 -0
  57. checks/class-title-check.php +82 -0
  58. checks/class-underscores-check.php +115 -0
  59. checks/class-uri-check.php +81 -0
  60. checks/class-widgets-check.php +103 -0
  61. checks/class-worms-check.php +61 -0
  62. checks/comment_reply.php +0 -27
  63. checks/commpage.php +0 -26
  64. checks/constants.php +0 -41
  65. checks/content-width.php +16 -8
  66. checks/customizer.php +0 -59
  67. checks/customs.php +0 -26
  68. checks/dep_recommend.php +0 -67
  69. checks/deprecated.php +0 -345
  70. checks/deregister.php +0 -29
  71. checks/directories.php +0 -36
  72. checks/editorstyle.php +0 -21
  73. checks/favicon.php +0 -33
  74. checks/generated.php +0 -42
  75. checks/gravatar.php +0 -24
  76. checks/i18n.php +0 -70
  77. checks/iframes.php +0 -29
  78. checks/include.php +0 -29
  79. checks/included-plugins.php +0 -34
  80. checks/lineendings.php +0 -43
  81. checks/links.php +0 -34
  82. checks/malware.php +0 -34
  83. checks/navmenu.php +0 -73
  84. checks/nongplsites.php +0 -46
  85. checks/nonprintable.php +0 -27
  86. checks/phpshort.php +0 -24
  87. checks/post-formats.php +0 -38
  88. checks/postsnav.php +0 -28
  89. checks/postthumb.php +0 -27
  90. checks/screenshot.php +0 -45
  91. checks/searchform.php +0 -26
  92. checks/style_needed.php +0 -43
  93. checks/style_suggested.php +0 -29
  94. checks/style_tags.php +0 -158
  95. checks/tags.php +0 -22
  96. checks/textdomain.php +138 -92
  97. checks/time_date.php +0 -31
  98. checks/title.php +0 -70
  99. checks/underscores.php +0 -57
  100. checks/uri.php +0 -31
  101. checks/widgets.php +0 -42
  102. checks/worms.php +0 -33
  103. main.php +147 -187
  104. readme.txt +3 -3
  105. theme-check.php +7 -5
README.md ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Theme Check
2
+
3
+ The theme check plugin is an easy way to test your theme and make sure it's up to spec with the latest [theme review](https://make.wordpress.org/themes/handbook/review/) standards. With it, you can run all the same automated testing tools on your theme that WordPress.org uses for theme submissions.
4
+
5
+ The tests are run through a simple admin menu and all results are displayed at once. This is very handy for theme developers, or anybody looking to make sure that their theme supports the latest WordPress theme standards and practices.
6
+
7
+ ## Frequently Asked Questions
8
+
9
+ ### Why does it flag something as bad?
10
+
11
+ It's not flagging "bad" things, as such. The theme check is designed to be a non-perfect way to test for compliance with the [Theme Review](https://make.wordpress.org/themes/handbook/review/) guidelines. Not all themes must adhere to these guidelines. The purpose of the checking tool is to ensure that themes uploaded to the central [WordPress.org theme repository](http://wordpress.org/themes/) meet the latest standards of WordPress themes and will work on a wide variety of sites.
12
+
13
+ Many sites use customized themes, and that's perfectly okay. But themes that are intended for use on many different kinds of sites by the public need to have a certain minimum level of capabilities, in order to ensure proper functioning in many different environments. The Theme Review guidelines are created with that goal in mind.
14
+
15
+ This theme checker is not perfect, and never will be. It is only a tool to help theme authors, or anybody else who wants to make their theme more capable. All themes submitted to WordPress.org are hand-reviewed by a team of experts. The automated theme checker is meant to be a useful tool only, not an absolute system of measurement.
16
+
17
+ This plugin does not decide the guidelines used. Any issues with particular theme review guidelines should be discussed on the [Make Themes site](https://make.wordpress.org/themes), or [https://github.com/WPTRT/Theme-Requirements](https://github.com/WPTRT/Theme-Requirements)
18
+
19
+ ## Other Notes
20
+
21
+ ### How to enable trac formatting
22
+ The Theme Review team use this plugin while reviewing themes and copy/paste the output into trac tickets, the trac system has its own markup language.
23
+ To enable trac formatting in Theme-Check you need to define a couple of variables in wp-config.php:
24
+ *TC_PRE* and *TC_POST* are used as a ticket header and footer.
25
+ Examples:
26
+ ```
27
+ define( 'TC_PRE', 'Theme Review:[[br]]
28
+ - Themes should be reviewed using "define(\'WP_DEBUG\', true);" in wp-config.php[[br]]
29
+ - Themes should be reviewed using the test data from the Theme Checklists (TC)
30
+ -----
31
+ ' );
32
+ ```
33
+
34
+ ```
35
+ define( 'TC_POST', 'Feel free to make use of the contact details below if you have any questions,
36
+ comments, or feedback:[[br]]
37
+ [[br]]
38
+ * Leave a comment on this ticket[[br]]
39
+ * Send an email to the Theme Review email list[[br]]
40
+ * Use the #wordpress-themes IRC channel on Freenode.' );
41
+ ```
42
+
43
+ If **either** of these two vars are defined a new trac tickbox will appear next to the *Check it!* button.
44
+
45
+ If you want to exclude checking other files in development directories return `true` for the filter `tc_skip_development_directories`.
46
+
47
+ ```
48
+ add_filter( 'tc_skip_development_directories', '__return_true' );
49
+ ```
50
+
51
+ To add more directories to the paths where other files are excluded then add them to the array through the `tc_common_dev_directories` filter.
52
+
53
+ ## Contributors
54
+ Otto42, pross, The theme review team
checkbase.php CHANGED
@@ -1,9 +1,18 @@
1
  <?php
2
- // main global to hold our checks
 
 
 
 
 
 
 
 
 
3
  global $themechecks;
4
  $themechecks = array();
5
 
6
- // counter for the checks
7
  global $checkcount;
8
  $checkcount = 0;
9
 
@@ -18,21 +27,83 @@ interface themecheck {
18
  }
19
 
20
  // load all the checks in the checks directory.
21
- $dir = 'checks';
22
- foreach ( glob( dirname( __FILE__ ) . "/{$dir}/*.php" ) as $file ) {
23
  include $file;
24
  }
25
 
26
  do_action( 'themecheck_checks_loaded' );
27
 
28
- function run_themechecks( $php, $css, $other ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  global $themechecks;
 
30
  $pass = true;
 
 
 
31
  foreach ( $themechecks as $check ) {
32
  if ( $check instanceof themecheck ) {
 
 
 
 
33
  $pass = $pass & $check->check( $php, $css, $other );
34
  }
35
  }
 
36
  return $pass;
37
  }
38
 
@@ -93,7 +164,7 @@ function tc_grep( $error, $file ) {
93
  $error = str_replace( '"', "'", $error );
94
  $this_line = str_replace( '"', "'", $this_line );
95
  $error = ltrim( $error );
96
- $pos = strpos( $this_line, $error );
97
  $pre = ( false !== $pos ? substr( $this_line, 0, $pos ) : false );
98
  $pre = ltrim( htmlspecialchars( $pre ) );
99
  $bad_lines .= "<pre class='tc-grep'>" . __( 'Line ', 'theme-check' ) . ( $line_index + 1 ) . ': ' . $pre . htmlspecialchars( substr( stristr( $this_line, $error ), 0, 75 ) ) . '</pre>';
@@ -149,152 +220,116 @@ function tc_trac( $e ) {
149
  return $e;
150
  }
151
 
152
- function listdir( $dir ) {
153
- $files = array();
154
- $dir_iterator = new RecursiveDirectoryIterator( $dir );
155
- $iterator = new RecursiveIteratorIterator( $dir_iterator, RecursiveIteratorIterator::SELF_FIRST );
156
-
157
- foreach ( $iterator as $file ) {
158
- array_push( $files, $file->getPathname() );
159
- }
160
- return $files;
161
- }
162
-
163
- function get_theme_data_from_contents( $theme_data ) {
164
- $themes_allowed_tags = array(
165
- 'a' => array(
166
- 'href' => array(),
167
- 'title' => array(),
168
- ),
169
- 'abbr' => array(
170
- 'title' => array(),
171
- ),
172
- 'acronym' => array(
173
- 'title' => array(),
174
- ),
175
- 'code' => array(),
176
- 'em' => array(),
177
- 'strong' => array(),
178
  );
179
-
180
- $theme_data = str_replace( '\r', '\n', $theme_data );
181
- preg_match( '|^[ \t\/*#@]*Theme Name:(.*)$|mi', $theme_data, $theme_name );
182
- preg_match( '|^[ \t\/*#@]*Theme URI:(.*)$|mi', $theme_data, $theme_uri );
183
- preg_match( '|^[ \t\/*#@]*Description:(.*)$|mi', $theme_data, $description );
184
-
185
- if ( preg_match( '|^[ \t\/*#@]*Author URI:(.*)$|mi', $theme_data, $author_uri ) ) {
186
- $author_uri = esc_url( trim( $author_uri[1] ) );
187
- } else {
188
- $author_uri = '';
189
- }
190
-
191
- if ( preg_match( '|^[ \t\/*#@]*Template:(.*)$|mi', $theme_data, $template ) ) {
192
- $template = wp_kses( trim( $template[1] ), $themes_allowed_tags );
193
- } else {
194
- $template = '';
195
- }
196
-
197
- if ( preg_match( '|^[ \t\/*#@]*Version:(.*)|mi', $theme_data, $version ) ) {
198
- $version = wp_kses( trim( $version[1] ), $themes_allowed_tags );
199
- } else {
200
- $version = '';
201
- }
202
-
203
- if ( preg_match( '|^[ \t\/*#@]*Status:(.*)|mi', $theme_data, $status ) ) {
204
- $status = wp_kses( trim( $status[1] ), $themes_allowed_tags );
205
- } else {
206
- $status = 'publish';
207
- }
208
-
209
- if ( preg_match( '|^[ \t\/*#@]*Tags:(.*)|mi', $theme_data, $tags ) ) {
210
- $tags = array_map( 'trim', explode( ',', wp_kses( trim( $tags[1] ), array() ) ) );
211
- } else {
212
- $tags = array();
213
- }
214
-
215
- $theme = ( isset( $theme_name[1] ) ) ? wp_kses( trim( $theme_name[1] ), $themes_allowed_tags ) : '';
216
-
217
- $theme_uri = ( isset( $theme_uri[1] ) ) ? esc_url( trim( $theme_uri[1] ) ) : '';
218
-
219
- $description = ( isset( $description[1] ) ) ? wp_kses( trim( $description[1] ), $themes_allowed_tags ) : '';
220
-
221
- if ( preg_match( '|^[ \t\/*#@]*Author:(.*)$|mi', $theme_data, $author_name ) ) {
222
- if ( empty( $author_uri ) ) {
223
- $author = wp_kses( trim( $author_name[1] ), $themes_allowed_tags );
224
  } else {
225
- $author = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $author_uri, __( 'Visit author homepage', 'theme-check' ), wp_kses( trim( $author_name[1] ), $themes_allowed_tags ) );
 
 
 
 
226
  }
227
- } else {
228
- $author = __( 'Anonymous', 'theme-check' );
229
  }
 
 
230
 
231
- return array(
232
- 'Name' => $theme,
233
- 'Title' => $theme,
234
- 'URI' => $theme_uri,
235
- 'Description' => $description,
236
- 'Author' => $author,
237
- 'Author_URI' => $author_uri,
238
- 'Version' => $version,
239
- 'Template' => $template,
240
- 'Status' => $status,
241
- 'Tags' => $tags,
 
 
 
 
 
242
  );
 
 
 
 
 
 
 
243
  }
244
 
245
- /*
246
- * 3.3/3.4 compat
247
  *
 
 
 
 
 
248
  */
249
- function tc_get_themes() {
 
250
 
251
- if ( ! class_exists( 'WP_Theme' ) ) {
252
- return wp_get_theme();
 
 
253
  }
254
 
255
- global $wp_themes;
256
- if ( isset( $wp_themes ) ) {
257
- return $wp_themes;
258
  }
259
 
260
- $themes = wp_get_themes();
261
- $wp_themes = array();
262
-
263
- foreach ( $themes as $theme ) {
264
- $name = $theme->get( 'Name' );
265
- if ( isset( $wp_themes[ $name ] ) ) {
266
- $wp_themes[ $name . '/' . $theme->get_stylesheet() ] = $theme;
267
- } else {
268
- $wp_themes[ $name ] = $theme;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  }
270
  }
271
 
272
- return $wp_themes;
273
- }
274
-
275
- function tc_get_theme_data( $theme_file ) {
276
 
277
- if ( ! class_exists( 'WP_Theme' ) ) {
278
- return wp_get_theme( $theme_file );
279
- }
280
-
281
- $theme = new WP_Theme( basename( dirname( $theme_file ) ), dirname( dirname( $theme_file ) ) );
282
-
283
- $theme_data = array(
284
- 'Name' => $theme->get( 'Name' ),
285
- 'URI' => $theme->display( 'ThemeURI', true, false ),
286
- 'Description' => $theme->display( 'Description', true, false ),
287
- 'Author' => $theme->display( 'Author', true, false ),
288
- 'AuthorURI' => $theme->display( 'AuthorURI', true, false ),
289
- 'Version' => $theme->get( 'Version' ),
290
- 'Template' => $theme->get( 'Template' ),
291
- 'Status' => $theme->get( 'Status' ),
292
- 'Tags' => $theme->get( 'Tags' ),
293
- 'Title' => $theme->get( 'Name' ),
294
- 'AuthorName' => $theme->display( 'Author', false, false ),
295
- 'License' => $theme->display( 'License', false, false ),
296
- 'License URI' => $theme->display( 'License URI', false, false ),
297
- 'Template Version' => $theme->display( 'Template Version', false, false ),
298
- );
299
- return $theme_data;
300
  }
1
  <?php
2
+ /**
3
+ * Runs checks against themes and displays the results
4
+ *
5
+ * Runs checks against themes and displays the results. Includes helper functions
6
+ * for performing checks.
7
+ *
8
+ * @package Theme Check
9
+ */
10
+
11
+ // main global to hold our checks.
12
  global $themechecks;
13
  $themechecks = array();
14
 
15
+ // counter for the checks.
16
  global $checkcount;
17
  $checkcount = 0;
18
 
27
  }
28
 
29
  // load all the checks in the checks directory.
30
+ foreach ( glob( __DIR__ . '/checks/*.php' ) as $file ) {
 
31
  include $file;
32
  }
33
 
34
  do_action( 'themecheck_checks_loaded' );
35
 
36
+ /**
37
+ * Run Theme Check against a given theme.
38
+ *
39
+ * @param WP_Theme $theme A WP_Theme instance.
40
+ * @param string $theme_slug The slug of the given theme.
41
+ * @return bool
42
+ */
43
+ function run_themechecks_against_theme( $theme, $theme_slug ) {
44
+ $files = $theme->get_files(
45
+ null /* all file types */,
46
+ -1 /* infinite recursion */,
47
+ true /* include parent theme files */
48
+ );
49
+
50
+ foreach ( $files as $filename ) {
51
+ if ( substr( $filename, -4 ) === '.php' ) {
52
+ $php[ $filename ] = file_get_contents( $filename );
53
+ $php[ $filename ] = tc_strip_comments( $php[ $filename ] );
54
+ } elseif ( substr( $filename, -4 ) === '.css' ) {
55
+ $css[ $filename ] = file_get_contents( $filename );
56
+ } else {
57
+ // In local development it might be useful to skip other files
58
+ // (non .php or .css files) in dev directories.
59
+ if ( apply_filters( 'tc_skip_development_directories', false ) ) {
60
+ if ( tc_is_other_file_in_dev_directory( $filename ) ) {
61
+ continue;
62
+ }
63
+ }
64
+ $other[ $filename ] = file_get_contents( $filename );
65
+ }
66
+ }
67
+
68
+ // Run the checks.
69
+ return run_themechecks(
70
+ $php,
71
+ $css,
72
+ $other,
73
+ array(
74
+ 'theme' => $theme,
75
+ 'slug' => $theme_slug,
76
+ )
77
+ );
78
+ }
79
+
80
+ /**
81
+ * Run the Theme Checks against a set of files.
82
+ *
83
+ * @param array $php The PHP files.
84
+ * @param array $css The CSS files.
85
+ * @param array $other Any non-php/css files.
86
+ * @param array $context Any context for the Theme Checks.
87
+ *
88
+ * @return bool
89
+ */
90
+ function run_themechecks( $php, $css, $other, $context = array() ) {
91
  global $themechecks;
92
+
93
  $pass = true;
94
+
95
+ tc_adapt_checks_for_fse_themes( $php, $css, $other );
96
+
97
  foreach ( $themechecks as $check ) {
98
  if ( $check instanceof themecheck ) {
99
+ if ( $context && is_callable( array( $check, 'set_context' ) ) ) {
100
+ $check->set_context( $context );
101
+ }
102
+
103
  $pass = $pass & $check->check( $php, $css, $other );
104
  }
105
  }
106
+
107
  return $pass;
108
  }
109
 
164
  $error = str_replace( '"', "'", $error );
165
  $this_line = str_replace( '"', "'", $this_line );
166
  $error = ltrim( $error );
167
+ $pos = strpos( $this_line, $error );
168
  $pre = ( false !== $pos ? substr( $this_line, 0, $pos ) : false );
169
  $pre = ltrim( htmlspecialchars( $pre ) );
170
  $bad_lines .= "<pre class='tc-grep'>" . __( 'Line ', 'theme-check' ) . ( $line_index + 1 ) . ': ' . $pre . htmlspecialchars( substr( stristr( $this_line, $error ), 0, 75 ) ) . '</pre>';
220
  return $e;
221
  }
222
 
223
+ // Strip comments from a PHP file in a way that will not change the underlying structure of the file.
224
+ function tc_strip_comments( $code ) {
225
+ $strip = array(
226
+ T_COMMENT => true,
227
+ T_DOC_COMMENT => true,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  );
229
+ $newlines = array(
230
+ "\n" => true,
231
+ "\r" => true,
232
+ );
233
+ $tokens = token_get_all( $code );
234
+ reset( $tokens );
235
+ $return = '';
236
+ $token = current( $tokens );
237
+ while ( $token ) {
238
+ if ( ! is_array( $token ) ) {
239
+ $return .= $token;
240
+ } elseif ( ! isset( $strip[ $token[0] ] ) ) {
241
+ $return .= $token[1];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
  } else {
243
+ for ( $i = 0, $token_length = strlen( $token[1] ); $i < $token_length; ++$i ) {
244
+ if ( isset( $newlines[ $token[1][ $i ] ] ) ) {
245
+ $return .= $token[1][ $i ];
246
+ }
247
+ }
248
  }
249
+ $token = next( $tokens );
 
250
  }
251
+ return $return;
252
+ }
253
 
254
+ /**
255
+ * Used to allow some directories to be skipped during development.
256
+ *
257
+ * @param string $filename a filename/path.
258
+ * @return boolean
259
+ */
260
+ function tc_is_other_file_in_dev_directory( $filename ) {
261
+ $skip = false;
262
+ // Filterable List of dirs that you may want to skip other files in during
263
+ // development.
264
+ $dev_dirs = apply_filters(
265
+ 'tc_common_dev_directories',
266
+ array(
267
+ 'node_modules',
268
+ 'vendor',
269
+ )
270
  );
271
+ foreach ( $dev_dirs as $dev_dir ) {
272
+ if ( strpos( $filename, $dev_dir ) ) {
273
+ $skip = true;
274
+ break;
275
+ }
276
+ }
277
+ return $skip;
278
  }
279
 
280
+ /**
281
+ * Adapt the Theme Checks if the theme is an experiment Full-Site Editing theme.
282
  *
283
+ * @param array $php_files The theme's PHP files.
284
+ * @param array $css_files The theme's CSS files.
285
+ * @param array $other_files Any other theme files.
286
+ *
287
+ * @return bool Whether the theme checks were adapted for FSE or not.
288
  */
289
+ function tc_adapt_checks_for_fse_themes( $php_files, $css_files, $other_files ) {
290
+ global $themechecks;
291
 
292
+ // Get a list of all non PHP and CSS file paths, relative to the theme root.
293
+ $other_filenames = array();
294
+ foreach ( $other_files as $path => $contents ) {
295
+ $other_filenames[] = tc_filename( $path );
296
  }
297
 
298
+ // Check whether this is a FSE theme by searching for an index.html block template.
299
+ if ( ! in_array( 'block-templates/index.html', $other_filenames, true ) ) {
300
+ return false;
301
  }
302
 
303
+ // Remove theme checks that do not apply to FSE themes.
304
+ foreach ( $themechecks as $key => $check ) {
305
+ if ( $check instanceof Tag_Check
306
+ || $check instanceof Suggested_Styles_Check
307
+ || $check instanceof Widgets_Check
308
+ || $check instanceof Gravatar_Check
309
+ || $check instanceof Post_Pagination_Check
310
+ || $check instanceof Basic_Check
311
+ || $check instanceof Comments_Check
312
+ || $check instanceof Comment_Pagination_Check
313
+ || $check instanceof Comment_Reply_Check
314
+ || $check instanceof Nav_Menu_Check
315
+ || $check instanceof Post_Thumbnail_Check
316
+ || $check instanceof Theme_Support_Check
317
+ || $check instanceof Editor_Style_Check
318
+ || $check instanceof Underscores_Check
319
+ || $check instanceof Constants_Check
320
+ || $check instanceof Customizer_Check
321
+ || $check instanceof Post_Format_Check
322
+ || $check instanceof Search_Form_Check
323
+ || $check instanceof Theme_Support_Title_Tag_Check
324
+ || $check instanceof Screen_Reader_Text_Check
325
+ || $check instanceof Include_Check
326
+ ) {
327
+ unset( $themechecks[ $key ] );
328
  }
329
  }
330
 
331
+ // Add FSE specific checks.
332
+ $themechecks[] = new FSE_Required_Files_Check();
 
 
333
 
334
+ return true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
335
  }
checks/admin_menu.php DELETED
@@ -1,73 +0,0 @@
1
- <?php
2
- class AdminMenu implements themecheck {
3
- protected $error = array();
4
-
5
- function check( $php_files, $css_files, $other_files) {
6
-
7
- $ret = true;
8
-
9
-
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 ) {
18
- foreach ( $checks as $key => $check ) {
19
- checkcount();
20
- if ( preg_match( $key, $phpfile, $matches ) ) {
21
- $filename = tc_filename( $php_key );
22
- $grep = ( isset( $matches[2] ) ) ? tc_grep( $matches[2], $php_key ) : tc_grep( $matches[1], $php_key );
23
- $this->error[] = sprintf('<span class="tc-lead tc-warning">'.__( 'WARNING', 'theme-check' ) . '</span>: <strong>%1$s</strong>. %2$s%3$s', $filename, $check, $grep );
24
- $ret = false;
25
- }
26
- }
27
- }
28
-
29
-
30
- // check for add_admin_page's, except for add_theme_page
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
-
42
- foreach ( $php_files as $php_key => $phpfile ) {
43
- foreach ( $checks as $key => $check ) {
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
- }
64
- }
65
- }
66
-
67
- return $ret;
68
- }
69
-
70
- function getError() { return $this->error; }
71
- }
72
-
73
- $themechecks[] = new AdminMenu;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/adminbar.php DELETED
@@ -1,55 +0,0 @@
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 DELETED
@@ -1,60 +0,0 @@
1
- <?php
2
- class Bad_Checks implements themecheck {
3
- protected $error = array();
4
-
5
- function check( $php_files, $css_files, $other_files ) {
6
- $ret = true;
7
-
8
- $checks = array(
9
- '/(?<![_|a-z0-9|\.])eval\s?\(/i' => __( 'eval() is not allowed.', 'theme-check' ),
10
- '/[^a-z0-9](?<!_)(popen|proc_open|[^_]exec|shell_exec|system|passthru)\(/' => __( 'PHP system calls are often disabled by server admins and should not be in themes', 'theme-check' ),
11
- '/\s?ini_set\(/' => __( 'Themes should not change server PHP settings', 'theme-check' ),
12
- '/base64_decode/' => __( 'base64_decode() is not allowed', 'theme-check' ),
13
- '/base64_encode/' => __( 'base64_encode() is not allowed', 'theme-check' ),
14
- '/uudecode/ims' => __( 'uudecode() is not allowed', 'theme-check' ),
15
- '/str_rot13/ims' => __( 'str_rot13() is not allowed', 'theme-check' ),
16
- '/cx=[0-9]{21}:[a-z0-9]{10}/' => __( 'Google search code detected', 'theme-check' ),
17
- '/pub-[0-9]{16}/i' => __( 'Google advertising code detected', 'theme-check' ),
18
- '/sharesale/i' => __( 'Sharesale affiliate link detected', 'theme-check' ),
19
- '/affiliate_id/i' => __( 'Potential affiliate link detected', 'theme-check' ),
20
- '/(elementor_partner_id)|(wpbeaverbuilder.*?fla)/i' => __( 'Potential affiliate link detected', 'theme-check' ),
21
- );
22
-
23
- $grep = '';
24
-
25
- foreach ( $php_files as $php_key => $phpfile ) {
26
- foreach ( $checks as $key => $check ) {
27
- checkcount();
28
- if ( preg_match( $key, $phpfile, $matches ) ) {
29
- $filename = tc_filename( $php_key );
30
- $error = ltrim( trim( $matches[0], '(' ) );
31
- $grep = tc_grep( $error, $php_key );
32
- $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 );
33
- $ret = false;
34
- }
35
- }
36
- }
37
-
38
-
39
- $checks = array(
40
- '/cx=[0-9]{21}:[a-z0-9]{10}/' => __( 'Google search code detected', 'theme-check' ),
41
- '/pub-[0-9]{16}/' => __( 'Google advertising code detected', 'theme-check' )
42
- );
43
-
44
- foreach ( $other_files as $php_key => $phpfile ) {
45
- foreach ( $checks as $key => $check ) {
46
- checkcount();
47
- if ( preg_match( $key, $phpfile, $matches ) ) {
48
- $filename = tc_filename( $php_key );
49
- $error = ltrim( rtrim( $matches[0],'(' ) );
50
- $grep = tc_grep( $error, $php_key );
51
- $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);
52
- $ret = false;
53
- }
54
- }
55
- }
56
- return $ret;
57
- }
58
- function getError() { return $this->error; }
59
- }
60
- $themechecks[] = new Bad_Checks;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/basic.php DELETED
@@ -1,47 +0,0 @@
1
- <?php
2
-
3
- // do some basic checks for strings
4
- class Basic_Checks implements themecheck {
5
- protected $error = array();
6
-
7
- function check( $php_files, $css_files, $other_files) {
8
-
9
- $php = implode( ' ', $php_files );
10
- $grep = '';
11
- $ret = true;
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>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"<br />"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"?&gt;</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> &lt;?php wp_body_open(); ?&gt;</pre>', 'theme-check' ),
16
- 'wp_footer\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/wp_footer/">wp_footer</a><pre> &lt;?php wp_footer(); ?&gt;</pre>', 'theme-check' ),
17
- 'wp_head\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/wp_head/">wp_head</a><pre> &lt;?php wp_head(); ?&gt;</pre>', 'theme-check' ),
18
- 'language_attributes' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/language_attributes/">language_attributes</a><pre>&lt;html &lt;?php language_attributes(); ?&gt;</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> &lt;?php add_theme_support( $feature ); ?&gt;</pre>', 'theme-check' ),
21
- 'comments_template\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/comments_template/">comments_template</a><pre> &lt;?php comments_template( $file, $separate_comments ); ?&gt;</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> &lt;?php wp_list_comments( $args ); ?&gt;</pre>', 'theme-check' ),
23
- 'comment_form\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/comment_form/">comment_form</a><pre> &lt;?php comment_form(); ?&gt;</pre>', 'theme-check' ),
24
- 'body_class\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/body_class/">body_class</a><pre> &lt;?php body_class( $class ); ?&gt;</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> &lt;?php wp_link_pages( $args ); ?&gt;</pre>', 'theme-check' ),
26
- 'post_class\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/post_class/">post_class</a><pre> &lt;div id="post-&lt;?php the_ID(); ?&gt;" &lt;?php post_class(); ?&gt;&gt;</pre>', 'theme-check' )
27
- );
28
-
29
- foreach ($checks as $key => $check) {
30
- checkcount();
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;
38
- }
39
- }
40
-
41
- return $ret;
42
- }
43
-
44
- function getError() { return $this->error; }
45
- }
46
-
47
- $themechecks[] = new Basic_Checks;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/cdn.php DELETED
@@ -1,45 +0,0 @@
1
- <?php
2
- /**
3
- * Checks for resources being loaded from CDNs.
4
- */
5
-
6
- class CDNCheck implements themecheck {
7
- protected $error = array();
8
-
9
- function check( $php_files, $css_files, $other_files) {
10
-
11
- $ret = true;
12
- $php_code = implode( ' ', $php_files );
13
- $css_code = implode( ' ', $css_files );
14
- $all_code = $php_code . ' ' . $css_code;
15
-
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
-
40
- return $ret;
41
- }
42
-
43
- function getError() { return $this->error; }
44
- }
45
- $themechecks[] = new CDNCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/class-admin-menu-check.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check for creation of admin menus
4
+ *
5
+ * Checks that user levels are not used when creating admin menus.
6
+ * Checks that only add_theme_page, add_menu_page and add_submenu_page are used to create admin menus.
7
+ *
8
+ * @package Theme Check
9
+ */
10
+
11
+ /**
12
+ * Check for creation of admin menus.
13
+ *
14
+ * Checks that user levels are not used when creating admin menus.
15
+ * Checks that only add_theme_page, add_menu_page and add_submenu_page are used to create admin menus.
16
+ */
17
+ class Admin_Menu_Check implements themecheck {
18
+ /**
19
+ * Error messages, warnings and info notices.
20
+ *
21
+ * @var array $error
22
+ */
23
+ protected $error = array();
24
+
25
+ /**
26
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
27
+ *
28
+ * @param array $php_files File paths and content for PHP files.
29
+ * @param array $css_files File paths and content for CSS files.
30
+ * @param array $other_files Folder names, file paths and content for other files.
31
+ */
32
+ public function check( $php_files, $css_files, $other_files ) {
33
+
34
+ $ret = true;
35
+
36
+ // Check for levels deprecated in 2.0 in creating menus.
37
+ $checks = array(
38
+ '/([^_](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' ),
39
+ '/[^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' ),
40
+ );
41
+
42
+ foreach ( $php_files as $php_key => $phpfile ) {
43
+ foreach ( $checks as $key => $check ) {
44
+ checkcount();
45
+ if ( preg_match( $key, $phpfile, $matches ) ) {
46
+ $filename = tc_filename( $php_key );
47
+ $grep = tc_grep( isset( $matches[2] ) ? $matches[2] : $matches[1], $php_key );
48
+ $this->error[] = sprintf(
49
+ '<span class="tc-lead tc-warning">%s</span>: <strong>%s</strong>. %s %s',
50
+ __( 'WARNING', 'theme-check' ),
51
+ $filename,
52
+ $check,
53
+ $grep
54
+ );
55
+ }
56
+ }
57
+ }
58
+
59
+ // Check for add_admin_page's, except for add_theme_page.
60
+ // Note to TGMPA: Stop trying to bypass theme check.
61
+ $checks = array(
62
+ '/(?<!function)[^_>:](add_[a-z]+_page)/' => _x(
63
+ 'Themes should not use <strong>%s()</strong>.',
64
+ 'function name',
65
+ 'theme-check'
66
+ ),
67
+ );
68
+
69
+ foreach ( $php_files as $php_key => $phpfile ) {
70
+ foreach ( $checks as $key => $check ) {
71
+ checkcount();
72
+ if ( preg_match_all( $key, $phpfile, $matches ) ) {
73
+ foreach ( $matches[1] as $match ) {
74
+ if ( in_array( $match, array( 'add_theme_page', 'add_menu_page', 'add_submenu_page' ), true ) ) {
75
+ continue;
76
+ }
77
+ $filename = tc_filename( $php_key );
78
+ $error = ltrim( rtrim( $match, '(' ) );
79
+ $grep = tc_grep( $error, $php_key );
80
+ $notallowed = sprintf( $check, $match );
81
+
82
+ $this->error[] = sprintf(
83
+ '<span class="tc-lead tc-recommended">%s</span>: <strong>%s</strong>. %s %s',
84
+ __( 'RECOMMENDED', 'theme-check' ),
85
+ $filename,
86
+ $notallowed,
87
+ $grep
88
+ );
89
+ }
90
+ }
91
+ }
92
+ }
93
+
94
+ return true;
95
+ }
96
+
97
+ /**
98
+ * Get error messages from the checks.
99
+ *
100
+ * @return array Error message.
101
+ */
102
+ public function getError() {
103
+ return $this->error;
104
+ }
105
+ }
106
+
107
+ $themechecks[] = new Admin_Menu_Check();
checks/class-bad-things-check.php ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check for code that is not allowed
4
+ *
5
+ * Checks for code that is not allowed, server settings, and affiliate links.
6
+ *
7
+ * @package Theme Check
8
+ */
9
+
10
+ /**
11
+ * Check for code that is not allowed.
12
+ *
13
+ * Checks for code that is not allowed, server settings, and affiliate links.
14
+ */
15
+ class Bad_Things_Check implements themecheck {
16
+ /**
17
+ * Error messages, warnings and info notices.
18
+ *
19
+ * @var array $error
20
+ */
21
+ protected $error = array();
22
+
23
+ /**
24
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
25
+ *
26
+ * @param array $php_files File paths and content for PHP files.
27
+ * @param array $css_files File paths and content for CSS files.
28
+ * @param array $other_files Folder names, file paths and content for other files.
29
+ */
30
+ public function check( $php_files, $css_files, $other_files ) {
31
+ $ret = true;
32
+
33
+ $checks = array(
34
+ '/(?<![_|a-z0-9|\.])eval\s?\(/i' => __( 'eval() is not allowed.', 'theme-check' ),
35
+ '/[^a-z0-9](?<!_)(popen|proc_open|[^_]exec|shell_exec|system|passthru)\(/' => __( 'PHP system calls are often disabled by server admins and should not be in themes', 'theme-check' ),
36
+ '/\s?ini_set\(/' => __( 'Themes should not change server PHP settings', 'theme-check' ),
37
+ '/base64_decode/' => __( 'base64_decode() is not allowed', 'theme-check' ),
38
+ '/base64_encode/' => __( 'base64_encode() is not allowed', 'theme-check' ),
39
+ '/uudecode/ims' => __( 'uudecode() is not allowed', 'theme-check' ),
40
+ '/str_rot13/ims' => __( 'str_rot13() is not allowed', 'theme-check' ),
41
+ '/cx=[0-9]{21}:[a-z0-9]{10}/' => __( 'Google search code detected', 'theme-check' ),
42
+ '/pub-[0-9]{16}/i' => __( 'Google advertising code detected', 'theme-check' ),
43
+ '/sharesale/i' => __( 'Sharesale affiliate link detected', 'theme-check' ),
44
+ '/affiliate_id/i' => __( 'Potential affiliate link detected', 'theme-check' ),
45
+ '/(elementor_partner_id)|(wpbeaverbuilder.*?fla)/i' => __( 'Potential affiliate link detected', 'theme-check' ),
46
+ );
47
+
48
+ $grep = '';
49
+
50
+ foreach ( $php_files as $php_key => $phpfile ) {
51
+ foreach ( $checks as $key => $check ) {
52
+ checkcount();
53
+ if ( preg_match( $key, $phpfile, $matches ) ) {
54
+ $filename = tc_filename( $php_key );
55
+ $error = ltrim( trim( $matches[0], '(' ) );
56
+ $grep = tc_grep( $error, $php_key );
57
+ $this->error[] = sprintf(
58
+ '<span class="tc-lead tc-required">%s</span>: %s %s %s',
59
+ __( 'REQUIRED', 'theme-check' ),
60
+ sprintf(
61
+ __( 'Found %1$s in the file %2$s.', 'theme-check' ),
62
+ '<strong>' . $error . '</strong>',
63
+ '<strong>' . $filename . '</strong>'
64
+ ),
65
+ $check,
66
+ $grep
67
+ );
68
+ $ret = false;
69
+ }
70
+ }
71
+ }
72
+
73
+ $checks = array(
74
+ '/cx=[0-9]{21}:[a-z0-9]{10}/' => __( 'Google search code detected', 'theme-check' ),
75
+ '/pub-[0-9]{16}/i' => __( 'Google advertising code detected', 'theme-check' ),
76
+ );
77
+
78
+ foreach ( $other_files as $php_key => $phpfile ) {
79
+ foreach ( $checks as $key => $check ) {
80
+ checkcount();
81
+ if ( preg_match( $key, $phpfile, $matches ) ) {
82
+ $filename = tc_filename( $php_key );
83
+ $error = ltrim( rtrim( $matches[0], '(' ) );
84
+ $grep = tc_grep( $error, $php_key );
85
+ $this->error[] = sprintf(
86
+ '<span class="tc-lead tc-required">%s</span>: %s %s %s',
87
+ __( 'REQUIRED', 'theme-check' ),
88
+ sprintf(
89
+ __( 'Found <strong>%1$s</strong> in the file <strong>%2$s</strong>.', 'theme-check' ),
90
+ $error,
91
+ $filename
92
+ ),
93
+ $check,
94
+ $grep
95
+ );
96
+ $ret = false;
97
+ }
98
+ }
99
+ }
100
+
101
+ return $ret;
102
+ }
103
+
104
+ /**
105
+ * Get error messages from the checks.
106
+ *
107
+ * @return array Error message.
108
+ */
109
+ public function getError() {
110
+ return $this->error;
111
+ }
112
+ }
113
+
114
+ $themechecks[] = new Bad_Things_Check();
checks/class-basic-check.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check for basic functions needed for classic themes to work correctly
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check for basic functions needed for classic themes to work correctly.
10
+ */
11
+ class Basic_Check 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
+ $php = implode( ' ', $php_files );
29
+ $grep = '';
30
+ $ret = true;
31
+
32
+ $checks = array(
33
+ 'DOCTYPE' => __( 'See: <a href="https://codex.wordpress.org/HTML_to_XHTML">https://codex.wordpress.org/HTML_to_XHTML</a><pre>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"<br />"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"?&gt;</pre>', 'theme-check' ),
34
+ '(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> &lt;?php wp_body_open(); ?&gt;</pre>', 'theme-check' ),
35
+ 'wp_footer\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/wp_footer/">wp_footer</a><pre> &lt;?php wp_footer(); ?&gt;</pre>', 'theme-check' ),
36
+ 'wp_head\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/wp_head/">wp_head</a><pre> &lt;?php wp_head(); ?&gt;</pre>', 'theme-check' ),
37
+ 'language_attributes' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/language_attributes/">language_attributes</a><pre>&lt;html &lt;?php language_attributes(); ?&gt;</pre>', 'theme-check' ),
38
+ 'charset' => __( 'There must be a charset defined in the Content-Type or the meta charset tag in the head.', 'theme-check' ),
39
+ '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> &lt;?php add_theme_support( $feature ); ?&gt;</pre>', 'theme-check' ),
40
+ 'body_class\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/body_class/">body_class</a><pre> &lt;?php body_class( $class ); ?&gt;</pre>', 'theme-check' ),
41
+ 'wp_link_pages\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/wp_link_pages/">wp_link_pages</a><pre> &lt;?php wp_link_pages( $args ); ?&gt;</pre>', 'theme-check' ),
42
+ 'post_class\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/post_class/">post_class</a><pre> &lt;div id="post-&lt;?php the_ID(); ?&gt;" &lt;?php post_class(); ?&gt;&gt;</pre>', 'theme-check' ),
43
+ );
44
+
45
+ foreach ( $checks as $key => $check ) {
46
+ checkcount();
47
+ if ( ! preg_match( '/' . $key . '/i', $php ) ) {
48
+ if ( $key === 'add_theme_support\s*\(\s?("|\')automatic-feed-links("|\')\s?\)' ) {
49
+ $key = __( 'add_theme_support( \'automatic-feed-links\' )', 'theme-check' );
50
+ }
51
+ if ( $key === 'body_class\s*\(' ) {
52
+ $key = __( 'body_class call in body tag', 'theme-check' );
53
+ }
54
+ if ( $key === '(wp_body_open\s*\()|(do_action\s*\(\s*["\']wp_body_open)' ) {
55
+ $key = __( 'wp_body_open action or function call at the very top of the body just after the opening body tag', 'theme-check' );
56
+ }
57
+ $key = str_replace( '\s*\(', '', $key );
58
+ $this->error[] = sprintf(
59
+ '<span class="tc-lead tc-required">%s</span>: %s',
60
+ __( 'REQUIRED', 'theme-check' ),
61
+ sprintf(
62
+ __( 'Could not find %1$s. %2$s', 'theme-check' ),
63
+ '<strong>' . $key . '</strong>',
64
+ $check
65
+ )
66
+ );
67
+ $ret = false;
68
+ }
69
+ }
70
+
71
+ return $ret;
72
+ }
73
+
74
+ /**
75
+ * Get error messages from the checks.
76
+ *
77
+ * @return array Error message.
78
+ */
79
+ public function getError() {
80
+ return $this->error;
81
+ }
82
+ }
83
+
84
+ $themechecks[] = new Basic_Check();
checks/class-block-patterns-check.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check if block patterns and block styles are included
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check if block patterns and block styles are included.
10
+ *
11
+ * Check if block patterns and block styles are included, if not, recommend it.
12
+ */
13
+ class Block_Patterns_Check implements themecheck {
14
+ /**
15
+ * Error messages, warnings and info notices.
16
+ *
17
+ * @var array $error
18
+ */
19
+ protected $error = array();
20
+
21
+ /**
22
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
23
+ *
24
+ * @param array $php_files File paths and content for PHP files.
25
+ * @param array $css_files File paths and content for CSS files.
26
+ * @param array $other_files Folder names, file paths and content for other files.
27
+ */
28
+ public function check( $php_files, $css_files, $other_files ) {
29
+ checkcount();
30
+
31
+ $php = implode( ' ', $php_files );
32
+
33
+ if ( strpos( $php, 'register_block_pattern' ) === false ) {
34
+ $this->error[] = sprintf(
35
+ '<span class="tc-lead tc-recommended">%s</span>: %s',
36
+ __( 'RECOMMENDED', 'theme-check' ),
37
+ __( 'No reference to <strong>register_block_pattern</strong> was found in the theme. Theme authors are encouraged to implement custom block patterns as a transition to block themes.', 'theme-check' )
38
+ );
39
+ }
40
+
41
+ if ( strpos( $php, 'register_block_style' ) === false ) {
42
+ $this->error[] = sprintf(
43
+ '<span class="tc-lead tc-recommended">%s</span>: %s',
44
+ __( 'RECOMMENDED', 'theme-check' ),
45
+ __( 'No reference to <strong>register_block_style</strong> was found in the theme. Theme authors are encouraged to implement new block styles as a transition to block themes.', 'theme-check' )
46
+ );
47
+ }
48
+
49
+ return true;
50
+ }
51
+
52
+ /**
53
+ * Get error messages from the checks.
54
+ *
55
+ * @return array Error message.
56
+ */
57
+ public function getError() {
58
+ return $this->error;
59
+ }
60
+ }
61
+
62
+ $themechecks[] = new Block_Patterns_Check();
checks/class-cdn-check.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Checks for resources being loaded from CDNs.
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Checks for resources being loaded from CDNs.
10
+ *
11
+ * Checks for resources being loaded from CDNs. Usage of CDN is required to be removed.
12
+ */
13
+ class CDN_Check implements themecheck {
14
+ /**
15
+ * Error messages, warnings and info notices.
16
+ *
17
+ * @var array $error
18
+ */
19
+ protected $error = array();
20
+
21
+ /**
22
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
23
+ *
24
+ * @param array $php_files File paths and content for PHP files.
25
+ * @param array $css_files File paths and content for CSS files.
26
+ * @param array $other_files Folder names, file paths and content for other files.
27
+ */
28
+ public function check( $php_files, $css_files, $other_files ) {
29
+
30
+ $ret = true;
31
+ $php_code = implode( ' ', $php_files );
32
+ $css_code = implode( ' ', $css_files );
33
+ $all_code = $php_code . ' ' . $css_code;
34
+
35
+ checkcount();
36
+
37
+ $cdn_list = array(
38
+ 'bootstrap-maxcdn' => 'maxcdn.bootstrapcdn.com',
39
+ 'bootstrap-netdna' => 'netdna.bootstrapcdn.com',
40
+ 'bootstrap-stackpath' => 'stackpath.bootstrapcdn.com',
41
+ 'fontawesome' => 'kit.fontawesome.com',
42
+ 'googlecode' => 'googlecode.com/svn/',
43
+ 'oss.maxcdn' => 'oss.maxcdn.com',
44
+ 'jquery' => 'code.jquery.com/jquery-',
45
+ 'aspnetcdn' => 'aspnetcdn.com',
46
+ 'cloudflare' => 'cloudflare.com',
47
+ 'keycdn' => 'keycdn.com',
48
+ 'pxgcdn' => 'pxgcdn.com',
49
+ 'vimeocdn' => 'vimeocdn.com', // Usually in JS files.
50
+ );
51
+
52
+ foreach ( $cdn_list as $cdn_slug => $cdn_url ) {
53
+ if ( false !== strpos( $all_code, $cdn_url ) ) {
54
+ $this->error[] = sprintf(
55
+ '<span class="tc-lead tc-required">%s</span>: %s',
56
+ __( 'REQUIRED', 'theme-check' ),
57
+ sprintf(
58
+ __( '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' ),
59
+ '<code>' . esc_html( $cdn_url ) . '</code>'
60
+ )
61
+ );
62
+ $ret = false;
63
+ }
64
+ }
65
+
66
+ return $ret;
67
+ }
68
+
69
+ /**
70
+ * Get error messages from the checks.
71
+ *
72
+ * @return array Error message.
73
+ */
74
+ public function getError() {
75
+ return $this->error;
76
+ }
77
+ }
78
+
79
+ $themechecks[] = new CDN_Check();
checks/class-comment-pagination-check.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Checks if comment pagination is included
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Checks if comment pagination is included.
10
+ *
11
+ * Checks if comment pagination is included. If not, recommend it.
12
+ */
13
+ class Comment_Pagination_Check implements themecheck {
14
+ /**
15
+ * Error messages, warnings and info notices.
16
+ *
17
+ * @var array $error
18
+ */
19
+ protected $error = array();
20
+
21
+ /**
22
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
23
+ *
24
+ * @param array $php_files File paths and content for PHP files.
25
+ * @param array $css_files File paths and content for CSS files.
26
+ * @param array $other_files Folder names, file paths and content for other files.
27
+ */
28
+ public function check( $php_files, $css_files, $other_files ) {
29
+
30
+ // Combine all the php files into one string to make it easier to search.
31
+ $php = implode( ' ', $php_files );
32
+
33
+ checkcount();
34
+
35
+ if (
36
+ strpos( $php, 'paginate_comments_links' ) === false &&
37
+ strpos( $php, 'the_comments_navigation' ) === false &&
38
+ strpos( $php, 'the_comments_pagination' ) === false &&
39
+ strpos( $php, 'next_comments_link' ) === false &&
40
+ strpos( $php, 'previous_comments_link' ) === false
41
+ ) {
42
+ $this->error[] = sprintf(
43
+ '<span class="tc-lead tc-recommended">%s</span>: %s',
44
+ __( 'RECOMMENDED', 'theme-check' ),
45
+ __( "The theme doesn't have comment pagination code in it. Use <strong>paginate_comments_links()</strong> or <strong>the_comments_navigation</strong> or <strong>the_comments_pagination</strong> or <strong>next_comments_link()</strong> and <strong>previous_comments_link()</strong> to add comment pagination.", 'theme-check' )
46
+ );
47
+ }
48
+
49
+ return true;
50
+ }
51
+
52
+ /**
53
+ * Get error messages from the checks.
54
+ *
55
+ * @return array Error message.
56
+ */
57
+ public function getError() {
58
+ return $this->error;
59
+ }
60
+ }
61
+
62
+ $themechecks[] = new Comment_Pagination_Check();
checks/class-comment-reply-check.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Checks if the comment reply script is included in classic themes
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Checks if the comment reply script is included in classic themes.
10
+ *
11
+ * Checks if the comment reply script is included. If not, recommend it.
12
+ */
13
+ class Comment_Reply_Check implements themecheck {
14
+ /**
15
+ * Error messages, warnings and info notices.
16
+ *
17
+ * @var array $error
18
+ */
19
+ protected $error = array();
20
+
21
+ /**
22
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
23
+ *
24
+ * @param array $php_files File paths and content for PHP files.
25
+ * @param array $css_files File paths and content for CSS files.
26
+ * @param array $other_files Folder names, file paths and content for other files.
27
+ */
28
+ public function check( $php_files, $css_files, $other_files ) {
29
+
30
+ $php = implode( ' ', $php_files );
31
+
32
+ checkcount();
33
+
34
+ if ( ! preg_match( '/wp_enqueue_script\(\s?("|\')comment-reply("|\')/i', $php ) ) {
35
+ if ( ! preg_match( '/comment-reply/', $php ) ) {
36
+ $this->error[] = sprintf(
37
+ '<span class="tc-lead tc-recommended">%s</span>: %s',
38
+ __( 'RECOMMENDED', 'theme-check' ),
39
+ __( 'Could not find the <strong>comment-reply</strong> script enqueued.', 'theme-check' )
40
+ );
41
+ } else {
42
+ $this->error[] = sprintf(
43
+ '<span class="tc-lead tc-info">%s</span>: %s',
44
+ __( 'INFO', 'theme-check' ),
45
+ __( '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' )
46
+ );
47
+ }
48
+ }
49
+
50
+ return true;
51
+ }
52
+
53
+ /**
54
+ * Get error messages from the checks.
55
+ *
56
+ * @return array Error message.
57
+ */
58
+ public function getError() {
59
+ return $this->error;
60
+ }
61
+ }
62
+
63
+ $themechecks[] = new Comment_Reply_Check();
checks/class-comments-check.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Checks if comment templates are included in classic themes
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Checks if comment templates are included in classic themes.
10
+ *
11
+ * Checks if comment templates are included. If not, recommend them.
12
+ */
13
+ class Comments_Check implements themecheck {
14
+ /**
15
+ * Error messages, warnings and info notices.
16
+ *
17
+ * @var array $error
18
+ */
19
+ protected $error = array();
20
+
21
+ /**
22
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
23
+ *
24
+ * @param array $php_files File paths and content for PHP files.
25
+ * @param array $css_files File paths and content for CSS files.
26
+ * @param array $other_files Folder names, file paths and content for other files.
27
+ */
28
+ public function check( $php_files, $css_files, $other_files ) {
29
+
30
+ $php = implode( ' ', $php_files );
31
+
32
+ $checks = array(
33
+ 'comments_template\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/comments_template/">comments_template</a><pre> &lt;?php comments_template( $file, $separate_comments ); ?&gt;</pre>', 'theme-check' ),
34
+ 'wp_list_comments\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/wp_list_comments/">wp_list_comments</a><pre> &lt;?php wp_list_comments( $args ); ?&gt;</pre>', 'theme-check' ),
35
+ 'comment_form\s*\(' => __( 'See: <a href="https://developer.wordpress.org/reference/functions/comment_form/">comment_form</a><pre> &lt;?php comment_form(); ?&gt;</pre>', 'theme-check' ),
36
+ );
37
+
38
+ foreach ( $checks as $key => $check ) {
39
+ checkcount();
40
+ if ( ! preg_match( '/' . $key . '/i', $php ) ) {
41
+ $key = str_replace( '\s*\(', '', $key );
42
+ $this->error[] = sprintf(
43
+ '<span class="tc-lead tc-recommended">%s</span>: %s',
44
+ __( 'RECOMMENDED', 'theme-check' ),
45
+ sprintf(
46
+ __( 'Could not find %1$s. %2$s', 'theme-check' ),
47
+ '<strong>' . $key . '</strong>',
48
+ $check
49
+ )
50
+ );
51
+ }
52
+ }
53
+
54
+ return true;
55
+ }
56
+
57
+ /**
58
+ * Get error messages from the checks.
59
+ *
60
+ * @return array Error message.
61
+ */
62
+ public function getError() {
63
+ return $this->error;
64
+ }
65
+ }
66
+
67
+ $themechecks[] = new Comments_Check();
checks/class-constants-check.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Checks if deprecated constants are included
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Checks if deprecated constants are included.
10
+ *
11
+ * Checks if deprecated constants are included. If they are, require them to be removed.
12
+ *
13
+ * @see https://core.trac.wordpress.org/changeset/20212
14
+ */
15
+ class Constants_Check implements themecheck {
16
+ /**
17
+ * Error messages, warnings and info notices.
18
+ *
19
+ * @var array $error
20
+ */
21
+ protected $error = array();
22
+
23
+ /**
24
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
25
+ *
26
+ * @param array $php_files File paths and content for PHP files.
27
+ * @param array $css_files File paths and content for CSS files.
28
+ * @param array $other_files Folder names, file paths and content for other files.
29
+ */
30
+ public function check( $php_files, $css_files, $other_files ) {
31
+
32
+ $ret = true;
33
+
34
+ $checks = array(
35
+ 'STYLESHEETPATH' => 'get_stylesheet_directory()',
36
+ 'TEMPLATEPATH' => 'get_template_directory()',
37
+ 'PLUGINDIR' => 'WP_PLUGIN_DIR',
38
+ 'MUPLUGINDIR' => 'WPMU_PLUGIN_DIR',
39
+ 'HEADER_IMAGE' => 'add_theme_support( \'custom-header\' )',
40
+ 'NO_HEADER_TEXT' => 'add_theme_support( \'custom-header\' )',
41
+ 'HEADER_TEXTCOLOR' => 'add_theme_support( \'custom-header\' )',
42
+ 'HEADER_IMAGE_WIDTH' => 'add_theme_support( \'custom-header\' )',
43
+ 'HEADER_IMAGE_HEIGHT' => 'add_theme_support( \'custom-header\' )',
44
+ 'BACKGROUND_COLOR' => 'add_theme_support( \'custom-background\' )',
45
+ 'BACKGROUND_IMAGE' => 'add_theme_support( \'custom-background\' )',
46
+ );
47
+
48
+ foreach ( $php_files as $php_key => $phpfile ) {
49
+ foreach ( $checks as $key => $check ) {
50
+ checkcount();
51
+ if ( preg_match( '/[\s|\'|\"]' . $key . '(?:\'|"|;|\s)/', $phpfile, $matches ) ) {
52
+ $filename = tc_filename( $php_key );
53
+ $error = ltrim( rtrim( $matches[0], '(' ), '\'"' );
54
+ $grep = tc_grep( $error, $php_key );
55
+ $this->error[] = sprintf(
56
+ '<span class="tc-lead tc-required">%s</span>: %s %s',
57
+ __( 'REQUIRED', 'theme-check' ),
58
+ sprintf(
59
+ __( '%1$s was found in the file %2$s. Use %3$s instead.', 'theme-check' ),
60
+ '<strong>' . $error . '</strong>',
61
+ '<strong>' . $filename . '</strong>',
62
+ '<strong>' . $check . '</strong>'
63
+ ),
64
+ $grep
65
+ );
66
+ $ret = false;
67
+ }
68
+ }
69
+ }
70
+ return $ret;
71
+ }
72
+
73
+ /**
74
+ * Get error messages from the checks.
75
+ *
76
+ * @return array Error message.
77
+ */
78
+ public function getError() {
79
+ return $this->error;
80
+ }
81
+ }
82
+
83
+ $themechecks[] = new Constants_Check();
checks/class-customizer-check.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Checks if Customizer settings have sanitization callbacks
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check whether every Customizer setting has a sanitization callback set.
10
+ *
11
+ * Check whether every Customizer setting has a sanitization callback set and that it is not empty.
12
+ */
13
+ class Customizer_Check implements themecheck {
14
+ /**
15
+ * Error messages, warnings and info notices.
16
+ *
17
+ * @var array $error
18
+ */
19
+ protected $error = array();
20
+
21
+ /**
22
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
23
+ *
24
+ * @param array $php_files File paths and content for PHP files.
25
+ * @param array $css_files File paths and content for CSS files.
26
+ * @param array $other_files Folder names, file paths and content for other files.
27
+ */
28
+ public function check( $php_files, $css_files, $other_files ) {
29
+
30
+ $ret = true;
31
+
32
+ checkcount();
33
+
34
+ foreach ( $php_files as $file_path => $file_content ) {
35
+ // Get the arguments passed to the add_setting method.
36
+ if ( preg_match_all( '/\$wp_customize->add_setting\(([^;]+)/', $file_content, $matches ) ) {
37
+ // The full match is in [0], the match group in [1].
38
+ foreach ( $matches[1] as $match ) {
39
+ // Check if we have sanitize_callback or sanitize_js_callback.
40
+ if (
41
+ false === strpos( $match, 'sanitize_callback' ) &&
42
+ false === strpos( $match, 'sanitize_js_callback' )
43
+ ) {
44
+ /*
45
+ * Clean up our match to be able to present the results better.
46
+ *
47
+ * Note: The delimiter in the below regex using $match MUST be a special regex character per preg_quote().
48
+ */
49
+ $ret = false;
50
+ $match = preg_split( '/,/', $match );
51
+ $grep = tc_preg( '!' . preg_quote( $match[0], '!' ) . '!', $file_path );
52
+ $grep = preg_split( '/,/', $grep );
53
+ $this->error[] = sprintf(
54
+ '<span class="tc-lead tc-required">%s</span>: %s %s',
55
+ __( 'REQUIRED', 'theme-check' ),
56
+ sprintf(
57
+ __( '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' ),
58
+ '<strong>' . $match[0] . '</strong>',
59
+ '<strong>' . tc_filename( $file_path ) . '</strong>'
60
+ ),
61
+ $grep[0]
62
+ );
63
+ } else {
64
+ // There's a callback, check that no empty parameter is passed.
65
+ if ( preg_match( '/[\'"](?:sanitize_callback|sanitize_js_callback)[\'"]\s*=>\s*[\'"]\s*[\'"]/', $match ) ) {
66
+ $ret = false;
67
+ $match = preg_split( '/,/', $match );
68
+ $grep = tc_preg( '/[\'"](?:sanitize_callback|sanitize_js_callback)[\'"]\s*=>\s*[\'"]\s*[\'"]/', $file_path );
69
+ $grep = preg_split( '/,/', $grep );
70
+ $this->error[] = sprintf(
71
+ '<span class="tc-lead tc-required">%s</span>: %s %s',
72
+ __( 'REQUIRED', 'theme-check' ),
73
+ sprintf(
74
+ __( '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' ),
75
+ '<strong>' . $match[0] . '</strong>',
76
+ '<strong>' . tc_filename( $file_path ) . '</strong>'
77
+ ),
78
+ $grep[0]
79
+ );
80
+ }
81
+ }
82
+ }
83
+ }
84
+ }
85
+
86
+ return $ret;
87
+ }
88
+
89
+ /**
90
+ * Get error messages from the checks.
91
+ *
92
+ * @return array Error message.
93
+ */
94
+ public function getError() {
95
+ return $this->error;
96
+ }
97
+ }
98
+
99
+ $themechecks[] = new Customizer_Check();
checks/class-deprecated-check.php ADDED
@@ -0,0 +1,1201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Checks if deprecated functions are included
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Checks if deprecated functions are included
10
+ */
11
+ class Deprecated_Check 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
+ $grep = '';
29
+ $ret = true;
30
+
31
+ $checks = array(
32
+ // Start wp-includes deprecated.
33
+ array(
34
+ 'get_postdata' => 'get_post()',
35
+ '1.5.1',
36
+ ),
37
+ array(
38
+ 'start_wp' => 'the Loop',
39
+ '1.5',
40
+ ),
41
+ array(
42
+ 'the_category_id' => 'get_the_category()',
43
+ '0.71',
44
+ ),
45
+ array(
46
+ 'the_category_head' => 'get_the_category_by_ID()',
47
+ '0.71',
48
+ ),
49
+ array(
50
+ 'previous_post' => 'previous_post_link()',
51
+ '2.0',
52
+ ),
53
+ array(
54
+ 'next_post' => 'next_post_link()',
55
+ '2.0',
56
+ ),
57
+ array(
58
+ 'user_can_create_post' => 'current_user_can()',
59
+ '2.0',
60
+ ),
61
+ array(
62
+ 'user_can_create_draft' => 'current_user_can()',
63
+ '2.0',
64
+ ),
65
+ array(
66
+ 'user_can_edit_post' => 'current_user_can()',
67
+ '2.0',
68
+ ),
69
+ array(
70
+ 'user_can_delete_post' => 'current_user_can()',
71
+ '2.0',
72
+ ),
73
+ array(
74
+ 'user_can_set_post_date' => 'current_user_can()',
75
+ '2.0',
76
+ ),
77
+ array(
78
+ 'user_can_edit_post_comments' => 'current_user_can()',
79
+ '2.0',
80
+ ),
81
+ array(
82
+ 'user_can_delete_post_comments' => 'current_user_can()',
83
+ '2.0',
84
+ ),
85
+ array(
86
+ 'user_can_edit_user' => 'current_user_can()',
87
+ '2.0',
88
+ ),
89
+ array(
90
+ 'get_linksbyname' => 'get_bookmarks()',
91
+ '2.1',
92
+ ),
93
+ array(
94
+ 'wp_get_linksbyname' => 'wp_list_bookmarks()',
95
+ '2.1',
96
+ ),
97
+ array(
98
+ 'get_linkobjectsbyname' => 'get_bookmarks()',
99
+ '2.1',
100
+ ),
101
+ array(
102
+ 'get_linkobjects' => 'get_bookmarks()',
103
+ '2.1',
104
+ ),
105
+ array(
106
+ 'get_linksbyname_withrating' => 'get_bookmarks()',
107
+ '2.1',
108
+ ),
109
+ array(
110
+ 'get_links_withrating' => 'get_bookmarks()',
111
+ '2.1',
112
+ ),
113
+ array(
114
+ 'get_autotoggle' => '',
115
+ '2.1',
116
+ ),
117
+ array(
118
+ 'list_cats' => 'wp_list_categories',
119
+ '2.1',
120
+ ),
121
+ array(
122
+ 'wp_list_cats' => 'wp_list_categories',
123
+ '2.1',
124
+ ),
125
+ array(
126
+ 'dropdown_cats' => 'wp_dropdown_categories()',
127
+ '2.1',
128
+ ),
129
+ array(
130
+ 'list_authors' => 'wp_list_authors()',
131
+ '2.1',
132
+ ),
133
+ array(
134
+ 'wp_get_post_cats' => 'wp_get_post_categories()',
135
+ '2.1',
136
+ ),
137
+ array(
138
+ 'wp_set_post_cats' => 'wp_set_post_categories()',
139
+ '2.1',
140
+ ),
141
+ array(
142
+ 'get_archives' => 'wp_get_archives',
143
+ '2.1',
144
+ ),
145
+ array(
146
+ 'get_author_link' => 'get_author_posts_url()',
147
+ '2.1',
148
+ ),
149
+ array(
150
+ 'link_pages' => 'wp_link_pages()',
151
+ '2.1',
152
+ ),
153
+ array(
154
+ 'get_settings' => 'get_option()',
155
+ '2.1',
156
+ ),
157
+ array(
158
+ 'permalink_link' => 'the_permalink()',
159
+ '1.2',
160
+ ),
161
+ array(
162
+ 'permalink_single_rss' => 'permalink_rss()',
163
+ '2.3',
164
+ ),
165
+ array(
166
+ 'wp_get_links' => 'wp_list_bookmarks()',
167
+ '2.1',
168
+ ),
169
+ array(
170
+ 'get_links' => 'get_bookmarks()',
171
+ '2.1',
172
+ ),
173
+ array(
174
+ 'get_links_list' => 'wp_list_bookmarks()',
175
+ '2.1',
176
+ ),
177
+ array(
178
+ 'links_popup_script' => '',
179
+ '2.1',
180
+ ),
181
+ array(
182
+ 'get_linkrating' => 'sanitize_bookmark_field()',
183
+ '2.1',
184
+ ),
185
+ array(
186
+ 'get_linkcatname' => 'get_category()',
187
+ '2.1',
188
+ ),
189
+ array(
190
+ 'comments_rss_link' => 'post_comments_feed_link()',
191
+ '2.5',
192
+ ),
193
+ array(
194
+ 'get_category_rss_link' => 'get_category_feed_link()',
195
+ '2.5',
196
+ ),
197
+ array(
198
+ 'get_author_rss_link' => 'get_author_feed_link()',
199
+ '2.5',
200
+ ),
201
+ array(
202
+ 'comments_rss' => 'get_post_comments_feed_link()',
203
+ '2.2',
204
+ ),
205
+ array(
206
+ 'create_user' => 'wp_create_user()',
207
+ '2.0',
208
+ ),
209
+ array(
210
+ 'gzip_compression' => '',
211
+ '2.5',
212
+ ),
213
+ array(
214
+ 'get_commentdata' => 'get_comment()',
215
+ '2.7',
216
+ ),
217
+ array(
218
+ 'get_catname' => 'get_cat_name()',
219
+ '2.8',
220
+ ),
221
+ array(
222
+ 'get_category_children' => 'get_term_children',
223
+ '2.8',
224
+ ),
225
+ array(
226
+ 'get_the_author_description' => 'get_the_author_meta(\'description\')',
227
+ '2.8',
228
+ ),
229
+ array(
230
+ 'the_author_description' => 'the_author_meta(\'description\')',
231
+ '2.8',
232
+ ),
233
+ array(
234
+ 'get_the_author_login' => 'the_author_meta(\'login\')',
235
+ '2.8',
236
+ ),
237
+ array(
238
+ 'get_the_author_firstname' => 'get_the_author_meta(\'first_name\')',
239
+ '2.8',
240
+ ),
241
+ array(
242
+ 'the_author_firstname' => 'the_author_meta(\'first_name\')',
243
+ '2.8',
244
+ ),
245
+ array(
246
+ 'get_the_author_lastname' => 'get_the_author_meta(\'last_name\')',
247
+ '2.8',
248
+ ),
249
+ array(
250
+ 'the_author_lastname' => 'the_author_meta(\'last_name\')',
251
+ '2.8',
252
+ ),
253
+ array(
254
+ 'get_the_author_nickname' => 'get_the_author_meta(\'nickname\')',
255
+ '2.8',
256
+ ),
257
+ array(
258
+ 'the_author_nickname' => 'the_author_meta(\'nickname\')',
259
+ '2.8',
260
+ ),
261
+ array(
262
+ 'get_the_author_email' => 'get_the_author_meta(\'email\')',
263
+ '2.8',
264
+ ),
265
+ array(
266
+ 'the_author_email' => 'the_author_meta(\'email\')',
267
+ '2.8',
268
+ ),
269
+ array(
270
+ 'get_the_author_icq' => 'get_the_author_meta(\'icq\')',
271
+ '2.8',
272
+ ),
273
+ array(
274
+ 'the_author_icq' => 'the_author_meta(\'icq\')',
275
+ '2.8',
276
+ ),
277
+ array(
278
+ 'get_the_author_yim' => 'get_the_author_meta(\'yim\')',
279
+ '2.8',
280
+ ),
281
+ array(
282
+ 'the_author_yim' => 'the_author_meta(\'yim\')',
283
+ '2.8',
284
+ ),
285
+ array(
286
+ 'get_the_author_msn' => 'get_the_author_meta(\'msn\')',
287
+ '2.8',
288
+ ),
289
+ array(
290
+ 'the_author_msn' => 'the_author_meta(\'msn\')',
291
+ '2.8',
292
+ ),
293
+ array(
294
+ 'get_the_author_aim' => 'get_the_author_meta(\'aim\')',
295
+ '2.8',
296
+ ),
297
+ array(
298
+ 'the_author_aim' => 'the_author_meta(\'aim\')',
299
+ '2.8',
300
+ ),
301
+ array(
302
+ 'get_author_name' => 'get_the_author_meta(\'display_name\')',
303
+ '2.8',
304
+ ),
305
+ array(
306
+ 'get_the_author_url' => 'get_the_author_meta(\'url\')',
307
+ '2.8',
308
+ ),
309
+ array(
310
+ 'the_author_url' => 'the_author_meta(\'url\')',
311
+ '2.8',
312
+ ),
313
+ array(
314
+ 'get_the_author_ID' => 'get_the_author_meta(\'ID\')',
315
+ '2.8',
316
+ ),
317
+ array(
318
+ 'the_author_ID' => 'the_author_meta(\'ID\')',
319
+ '2.8',
320
+ ),
321
+ array(
322
+ 'the_content_rss' => 'the_content_feed()',
323
+ '2.9',
324
+ ),
325
+ array(
326
+ 'make_url_footnote' => '',
327
+ '2.9',
328
+ ),
329
+ array(
330
+ '_c' => '_x()',
331
+ '2.9',
332
+ ),
333
+ array(
334
+ 'translate_with_context' => '_x()',
335
+ '3.0',
336
+ ),
337
+ array(
338
+ 'nc' => 'nx()',
339
+ '3.0',
340
+ ),
341
+ array(
342
+ '__ngettext' => '_n_noop()',
343
+ '2.8',
344
+ ),
345
+ array(
346
+ '__ngettext_noop' => '_n_noop()',
347
+ '2.8',
348
+ ),
349
+ array(
350
+ 'get_alloptions' => 'wp_load_alloptions()',
351
+ '3.0',
352
+ ),
353
+ array(
354
+ 'get_the_attachment_link' => 'wp_get_attachment_link()',
355
+ '2.5',
356
+ ),
357
+ array(
358
+ 'get_attachment_icon_src' => 'wp_get_attachment_image_src()',
359
+ '2.5',
360
+ ),
361
+ array(
362
+ 'get_attachment_icon' => 'wp_get_attachment_image()',
363
+ '2.5',
364
+ ),
365
+ array(
366
+ 'get_attachment_innerhtml' => 'wp_get_attachment_image()',
367
+ '2.5',
368
+ ),
369
+ array(
370
+ 'get_link' => 'get_bookmark()',
371
+ '2.1',
372
+ ),
373
+ array(
374
+ 'sanitize_url' => 'esc_url()',
375
+ '2.8',
376
+ ),
377
+ array(
378
+ 'clean_url' => 'esc_url()',
379
+ '3.0',
380
+ ),
381
+ array(
382
+ 'js_escape' => 'esc_js()',
383
+ '2.8',
384
+ ),
385
+ array(
386
+ 'wp_specialchars' => 'esc_html()',
387
+ '2.8',
388
+ ),
389
+ array(
390
+ 'attribute_escape' => 'esc_attr()',
391
+ '2.8',
392
+ ),
393
+ array(
394
+ 'register_sidebar_widget' => 'wp_register_sidebar_widget()',
395
+ '2.8',
396
+ ),
397
+ array(
398
+ 'unregister_sidebar_widget' => 'wp_unregister_sidebar_widget()',
399
+ '2.8',
400
+ ),
401
+ array(
402
+ 'register_widget_control' => 'wp_register_widget_control()',
403
+ '2.8',
404
+ ),
405
+ array(
406
+ 'unregister_widget_control' => 'wp_unregister_widget_control()',
407
+ '2.8',
408
+ ),
409
+ array(
410
+ 'delete_usermeta' => 'delete_user_meta()',
411
+ '3.0',
412
+ ),
413
+ array(
414
+ 'get_usermeta' => 'get_user_meta()',
415
+ '3.0',
416
+ ),
417
+ array(
418
+ 'update_usermeta' => 'update_user_meta()',
419
+ '3.0',
420
+ ),
421
+ array(
422
+ 'automatic_feed_links' => 'add_theme_support( \'automatic-feed-links\' )',
423
+ '3.0',
424
+ ),
425
+ array(
426
+ 'get_profile' => 'get_the_author_meta()',
427
+ '3.0',
428
+ ),
429
+ array(
430
+ 'get_usernumposts' => 'count_user_posts()',
431
+ '3.0',
432
+ ),
433
+ array(
434
+ 'funky_javascript_callback' => '',
435
+ '3.0',
436
+ ),
437
+ array(
438
+ 'funky_javascript_fix' => '',
439
+ '3.0',
440
+ ),
441
+ array(
442
+ 'is_taxonomy' => 'taxonomy_exists()',
443
+ '3.0',
444
+ ),
445
+ array(
446
+ 'is_term' => 'term_exists()',
447
+ '3.0',
448
+ ),
449
+ array(
450
+ 'is_plugin_page' => '$plugin_page and/or get_plugin_page_hookname() hooks',
451
+ '3.1',
452
+ ),
453
+ array(
454
+ 'update_category_cache' => 'No alternatives',
455
+ '3.1',
456
+ ),
457
+ array(
458
+ 'get_users_of_blog' => 'get_users()',
459
+ '3.1',
460
+ ),
461
+ array(
462
+ 'wp_timezone_supported' => '',
463
+ '3.2',
464
+ ),
465
+ array(
466
+ 'the_editor' => 'wp_editor',
467
+ '3.3',
468
+ ),
469
+ array(
470
+ 'get_user_metavalues' => '',
471
+ '3.3',
472
+ ),
473
+ array(
474
+ 'sanitize_user_object' => '',
475
+ '3.3',
476
+ ),
477
+ array(
478
+ 'get_boundary_post_rel_link' => '',
479
+ '3.3',
480
+ ),
481
+ array(
482
+ 'start_post_rel_link' => 'none available ',
483
+ '3.3',
484
+ ),
485
+ array(
486
+ 'get_index_rel_link' => '',
487
+ '3.3',
488
+ ),
489
+ array(
490
+ 'index_rel_link' => '',
491
+ '3.3',
492
+ ),
493
+ array(
494
+ 'get_parent_post_rel_link' => '',
495
+ '3.3',
496
+ ),
497
+ array(
498
+ 'parent_post_rel_link' => '',
499
+ '3.3',
500
+ ),
501
+ array(
502
+ 'wp_admin_bar_dashboard_view_site_menu' => '',
503
+ '3.3',
504
+ ),
505
+ array(
506
+ 'is_blog_user' => 'is_member_of_blog()',
507
+ '3.3',
508
+ ),
509
+ array(
510
+ 'debug_fopen' => 'error_log()',
511
+ '3.3',
512
+ ),
513
+ array(
514
+ 'debug_fwrite' => 'error_log()',
515
+ '3.3',
516
+ ),
517
+ array(
518
+ 'debug_fclose' => 'error_log()',
519
+ '3.3',
520
+ ),
521
+ array(
522
+ 'get_themes' => 'wp_get_themes()',
523
+ '3.4',
524
+ ),
525
+ array(
526
+ 'get_theme' => 'wp_get_theme()',
527
+ '3.4',
528
+ ),
529
+ array(
530
+ 'get_current_theme' => 'wp_get_theme()',
531
+ '3.4',
532
+ ),
533
+ array(
534
+ 'clean_pre' => '',
535
+ '3.4',
536
+ ),
537
+ array(
538
+ 'add_custom_image_header' => 'add_theme_support( \'custom-header\', $args )',
539
+ '3.4',
540
+ ),
541
+ array(
542
+ 'remove_custom_image_header' => 'remove_theme_support( \'custom-header\' )',
543
+ '3.4',
544
+ ),
545
+ array(
546
+ 'add_custom_background' => 'add_theme_support( \'custom-background\', $args )',
547
+ '3.4',
548
+ ),
549
+ array(
550
+ 'remove_custom_background' => 'remove_theme_support( \'custom-background\' )',
551
+ '3.4',
552
+ ),
553
+ array(
554
+ 'get_theme_data' => 'wp_get_theme()',
555
+ '3.4',
556
+ ),
557
+ array(
558
+ 'update_page_cache' => 'update_post_cache()',
559
+ '3.4',
560
+ ),
561
+ array(
562
+ 'clean_page_cache' => 'clean_post_cache()',
563
+ '3.4',
564
+ ),
565
+ array(
566
+ 'wp_explain_nonce' => 'wp_nonce_ays',
567
+ '3.4.1',
568
+ ),
569
+ array(
570
+ 'sticky_class' => 'post_class()',
571
+ '3.5',
572
+ ),
573
+ array(
574
+ '_get_post_ancestors' => '',
575
+ '3.5',
576
+ ),
577
+ array(
578
+ 'wp_load_image' => 'wp_get_image_editor()',
579
+ '3.5',
580
+ ),
581
+ array(
582
+ 'image_resize' => 'wp_get_image_editor()',
583
+ '3.5',
584
+ ),
585
+ array(
586
+ 'wp_get_single_post' => 'get_post()',
587
+ '3.5',
588
+ ),
589
+ array(
590
+ 'user_pass_ok' => 'wp_authenticate()',
591
+ '3.5',
592
+ ),
593
+ array(
594
+ '_save_post_hook' => '',
595
+ '3.5',
596
+ ),
597
+ array(
598
+ 'gd_edit_image_support' => 'wp_image_editor_supports',
599
+ '3.5',
600
+ ),
601
+ array(
602
+ 'get_user_id_from_string' => 'get_user_by()',
603
+ '3.6',
604
+ ),
605
+ array(
606
+ 'wp_convert_bytes_to_hr' => 'size_format()',
607
+ '3.6',
608
+ ),
609
+
610
+ array(
611
+ 'tinymce_include' => 'wp_tiny_mce()',
612
+ '2.1',
613
+ ),
614
+
615
+ array(
616
+ 'documentation_link' => '',
617
+ '2.5',
618
+ ),
619
+
620
+ array(
621
+ 'dropdown_categories' => 'wp_category_checklist()',
622
+ '2.6',
623
+ ),
624
+ array(
625
+ 'dropdown_link_categories' => 'wp_link_category_checklist()',
626
+ '2.6',
627
+ ),
628
+
629
+ array(
630
+ 'wp_dropdown_cats' => 'wp_dropdown_categories()',
631
+ '3.0',
632
+ ),
633
+ array(
634
+ 'add_option_update_handler' => 'register_setting()',
635
+ '3.0',
636
+ ),
637
+ array(
638
+ 'remove_option_update_handler' => 'unregister_setting()',
639
+ '3.0',
640
+ ),
641
+ array(
642
+ 'codepress_get_lang' => '',
643
+ '3.0',
644
+ ),
645
+ array(
646
+ 'codepress_footer_js' => '',
647
+ '3.0',
648
+ ),
649
+ array(
650
+ 'use_codepress' => '',
651
+ '3.0',
652
+ ),
653
+ array(
654
+ 'wp_shrink_dimensions' => 'wp_constrain_dimensions()',
655
+ '3.0',
656
+ ),
657
+
658
+ array(
659
+ 'get_author_user_ids' => '',
660
+ '3.1',
661
+ ),
662
+ array(
663
+ 'get_editable_authors' => '',
664
+ '3.1',
665
+ ),
666
+ array(
667
+ 'get_editable_user_ids' => '',
668
+ '3.1',
669
+ ),
670
+ array(
671
+ 'get_nonauthor_user_ids' => '',
672
+ '3.1',
673
+ ),
674
+ array(
675
+ 'WP_User_Search' => 'WP_User_Query',
676
+ '3.1',
677
+ ),
678
+ array(
679
+ 'get_others_unpublished_posts' => '',
680
+ '3.1',
681
+ ),
682
+ array(
683
+ 'get_others_drafts' => '',
684
+ '3.1',
685
+ ),
686
+ array(
687
+ 'get_others_pending' => '',
688
+ '3.1',
689
+ ),
690
+
691
+ array(
692
+ 'wp_dashboard_quick_press()' => '',
693
+ '3.2',
694
+ ),
695
+ array(
696
+ 'wp_tiny_mce' => 'wp_editor',
697
+ '3.2',
698
+ ),
699
+ array(
700
+ 'wp_preload_dialogs' => 'wp_editor()',
701
+ '3.2',
702
+ ),
703
+ array(
704
+ 'wp_print_editor_js' => 'wp_editor()',
705
+ '3.2',
706
+ ),
707
+ array(
708
+ 'wp_quicktags' => 'wp_editor()',
709
+ '3.2',
710
+ ),
711
+ array(
712
+ 'favorite_actions' => 'WP_Admin_Bar',
713
+ '3.2',
714
+ ),
715
+
716
+ array(
717
+ 'screen_layout' => '$current_screen->render_screen_layout()',
718
+ '3.3',
719
+ ),
720
+ array(
721
+ 'screen_options' => '$current_screen->render_per_page_options()',
722
+ '3.3',
723
+ ),
724
+ array(
725
+ 'screen_meta' => ' $current_screen->render_screen_meta()',
726
+ '3.3',
727
+ ),
728
+ array(
729
+ 'media_upload_image' => 'wp_media_upload_handler()',
730
+ '3.3',
731
+ ),
732
+ array(
733
+ 'media_upload_audio' => 'wp_media_upload_handler()',
734
+ '3.3',
735
+ ),
736
+ array(
737
+ 'media_upload_video' => 'wp_media_upload_handler()',
738
+ '3.3',
739
+ ),
740
+ array(
741
+ 'media_upload_file' => 'wp_media_upload_handler()',
742
+ '3.3',
743
+ ),
744
+ array(
745
+ 'type_url_form_image' => 'wp_media_insert_url_form( \'image\' )',
746
+ '3.3',
747
+ ),
748
+ array(
749
+ 'type_url_form_audio' => 'wp_media_insert_url_form( \'audio\' )',
750
+ '3.3',
751
+ ),
752
+ array(
753
+ 'type_url_form_video' => 'wp_media_insert_url_form( \'video\' )',
754
+ '3.3',
755
+ ),
756
+ array(
757
+ 'type_url_form_file' => 'wp_media_insert_url_form( \'file\' )',
758
+ '3.3',
759
+ ),
760
+ array(
761
+ 'add_contextual_help' => 'get_current_screen()->add_help_tab()',
762
+ '3.3',
763
+ ),
764
+
765
+ array(
766
+ 'get_allowed_themes' => 'wp_get_themes( array( \'allowed\' => true ) )',
767
+ '3.4',
768
+ ),
769
+ array(
770
+ 'get_broken_themes' => 'wp_get_themes( array( \'errors\' => true )',
771
+ '3.4',
772
+ ),
773
+ array(
774
+ 'current_theme_info' => 'wp_get_theme()',
775
+ '3.4',
776
+ ),
777
+
778
+ array(
779
+ '_insert_into_post_button' => '',
780
+ '3.5',
781
+ ),
782
+ array(
783
+ '_media_button' => '',
784
+ '3.5',
785
+ ),
786
+ array(
787
+ 'get_post_to_edit' => 'get_post()',
788
+ '3.5',
789
+ ),
790
+ array(
791
+ 'get_default_page_to_edit' => 'get_default_post_to_edit()',
792
+ '3.5',
793
+ ),
794
+ array(
795
+ 'wp_create_thumbnail' => 'image_resize()',
796
+ '3.5',
797
+ ),
798
+
799
+ array(
800
+ 'wp_nav_menu_locations_meta_box' => '',
801
+ '3.6',
802
+ ),
803
+
804
+ array(
805
+ 'the_attachment_links' => '',
806
+ '3.7',
807
+ ),
808
+ array(
809
+ 'wp_update_core' => 'new Core_Upgrader()',
810
+ '3.7',
811
+ ),
812
+ array(
813
+ 'wp_update_plugin' => 'new Plugin_Upgrader()',
814
+ '3.7',
815
+ ),
816
+ array(
817
+ 'wp_update_theme' => 'new Theme_Upgrader()',
818
+ '3.7',
819
+ ),
820
+ array(
821
+ '_search_terms_tidy' => '',
822
+ '3.7',
823
+ ),
824
+ array(
825
+ 'get_blogaddress_by_domain' => '',
826
+ '3.7',
827
+ ),
828
+
829
+ array(
830
+ 'get_screen_icon' => '',
831
+ '3.8',
832
+ ),
833
+ array(
834
+ 'screen_icon' => '',
835
+ '3.8',
836
+ ),
837
+ array(
838
+ 'wp_dashboard_incoming_links' => '',
839
+ '3.8',
840
+ ),
841
+ array(
842
+ 'wp_dashboard_incoming_links_control' => '',
843
+ '3.8',
844
+ ),
845
+ array(
846
+ 'wp_dashboard_incoming_links_output' => '',
847
+ '3.8',
848
+ ),
849
+ array(
850
+ 'wp_dashboard_plugins' => '',
851
+ '3.8',
852
+ ),
853
+ array(
854
+ 'wp_dashboard_primary_control' => '',
855
+ '3.8',
856
+ ),
857
+ array(
858
+ 'wp_dashboard_recent_comments_control' => '',
859
+ '3.8',
860
+ ),
861
+ array(
862
+ 'wp_dashboard_secondary' => '',
863
+ '3.8',
864
+ ),
865
+ array(
866
+ 'wp_dashboard_secondary_control' => '',
867
+ '3.8',
868
+ ),
869
+ array(
870
+ 'wp_dashboard_secondary_output' => '',
871
+ '3.8',
872
+ ),
873
+
874
+ array(
875
+ 'rich_edit_exists' => '',
876
+ '3.9',
877
+ ),
878
+ array(
879
+ 'default_topic_count_text' => '',
880
+ '3.9',
881
+ ),
882
+ array(
883
+ 'format_to_post' => '',
884
+ '3.9',
885
+ ),
886
+ array(
887
+ 'get_current_site_name' => 'get_current_site()',
888
+ '3.9',
889
+ ),
890
+ array(
891
+ 'wpmu_current_site' => '',
892
+ '3.9',
893
+ ),
894
+ array(
895
+ '_relocate_children' => '',
896
+ '3.9',
897
+ ),
898
+
899
+ array(
900
+ 'get_all_category_ids' => 'get_terms()',
901
+ '4.0',
902
+ ),
903
+ array(
904
+ 'like_escape' => 'wpdb::esc_like()',
905
+ '4.0',
906
+ ),
907
+ array(
908
+ 'url_is_accessable_via_ssl' => '',
909
+ '4.0',
910
+ ),
911
+ array(
912
+ 'get_all_category_ids' => 'get_terms()',
913
+ '4.0',
914
+ ),
915
+ array(
916
+ 'like_escape' => 'wpdb::esc_like()',
917
+ '4.0',
918
+ ),
919
+ array(
920
+ 'url_is_accessable_via_ssl' => '',
921
+ '4.0',
922
+ ),
923
+
924
+ array(
925
+ 'prepare_control' => '',
926
+ '4.1',
927
+ ),
928
+ array(
929
+ 'add_tab' => '',
930
+ '4.1',
931
+ ),
932
+ array(
933
+ 'remove_tab' => '',
934
+ '4.1',
935
+ ),
936
+ array(
937
+ 'print_tab_image' => '',
938
+ '4.1',
939
+ ),
940
+
941
+ array(
942
+ 'setup_widget_addition_previews' => 'customize_dynamic_setting_args',
943
+ '4.2',
944
+ ),
945
+ array(
946
+ 'prepreview_added_sidebars_widgets' => 'customize_dynamic_setting_args',
947
+ '4.2',
948
+ ),
949
+ array(
950
+ 'prepreview_added_widget_instance' => 'customize_dynamic_setting_args',
951
+ '4.2',
952
+ ),
953
+ array(
954
+ 'remove_prepreview_filters' => 'customize_dynamic_setting_args',
955
+ '4.2',
956
+ ),
957
+
958
+ array(
959
+ 'wp_htmledit_pre' => 'format_for_editor',
960
+ '4.3',
961
+ ),
962
+ array(
963
+ 'wp_richedit_pre' => 'format_for_editor',
964
+ '4.3',
965
+ ),
966
+ array(
967
+ 'preview_theme' => '',
968
+ '4.3',
969
+ ),
970
+ array(
971
+ '_preview_theme_stylesheet_filter' => '',
972
+ '4.3',
973
+ ),
974
+ array(
975
+ 'preview_theme_ob_filter' => '',
976
+ '4.3',
977
+ ),
978
+ array(
979
+ 'preview_theme_ob_filter_callback' => '',
980
+ '4.3',
981
+ ),
982
+ array(
983
+ 'wp_ajax_wp_fullscreen_save_post' => '',
984
+ '4.3',
985
+ ),
986
+
987
+ array(
988
+ 'wp_get_http' => 'WP_Http',
989
+ '4.4',
990
+ ),
991
+ array(
992
+ 'post_permalink' => 'get_permalink',
993
+ '4.4',
994
+ ),
995
+ array(
996
+ 'force_ssl_login' => 'force_ssl_admin',
997
+ '4.4',
998
+ ),
999
+ array(
1000
+ 'create_empty_blog' => '',
1001
+ '4.4',
1002
+ ),
1003
+ array(
1004
+ 'get_admin_users_for_domain' => '',
1005
+ '4.4',
1006
+ ),
1007
+
1008
+ array(
1009
+ 'is_comments_popup' => '',
1010
+ '4.5',
1011
+ ),
1012
+ array(
1013
+ 'add_object_page' => 'add_menu_page',
1014
+ '4.5',
1015
+ ),
1016
+ array(
1017
+ 'add_utility_page' => 'add_menu_page',
1018
+ '4.5',
1019
+ ),
1020
+ array(
1021
+ 'get_comments_popup_template' => '',
1022
+ '4.5',
1023
+ ),
1024
+ array(
1025
+ 'comments_popup_script' => '',
1026
+ '4.5',
1027
+ ),
1028
+ array(
1029
+ 'popuplinks' => '',
1030
+ '4.5',
1031
+ ),
1032
+ array(
1033
+ 'get_currentuserinfo' => 'wp_get_current_user',
1034
+ '4.5',
1035
+ ),
1036
+
1037
+ array(
1038
+ 'wp_embed_handler_googlevideo' => '',
1039
+ '4.6',
1040
+ ),
1041
+ array(
1042
+ 'wp_get_sites' => 'get_sites',
1043
+ '4.6',
1044
+ ),
1045
+ array(
1046
+ 'post_form_autocomplete_off' => '',
1047
+ '4.6',
1048
+ ),
1049
+
1050
+ array(
1051
+ 'wp_die_handler' => '',
1052
+ '4.7',
1053
+ ),
1054
+ array(
1055
+ 'wp_redirect_status' => '',
1056
+ '4.7',
1057
+ ),
1058
+ array(
1059
+ 'customize_preview_override_404_status' => '',
1060
+ '4.7',
1061
+ ),
1062
+ array(
1063
+ 'customize_preview_base' => '',
1064
+ '4.7',
1065
+ ),
1066
+ array(
1067
+ 'customize_preview_html5' => '',
1068
+ '4.7',
1069
+ ),
1070
+ array(
1071
+ 'customize_preview_signature' => '',
1072
+ '4.7',
1073
+ ),
1074
+ array(
1075
+ 'remove_preview_signature' => '',
1076
+ '4.7',
1077
+ ),
1078
+ array(
1079
+ '_cmp_priority' => 'wp_list_sort',
1080
+ '4.7',
1081
+ ),
1082
+ array(
1083
+ 'reinit' => 'WP_Roles::for_site()',
1084
+ '4.7',
1085
+ ),
1086
+ array(
1087
+ 'get_paged_template' => '',
1088
+ '4.7',
1089
+ ),
1090
+ array(
1091
+ 'wp_kses_js_entities' => '',
1092
+ '4.7',
1093
+ ),
1094
+ array(
1095
+ 'wp_get_network' => 'get_network()',
1096
+ '4.7',
1097
+ ),
1098
+ array(
1099
+ '_sort_menus_by_orderby' => 'wp_list_sort',
1100
+ '4.7',
1101
+ ),
1102
+
1103
+ array(
1104
+ 'wp_dashboard_plugins_output' => '',
1105
+ '4.8',
1106
+ ),
1107
+
1108
+ array(
1109
+ '_init' => 'WP_Roles::for_site()',
1110
+ '4.9',
1111
+ ),
1112
+ array(
1113
+ '_init_caps' => 'WP_User::for_site()',
1114
+ '4.9',
1115
+ ),
1116
+ array(
1117
+ 'for_blog' => 'WP_User::for_site()',
1118
+ '4.9',
1119
+ ),
1120
+ array(
1121
+ 'get_shortcut_link' => '',
1122
+ '4.9',
1123
+ ),
1124
+ array(
1125
+ 'wp_ajax_press_this_save_post' => '',
1126
+ '4.9',
1127
+ ),
1128
+ array(
1129
+ 'wp_ajax_press_this_add_category' => '',
1130
+ '4.9',
1131
+ ),
1132
+ array(
1133
+ 'is_user_option_local' => '',
1134
+ '4.9',
1135
+ ),
1136
+ array(
1137
+ 'maybe_log_events_response' => '',
1138
+ '4.9',
1139
+ ),
1140
+
1141
+ array(
1142
+ 'insert_blog' => 'wp_insert_site()',
1143
+ '5.1',
1144
+ ),
1145
+ array(
1146
+ 'install_blog' => '',
1147
+ '5.1',
1148
+ ),
1149
+ );
1150
+ foreach ( $php_files as $php_key => $phpfile ) {
1151
+ foreach ( $checks as $alt => $check ) {
1152
+ checkcount();
1153
+ $key = key( $check );
1154
+ $alt = $check[ $key ];
1155
+ if ( preg_match( '/(?<!function)[\s?]' . $key . '\s?\(/', $phpfile, $matches ) ) {
1156
+ $filename = tc_filename( $php_key );
1157
+ $error = ltrim( rtrim( $matches[0], '(' ) );
1158
+ $version = $check[0];
1159
+ $grep = tc_grep( $error, $php_key );
1160
+
1161
+ // Point out the deprecated function.
1162
+ $error_msg = sprintf(
1163
+ __( '%1$s found in the file %2$s. Deprecated since version %3$s.', 'theme-check' ),
1164
+ '<strong>' . $error . '()</strong>',
1165
+ '<strong>' . $filename . '</strong>',
1166
+ '<strong>' . $version . '</strong>'
1167
+ );
1168
+
1169
+ // Add alternative function when available.
1170
+ if ( $alt ) {
1171
+ $error_msg .= ' ' . sprintf( __( 'Use %s instead.', 'theme-check' ), '<strong>' . $alt . '</strong>' );
1172
+ }
1173
+
1174
+ // Add the precise code match that was found.
1175
+ $error_msg .= $grep;
1176
+
1177
+ // Add the finalized error message.
1178
+ $this->error[] = sprintf(
1179
+ '<span class="tc-lead tc-required">%s</span>: %s',
1180
+ __( 'REQUIRED', 'theme-check' ),
1181
+ $error_msg
1182
+ );
1183
+
1184
+ $ret = false;
1185
+ }
1186
+ }
1187
+ }
1188
+ return $ret;
1189
+ }
1190
+
1191
+ /**
1192
+ * Get error messages from the checks.
1193
+ *
1194
+ * @return array Error message.
1195
+ */
1196
+ public function getError() {
1197
+ return $this->error;
1198
+ }
1199
+ }
1200
+
1201
+ $themechecks[] = new Deprecated_Check();
checks/{more_deprecated.php → class-deprecated-param-check.php} RENAMED
@@ -1,13 +1,29 @@
1
  <?php
2
-
3
  /**
4
  * Checks for the use of deprecated function parameters.
 
 
5
  */
6
 
7
- class More_Deprecated implements themecheck {
 
 
 
 
 
 
 
 
8
  protected $error = array();
9
 
10
- function check( $php_files, $css_files, $other_files ) {
 
 
 
 
 
 
 
11
 
12
  $ret = true;
13
 
@@ -22,7 +38,7 @@ class More_Deprecated implements themecheck {
22
  'text_direction' => 'is_rtl()',
23
  'feed_url' => "get_feed_link( 'feed' ), where feed is rss, rss2 or atom",
24
  ),
25
- 'bloginfo' => array(
26
  'home' => 'echo esc_url( home_url() )',
27
  'url' => 'echo esc_url( home_url() )',
28
  'wpurl' => 'echo esc_url( site_url() )',
@@ -32,10 +48,10 @@ class More_Deprecated implements themecheck {
32
  'text_direction' => 'is_rtl()',
33
  'feed_url' => "echo esc_url( get_feed_link( 'feed' ) ), where feed is rss, rss2 or atom",
34
  ),
35
- 'get_option' => array(
36
  'home' => 'home_url()',
37
  'site_url' => 'site_url()',
38
- )
39
  );
40
 
41
  foreach ( $php_files as $php_key => $php_file ) {
@@ -49,7 +65,17 @@ class More_Deprecated implements themecheck {
49
  $filename = tc_filename( $php_key );
50
  $error = ltrim( rtrim( $matches[0], '(' ) );
51
  $grep = tc_grep( $error, $php_key );
52
- $this->error[] = sprintf( '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( '%1$s was found in the file %2$s. Use %3$s instead.%4$s', 'theme-check' ), '<strong>' . $error . '</strong>', '<strong>' . $filename . '</strong>', '<strong>' . $replacement . '</strong>', $grep );
 
 
 
 
 
 
 
 
 
 
53
  $ret = false;
54
  }
55
  }
@@ -59,6 +85,14 @@ class More_Deprecated implements themecheck {
59
  return $ret;
60
  }
61
 
62
- function getError() { return $this->error; }
 
 
 
 
 
 
 
63
  }
64
- $themechecks[] = new More_Deprecated;
 
1
  <?php
 
2
  /**
3
  * Checks for the use of deprecated function parameters.
4
+ *
5
+ * @package Theme Check
6
  */
7
 
8
+ /**
9
+ * Checks for the use of deprecated function parameters.
10
+ */
11
+ class Deprecated_Param_Check 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
 
38
  'text_direction' => 'is_rtl()',
39
  'feed_url' => "get_feed_link( 'feed' ), where feed is rss, rss2 or atom",
40
  ),
41
+ 'bloginfo' => array(
42
  'home' => 'echo esc_url( home_url() )',
43
  'url' => 'echo esc_url( home_url() )',
44
  'wpurl' => 'echo esc_url( site_url() )',
48
  'text_direction' => 'is_rtl()',
49
  'feed_url' => "echo esc_url( get_feed_link( 'feed' ) ), where feed is rss, rss2 or atom",
50
  ),
51
+ 'get_option' => array(
52
  'home' => 'home_url()',
53
  'site_url' => 'site_url()',
54
+ ),
55
  );
56
 
57
  foreach ( $php_files as $php_key => $php_file ) {
65
  $filename = tc_filename( $php_key );
66
  $error = ltrim( rtrim( $matches[0], '(' ) );
67
  $grep = tc_grep( $error, $php_key );
68
+ $this->error[] = sprintf(
69
+ '<span class="tc-lead tc-required">%s</span>: %s %s',
70
+ __( 'REQUIRED', 'theme-check' ),
71
+ sprintf(
72
+ __( '%1$s was found in the file %2$s. Use %3$s instead.', 'theme-check' ),
73
+ '<strong>' . $error . '</strong>',
74
+ '<strong>' . $filename . '</strong>',
75
+ '<strong>' . $replacement . '</strong>'
76
+ ),
77
+ $grep
78
+ );
79
  $ret = false;
80
  }
81
  }
85
  return $ret;
86
  }
87
 
88
+ /**
89
+ * Get error messages from the checks.
90
+ *
91
+ * @return array Error message.
92
+ */
93
+ public function getError() {
94
+ return $this->error;
95
+ }
96
  }
97
+
98
+ $themechecks[] = new Deprecated_Param_Check();
checks/class-deregister-check.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Checks if core scripts are deregistered.
4
+ *
5
+ * Themes must use WordPress’ default libraries.
6
+ * WordPress includes a number of libraries such as jQuery.
7
+ * For security and stability reasons themes may not include those libraries in their own code.
8
+ * Instead themes must use the versions of those libraries packaged with WordPress.
9
+ *
10
+ * @package Theme Check
11
+ */
12
+
13
+ /**
14
+ * Checks if core scripts are deregistered.
15
+ */
16
+ class Deregister_Check implements themecheck {
17
+ protected $error = array();
18
+
19
+ function check( $php_files, $css_files, $other_files ) {
20
+ foreach ( $php_files as $file_path => $file_content ) {
21
+ checkcount();
22
+
23
+ if ( false !== strpos( $file_content, 'wp_deregister_script' ) ) {
24
+ $grep = tc_preg( '/wp_deregister_script/', $file_path );
25
+ $this->error[] = sprintf(
26
+ '<span class="tc-lead tc-warning">%s</span>: %s %s',
27
+ __( 'WARNING', 'theme-check' ),
28
+ sprintf(
29
+ __( 'Found wp_deregister_script in %1$s. Themes must not deregister scripts that are included in WordPress. Deregistering third party scripts that are registered by parent themes is allowed.', 'theme-check' ),
30
+ '<strong>' . tc_filename( $file_path ) . '</strong>'
31
+ ),
32
+ $grep
33
+ );
34
+ }
35
+ }
36
+
37
+ return true;
38
+ }
39
+
40
+ function getError() {
41
+ return $this->error;
42
+ }
43
+ }
44
+
45
+ $themechecks[] = new Deregister_Check();
checks/class-directories-check.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check if directories only intended for development are included
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check if directories only intended for development are included.
10
+ *
11
+ * Check if directories only intended for development are included. If they are, require them to be removed.
12
+ */
13
+ class Directories_Check implements themecheck {
14
+ /**
15
+ * Error messages, warnings and info notices.
16
+ *
17
+ * @var array $error
18
+ */
19
+ protected $error = array();
20
+
21
+ /**
22
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
23
+ *
24
+ * @param array $php_files File paths and content for PHP files.
25
+ * @param array $css_files File paths and content for CSS files.
26
+ * @param array $other_files Folder names, file paths and content for other files.
27
+ */
28
+ public function check( $php_files, $css_files, $other_files ) {
29
+
30
+ $excluded_directories = array(
31
+ '.git',
32
+ '.svn',
33
+ '.hg',
34
+ '.bzr',
35
+ );
36
+
37
+ $ret = true;
38
+
39
+ $all_filenames = array_merge(
40
+ array_keys( $php_files ),
41
+ array_keys( $css_files ),
42
+ array_keys( $other_files )
43
+ );
44
+
45
+ foreach ( $all_filenames as $path ) {
46
+ checkcount();
47
+
48
+ $filename = basename( $path );
49
+
50
+ if ( in_array( $filename, $excluded_directories, true ) ) {
51
+ $this->error[] = sprintf(
52
+ '<span class="tc-lead tc-required">%s</span>: %s',
53
+ __( 'REQUIRED', 'theme-check' ),
54
+ __( 'Please remove any extraneous directories like .git or .svn from the ZIP file before uploading it.', 'theme-check' )
55
+ );
56
+ $ret = false;
57
+ }
58
+ }
59
+
60
+ return $ret;
61
+ }
62
+
63
+ /**
64
+ * Get error messages from the checks.
65
+ *
66
+ * @return array Error message.
67
+ */
68
+ public function getError() {
69
+ return $this->error;
70
+ }
71
+ }
72
+
73
+ $themechecks[] = new Directories_Check();
checks/class-editor-style-check.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check if add_editor_style is included
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check if add_editor_style is included.
10
+ *
11
+ * Check if add_editor_style is included. If not, recommend it.
12
+ */
13
+ class Editor_Style_Check implements themecheck {
14
+ /**
15
+ * Error messages, warnings and info notices.
16
+ *
17
+ * @var array $error
18
+ */
19
+ protected $error = array();
20
+
21
+ /**
22
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
23
+ *
24
+ * @param array $php_files File paths and content for PHP files.
25
+ * @param array $css_files File paths and content for CSS files.
26
+ * @param array $other_files Folder names, file paths and content for other files.
27
+ */
28
+ public function check( $php_files, $css_files, $other_files ) {
29
+ checkcount();
30
+ $ret = true;
31
+
32
+ $php = implode( ' ', $php_files );
33
+
34
+ if ( strpos( $php, 'add_editor_style' ) === false ) {
35
+ $this->error[] = sprintf(
36
+ '<span class="tc-lead tc-recommended">%s</span>: %s',
37
+ __( 'RECOMMENDED', 'theme-check' ),
38
+ __( 'No reference to <strong>add_editor_style()</strong> was found in the theme. It is recommended that the theme implement editor styling, so as to make the editor content match the resulting post output in the theme, for a better user experience.', 'theme-check' )
39
+ );
40
+ }
41
+
42
+ return $ret;
43
+ }
44
+
45
+ /**
46
+ * Get error messages from the checks.
47
+ *
48
+ * @return array Error message.
49
+ */
50
+ public function getError() {
51
+ return $this->error;
52
+ }
53
+ }
54
+
55
+ $themechecks[] = new Editor_Style_Check();
checks/{escaping.php → class-escaping-check.php} RENAMED
@@ -1,105 +1,122 @@
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
2
+ /**
3
+ * Checks for common escaping issues.
4
+ *
5
+ * @link https://make.wordpress.org/themes/handbook/review/required/#code
6
+ *
7
+ * @package Theme Check
8
+ */
9
+
10
+ /**
11
+ * Checks for common escaping issues.
12
+ */
13
+ class Escaping_Check implements themecheck {
14
+ /**
15
+ * Error messages, warnings and info notices.
16
+ *
17
+ * @var array $error
18
+ */
19
+ protected $error = array();
20
+
21
+ /**
22
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
23
+ *
24
+ * @param array $php_files File paths and content for PHP files.
25
+ * @param array $css_files File paths and content for CSS files.
26
+ * @param array $other_files Folder names, file paths and content for other files.
27
+ */
28
+ public function check( $php_files, $css_files, $other_files ) {
29
+
30
+ $ret = true;
31
+
32
+ $warnings = array(
33
+ '/="<\?php esc_html_e/' => __( 'Use esc_attr_e() inside HTML attributes, and esc_url() for link attributes', 'theme-check' ),
34
+ '/="<\?php echo esc_html__/' => __( 'Use esc_attr__() inside HTML attributes, and esc_url() for link attributes', 'theme-check' ),
35
+ '/="<\?php esc_html\(/' => __( 'Use esc_attr() inside HTML attributes, and esc_url() for link attributes', 'theme-check' ),
36
+ '/><\?php echo esc_attr\(/' => __( 'Only use esc_attr() inside HTML attributes. Use esc_html() between HTML tags', 'theme-check' ),
37
+ '/><\?php echo esc_attr__/' => __( 'Only use esc_attr__() inside HTML attributes. Use esc_html__() between HTML tags', 'theme-check' ),
38
+ '/><\?php esc_attr_e/' => __( 'Only use esc_attr_e() inside HTML attributes. Use esc_html_e() between HTML tags', 'theme-check' ),
39
+ );
40
+
41
+ $required = array(
42
+ '/echo home_url/' => __( 'home_url() must be escaped. Use esc_url() for link attributes', 'theme-check' ),
43
+ '/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' ),
44
+ );
45
+
46
+ foreach ( $php_files as $php_key => $phpfile ) {
47
+
48
+ checkcount();
49
+ if ( false !== strpos( $phpfile, 'echo get_theme_mod' ) ) {
50
+ $filename = tc_filename( $php_key );
51
+ $error = 'echo get_theme_mod';
52
+ $grep = tc_grep( $error, $php_key );
53
+ $this->error[] = sprintf(
54
+ '<span class="tc-lead tc-warning">%s</span>: %s %s',
55
+ __( 'WARNING', 'theme-check' ),
56
+ sprintf(
57
+ __( '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' ),
58
+ '<code>' . esc_html( $error ) . '</code>',
59
+ '<strong>' . $filename . '</strong>',
60
+ 'https://developer.wordpress.org/themes/theme-security/data-sanitization-escaping/#escaping-securing-output'
61
+ ),
62
+ $grep
63
+ );
64
+
65
+ }
66
+
67
+ foreach ( $warnings as $key => $check ) {
68
+ checkcount();
69
+ if ( preg_match( $key, $phpfile, $matches ) ) {
70
+ $filename = tc_filename( $php_key );
71
+ $error = $matches[0];
72
+ $grep = tc_grep( $error, $php_key );
73
+ $this->error[] = sprintf(
74
+ '<span class="tc-lead tc-warning">%s</span>: %s %s',
75
+ __( 'WARNING', 'theme-check' ),
76
+ sprintf(
77
+ __( 'Found %1$s in %2$s. %3$s. A manual review is needed.', 'theme-check' ),
78
+ '<code>' . esc_html( $error ) . '</code>',
79
+ '<strong>' . $filename . '</strong>',
80
+ $check
81
+ ),
82
+ $grep
83
+ );
84
+ }
85
+ }
86
+
87
+ foreach ( $required as $key => $check ) {
88
+ checkcount();
89
+ if ( preg_match( $key, $phpfile, $matches ) ) {
90
+ $filename = tc_filename( $php_key );
91
+ $error = $matches[0];
92
+ $grep = tc_grep( $error, $php_key );
93
+ $this->error[] = sprintf(
94
+ '<span class="tc-lead tc-required">%s</span>: %s %s',
95
+ __( 'REQUIRED', 'theme-check' ),
96
+ sprintf(
97
+ __( 'Found %1$s in %2$s. %3$s. A manual review is needed.', 'theme-check' ),
98
+ '<code>' . esc_html( $error ) . '</code>',
99
+ '<strong>' . $filename . '</strong>',
100
+ $check
101
+ ),
102
+ $grep
103
+ );
104
+
105
+ $ret = false;
106
+ }
107
+ }
108
+ }
109
+ return $ret;
110
+ }
111
+
112
+ /**
113
+ * Get error messages from the checks.
114
+ *
115
+ * @return array Error message.
116
+ */
117
+ public function getError() {
118
+ return $this->error;
119
+ }
120
+ }
121
+
122
+ $themechecks[] = new Escaping_Check();
checks/class-favicon-check.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Checks for favicons.
4
+ *
5
+ * Note: The check for the icon file is in filenames.php.
6
+ *
7
+ * @package Theme Check
8
+ */
9
+
10
+ /**
11
+ * Checks for favicons.
12
+ */
13
+ class Favicon_Check implements themecheck {
14
+ /**
15
+ * Error messages, warnings and info notices.
16
+ *
17
+ * @var array $error
18
+ */
19
+ protected $error = array();
20
+
21
+ /**
22
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
23
+ *
24
+ * @param array $php_files File paths and content for PHP files.
25
+ * @param array $css_files File paths and content for CSS files.
26
+ * @param array $other_files Folder names, file paths and content for other files.
27
+ */
28
+ public function check( $php_files, $css_files, $other_files ) {
29
+
30
+ $ret = true;
31
+
32
+ checkcount();
33
+
34
+ foreach ( $php_files as $file_path => $file_content ) {
35
+
36
+ $filename = tc_filename( $file_path );
37
+
38
+ if (
39
+ preg_match( '/(<link rel=[\'"](icon|shortcut icon|apple-touch-icon.*)[\'"])/i', $file_content ) ||
40
+ preg_match( '/(<meta name=[\'"]msapplication-TileImage[\'"])/i', $file_content )
41
+ ) {
42
+ $this->error[] = sprintf(
43
+ '<span class="tc-lead tc-required">%s</span>: %s',
44
+ __( 'REQUIRED', 'theme-check' ),
45
+ sprintf(
46
+ __( 'Possible Favicon found in %1$s. Favicons are handled by the Site Icon setting in the customizer since version 4.3.', 'theme-check' ),
47
+ '<strong>' . $filename . '</strong>'
48
+ )
49
+ );
50
+ $ret = false;
51
+ }
52
+ }
53
+ return $ret;
54
+ }
55
+
56
+ /**
57
+ * Get error messages from the checks.
58
+ *
59
+ * @return array Error message.
60
+ */
61
+ public function getError() {
62
+ return $this->error;
63
+ }
64
+ }
65
+
66
+ $themechecks[] = new Favicon_Check();
checks/{filenames.php → class-file-check.php} RENAMED
@@ -1,8 +1,29 @@
1
  <?php
2
- class File_Checks implements themecheck {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  protected $error = array();
4
 
5
- function check( $php_files, $css_files, $other_files ) {
 
 
 
 
 
 
 
6
 
7
  $ret = true;
8
 
@@ -20,7 +41,7 @@ class File_Checks implements themecheck {
20
 
21
  $allowlist = array(
22
  'wpml-config.xml',
23
- 'loco.xml'
24
  );
25
 
26
  $blocklist = array(
@@ -46,50 +67,64 @@ class File_Checks implements themecheck {
46
  'postcss\.config\.js' => __( 'PostCSS config file', 'theme-check' ),
47
  '\.editorconfig.' => __( 'Editor config file', 'theme-check' ),
48
  '\.stylelintrc\.json' => __( 'Stylelint config file', 'theme-check' ),
49
- '\.map' => __( 'Map file', 'theme-check' ),
50
  '\.eslintrc' => __( 'ES lint config file', 'theme-check' ),
51
  'favicon\.ico' => __( 'Favicon', 'theme-check' ),
52
  );
53
 
54
  $musthave = array( 'index.php', 'style.css', 'readme.txt' );
55
- $rechave = array();
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
  }
74
  }
75
 
76
  foreach ( $musthave as $file ) {
77
  if ( ! in_array( $file, $filenames ) ) {
78
- $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>' );
 
 
 
 
 
 
 
79
  $ret = false;
80
  }
81
  }
82
 
83
- foreach ( $rechave as $file => $reason ) {
84
- if ( ! in_array( $file, $filenames ) ) {
85
- $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 );
86
- }
87
- }
88
-
89
  return $ret;
90
  }
91
 
92
- function getError() { return $this->error; }
 
 
 
 
 
 
 
93
  }
94
 
95
- $themechecks[] = new File_Checks();
1
  <?php
2
+ /**
3
+ * Check for files that are not allowed and files that are required.
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check for files that are not allowed and files that are required.
10
+ */
11
+ class File_Check 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
 
41
 
42
  $allowlist = array(
43
  'wpml-config.xml',
44
+ 'loco.xml',
45
  );
46
 
47
  $blocklist = array(
67
  'postcss\.config\.js' => __( 'PostCSS config file', 'theme-check' ),
68
  '\.editorconfig.' => __( 'Editor config file', 'theme-check' ),
69
  '\.stylelintrc\.json' => __( 'Stylelint config file', 'theme-check' ),
 
70
  '\.eslintrc' => __( 'ES lint config file', 'theme-check' ),
71
  'favicon\.ico' => __( 'Favicon', 'theme-check' ),
72
  );
73
 
74
  $musthave = array( 'index.php', 'style.css', 'readme.txt' );
 
75
 
76
  checkcount();
77
 
78
  foreach ( $blocklist as $file => $reason ) {
79
  if ( $filename = preg_grep( '/' . $file . '/', $filenames ) ) {
80
+ $commons = array_intersect( $filename, $allowlist );
81
  foreach ( $commons as $common ) {
82
+ if ( ( $allowed_key = array_search( $common, $filename ) ) !== false ) {
83
+ unset( $filename[ $allowed_key ] );
84
  }
85
  }
86
  if ( empty( $filename ) ) {
87
  continue;
88
  }
89
  $error = implode( ' ', array_unique( $filename ) );
90
+ $this->error[] = sprintf(
91
+ '<span class="tc-lead tc-required">%s</span>: %s',
92
+ __( 'REQUIRED', 'theme-check' ),
93
+ sprintf(
94
+ __( '%1$s %2$s found. This file must not be in a theme.', 'theme-check' ),
95
+ '<strong>' . $error . '</strong>',
96
+ $reason
97
+ )
98
+ );
99
  $ret = false;
100
  }
101
  }
102
 
103
  foreach ( $musthave as $file ) {
104
  if ( ! in_array( $file, $filenames ) ) {
105
+ $this->error[] = sprintf(
106
+ '<span class="tc-lead tc-required">%s</span>: %s',
107
+ __( 'REQUIRED', 'theme-check' ),
108
+ sprintf(
109
+ __( 'Could not find the file %s in the theme.', 'theme-check' ),
110
+ '<strong>' . $file . '</strong>'
111
+ )
112
+ );
113
  $ret = false;
114
  }
115
  }
116
 
 
 
 
 
 
 
117
  return $ret;
118
  }
119
 
120
+ /**
121
+ * Get error messages from the checks.
122
+ *
123
+ * @return array Error message.
124
+ */
125
+ public function getError() {
126
+ return $this->error;
127
+ }
128
  }
129
 
130
+ $themechecks[] = new File_Check();
checks/class-filesystem-http-check.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check for filesystem operations and HTTP requests.
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check for filesystem operations and HTTP requests.
10
+ */
11
+ class Filesystem_HTTP_Check 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
+
29
+ $checks = array(
30
+ // Filesystem operations are not advised. file_get_contents() is allowed.
31
+ '/[^a-z0-9](?<!_)(readfile|fopen)\s?\(/i' => __( 'File read operations should use file_get_contents() but are discouraged unless required', 'theme-check' ),
32
+ '/[^a-z0-9](?<!_)(fopen|fclose|fread|fwrite|file_put_contents)\s?\(/i' => __( 'File write operations should are avoided unless necessary', 'theme-check' ),
33
+
34
+ // WP_Filesystem should only be used for theme upgrade operations. It should not be used to avoid the fopen()/file_put_contents()/etc warnings.
35
+ '/[^a-z0-9](?<!_)(WP_Filesystem)\s?\(/i' => __( 'WP_Filesystem should only be used for theme upgrade operations, not for all file operations. Consider using file_get_contents(), scandir(), or glob()', 'theme-check' ),
36
+
37
+ // HTTP Requests should use WP_HTTP.
38
+ '/[^a-z0-9](?<!_)(curl_exec|curl_init|fsockopen|pfsockopen|stream_context_create)\s?\(/' => __( 'HTTP requests should be made using the WordPress HTTP wrappers, such as wp_safe_remote_get() and wp_safe_remote_post()', 'theme-check' ),
39
+ );
40
+
41
+ foreach ( $php_files as $php_key => $phpfile ) {
42
+ foreach ( $checks as $key => $check ) {
43
+ checkcount();
44
+
45
+ if ( preg_match_all( $key, $phpfile, $matches ) ) {
46
+ $filename = tc_filename( $php_key );
47
+
48
+ foreach ( $matches[1] as $match ) {
49
+ $error = ltrim( $match, '(' );
50
+ $error = rtrim( $error, '(' );
51
+
52
+ $grep = tc_grep( $error, $php_key );
53
+ $this->error[] = sprintf(
54
+ '<span class="tc-lead tc-warning">%s</span>: %s %s',
55
+ __( 'WARNING', 'theme-check' ),
56
+ sprintf(
57
+ __( '%1$s was found in the file %2$s %3$s', 'theme-check' ),
58
+ '<strong>' . $error . '</strong>',
59
+ '<strong>' . $filename . '</strong>',
60
+ $check
61
+ ),
62
+ $grep
63
+ );
64
+ }
65
+ }
66
+ }
67
+ }
68
+ return $ret;
69
+ }
70
+
71
+ /**
72
+ * Get error messages from the checks.
73
+ *
74
+ * @return array Error message.
75
+ */
76
+ public function getError() {
77
+ return $this->error;
78
+ }
79
+ }
80
+
81
+ $themechecks[] = new Filesystem_HTTP_Check();
checks/class-fse-required-files-check.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Checks that Full-Site Editing themes have the required files.
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Class FSE_Required_Files_Check
10
+ *
11
+ * Checks that Full-Site Editing themes have the required files.
12
+ *
13
+ * This check is not added to the global array of checks, because it doesn't apply to all themes.
14
+ */
15
+ class FSE_Required_Files_Check implements themecheck {
16
+ /**
17
+ * Error messages, warnings and info notices.
18
+ *
19
+ * @var array $error
20
+ */
21
+ protected $error = array();
22
+
23
+ /**
24
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
25
+ *
26
+ * @param array $php_files File paths and content for PHP files.
27
+ * @param array $css_files File paths and content for CSS files.
28
+ * @param array $other_files Folder names, file paths and content for other files.
29
+ */
30
+ public function check( $php_files, $css_files, $other_files ) {
31
+
32
+ $ret = true;
33
+
34
+ $filenames = array();
35
+
36
+ foreach ( $other_files as $php_key => $phpfile ) {
37
+ array_push( $filenames, tc_filename( $php_key ) );
38
+ }
39
+
40
+ $musthave = array(
41
+ 'block-templates/index.html',
42
+ 'theme.json',
43
+ );
44
+
45
+ foreach ( $musthave as $file ) {
46
+ if ( ! in_array( $file, $filenames ) ) {
47
+ $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>' );
48
+ $ret = false;
49
+ }
50
+ }
51
+
52
+ return $ret;
53
+ }
54
+
55
+ /**
56
+ * Get error messages from the checks.
57
+ *
58
+ * @return array Error message.
59
+ */
60
+ public function getError() {
61
+ return $this->error;
62
+ }
63
+ }
checks/class-generated-check.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check that the theme is not generated.
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check that the theme is not generated.
10
+ */
11
+ class Generated_Check 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
+ // Combine all the php files into one string to make it easier to search.
29
+ $php = implode( ' ', $php_files );
30
+
31
+ checkcount();
32
+
33
+ $ret = true;
34
+ if (
35
+ // Artisteer.
36
+ strpos( $php, 'art_normalize_widget_style_tokens' ) !== false
37
+ || strpos( $php, 'art_include_lib' ) !== false
38
+ || strpos( $php, '_remove_last_slash($url) {' ) !== false
39
+ || strpos( $php, 'adi_normalize_widget_style_tokens' ) !== false
40
+ || strpos( $php, 'm_normalize_widget_style_tokens' ) !== false
41
+ || strpos( $php, "bw = '<!--- BEGIN Widget --->';" ) !== false
42
+ || strpos( $php, "ew = '<!-- end_widget -->';" ) !== false
43
+ || strpos( $php, "end_widget' => '<!-- end_widget -->'" ) !== false
44
+ // Lubith.
45
+ || strpos( $php, 'Lubith' ) !== false
46
+ // Templatetoaster.
47
+ || strpos( $php, 'templatetoaster_' ) !== false
48
+ || strpos( $php, 'Templatetoaster_' ) !== false
49
+ || strpos( $php, '@package templatetoaster' ) !== false
50
+ // wpthemegenerator.
51
+ || strpos( $php, 'wptg_' ) !== false
52
+ ) {
53
+ $this->error[] = sprintf(
54
+ '<span class="tc-lead tc-required">%s</span>: %s',
55
+ __( 'REQUIRED', 'theme-check' ),
56
+ __( 'This theme appears to have been auto-generated. Generated themes are not allowed in the themes directory.', 'theme-check' )
57
+ );
58
+ $ret = false;
59
+ }
60
+
61
+ return $ret;
62
+ }
63
+
64
+ /**
65
+ * Get error messages from the checks.
66
+ *
67
+ * @return array Error message.
68
+ */
69
+ public function getError() {
70
+ return $this->error;
71
+ }
72
+ }
73
+
74
+ $themechecks[] = new Generated_Check();
checks/class-gravatar-check.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Checks that gravatars are supported in comments.
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Checks that gravatars are supported in comments.
10
+ */
11
+ class Gravatar_Check 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
+ $php = implode( ' ', $php_files );
29
+
30
+ checkcount();
31
+
32
+ if (
33
+ strpos( $php, 'get_avatar' ) === false &&
34
+ strpos( $php, 'wp_list_comments' ) === false
35
+ ) {
36
+ $this->error[] = sprintf(
37
+ '<span class="tc-lead tc-recommended">%s</span>: %s',
38
+ __( 'RECOMMENDED', 'theme-check' ),
39
+ __( "This theme doesn't seem to support the standard avatar functions. Use <strong>get_avatar</strong> or <strong>wp_list_comments</strong> to add this support.", 'theme-check' )
40
+ );
41
+ }
42
+
43
+ return true;
44
+ }
45
+
46
+ /**
47
+ * Get error messages from the checks.
48
+ *
49
+ * @return array Error message.
50
+ */
51
+ public function getError() {
52
+ return $this->error;
53
+ }
54
+ }
55
+
56
+ $themechecks[] = new Gravatar_Check();
checks/class-i18n-check.php ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check for various I18N errors
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check for various I18N errors.
10
+ */
11
+ class I18N_Check 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
+ $error = '';
29
+ checkcount();
30
+
31
+ // Make sure the tokenizer is available.
32
+ if ( ! function_exists( 'token_get_all' ) ) {
33
+ return true;
34
+ }
35
+
36
+ foreach ( $php_files as $php_key => $phpfile ) {
37
+ $error = '';
38
+
39
+ $stmts = array();
40
+ foreach ( array( '_e(', '__(', '_e (', '__ (' ) as $finder ) {
41
+ $search = $phpfile;
42
+ while ( ( $pos = strpos( $search, $finder ) ) !== false ) {
43
+ $search = substr( $search, $pos );
44
+ $open = 1;
45
+ $i = strpos( $search, '(' ) + 1;
46
+ while ( $open > 0 ) {
47
+ switch ( $search[ $i ] ) {
48
+ case '(':
49
+ $open++;
50
+ break;
51
+ case ')':
52
+ $open--;
53
+ break;
54
+ }
55
+ $i++;
56
+ }
57
+ $stmts[] = substr( $search, 0, $i );
58
+ $search = substr( $search, $i );
59
+ }
60
+ }
61
+
62
+ foreach ( $stmts as $match ) {
63
+ $tokens = token_get_all( '<?php ' . $match . ';' );
64
+ if ( ! empty( $tokens ) ) {
65
+ foreach ( $tokens as $token ) {
66
+ if ( is_array( $token ) && in_array( $token[0], array( T_VARIABLE ) ) ) {
67
+ $filename = tc_filename( $php_key );
68
+ $grep = tc_grep( ltrim( $match ), $php_key );
69
+ preg_match( '/[^\s]*\s[0-9]+/', $grep, $line );
70
+ $error = '';
71
+ if ( isset( $line[0] ) ) {
72
+ $error = ( ! strpos( $error, $line[0] ) ) ? $grep : '';
73
+ }
74
+ $this->error[] = sprintf(
75
+ '<span class="tc-lead tc-recommended">%s</span>: %s',
76
+ __( 'RECOMMENDED', 'theme-check' ),
77
+ sprintf(
78
+ __( 'Possible variable %1$s found in translation function in %2$s. Translation function calls must NOT contain PHP variables. %3$s', 'theme-check' ),
79
+ '<strong>' . $token[1] . '</strong>',
80
+ '<strong>' . $filename . '</strong>',
81
+ $error
82
+ )
83
+ );
84
+ break; // Stop looking at the tokens on this line once a variable is found.
85
+ }
86
+ }
87
+ }
88
+ }
89
+ }
90
+ return $ret;
91
+ }
92
+
93
+ /**
94
+ * Get error messages from the checks.
95
+ *
96
+ * @return array Error message.
97
+ */
98
+ public function getError() {
99
+ return $this->error;
100
+ }
101
+ }
102
+
103
+ $themechecks[] = new I18N_Check();
checks/class-iframe-check.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check if iframes are used
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check if iframes are used.
10
+ *
11
+ * Check if iframes are used. if they are, inform that the content need to be manually checked.
12
+ */
13
+ class Iframe_Check implements themecheck {
14
+ /**
15
+ * Error messages, warnings and info notices.
16
+ *
17
+ * @var array $error
18
+ */
19
+ protected $error = array();
20
+
21
+ /**
22
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
23
+ *
24
+ * @param array $php_files File paths and content for PHP files.
25
+ * @param array $css_files File paths and content for CSS files.
26
+ * @param array $other_files Folder names, file paths and content for other files.
27
+ */
28
+ public function check( $php_files, $css_files, $other_files ) {
29
+ $ret = true;
30
+
31
+ $checks = array(
32
+ '/<(iframe)[^>]*>/' => __( 'iframes are sometimes used to load unwanted adverts and code on your site', 'theme-check' ),
33
+ );
34
+
35
+ foreach ( $php_files as $php_key => $phpfile ) {
36
+ foreach ( $checks as $key => $check ) {
37
+ checkcount();
38
+ if ( preg_match( $key, $phpfile, $matches ) ) {
39
+ $filename = tc_filename( $php_key );
40
+ $error = ltrim( $matches[1], '(' );
41
+ $error = rtrim( $error, '(' );
42
+ $grep = tc_grep( $error, $php_key );
43
+ $this->error[] = sprintf(
44
+ '<span class="tc-lead tc-info">%s</span>: %s %s',
45
+ __( 'INFO', 'theme-check' ),
46
+ sprintf(
47
+ __( '%1$s was found in the file %2$s %3$s.', 'theme-check' ),
48
+ '<strong>' . $error . '</strong>',
49
+ '<strong>' . $filename . '</strong>',
50
+ $check
51
+ ),
52
+ $grep
53
+ );
54
+ }
55
+ }
56
+ }
57
+ return $ret;
58
+ }
59
+
60
+ /**
61
+ * Get error messages from the checks.
62
+ *
63
+ * @return array Error message.
64
+ */
65
+ public function getError() {
66
+ return $this->error;
67
+ }
68
+ }
69
+
70
+ $themechecks[] = new Iframe_Check();
checks/class-include-check.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check if include or required is used.
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check if include or required is used.
10
+ *
11
+ * Check if include or required is used. If they are, inform that they should not be used for templates.
12
+ */
13
+ class Include_Check implements themecheck {
14
+ /**
15
+ * Error messages, warnings and info notices.
16
+ *
17
+ * @var array $error
18
+ */
19
+ protected $error = array();
20
+
21
+ /**
22
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
23
+ *
24
+ * @param array $php_files File paths and content for PHP files.
25
+ * @param array $css_files File paths and content for CSS files.
26
+ * @param array $other_files Folder names, file paths and content for other files.
27
+ */
28
+ public function check( $php_files, $css_files, $other_files ) {
29
+ $checks = array(
30
+ '/(?<![a-z0-9_\'"])(?:require|include)(?:_once)?\s?[\'"\(]/i' => __( 'The theme appears to use include or require. If these are being used to include separate sections of a template from independent files, then <strong>get_template_part()</strong> should be used instead.', 'theme-check' ),
31
+ );
32
+
33
+ foreach ( $php_files as $file_path => $file_content ) {
34
+ foreach ( $checks as $check_regex => $check ) {
35
+ checkcount();
36
+
37
+ $filename = tc_filename( $file_path );
38
+ // This doesn't apply to functions.php.
39
+ if ( $filename === 'functions.php' ) {
40
+ continue;
41
+ }
42
+
43
+ if ( preg_match( $check_regex, $file_content, $matches ) ) {
44
+ $grep = tc_preg( '/(?<![a-z0-9_\'"])(?:require|include)(?:_once)?\s?[\'"\(]/i', $file_path );
45
+ $this->error[] = sprintf(
46
+ '<span class="tc-lead tc-info">%s</span>: <strong>%s</strong> %s %s',
47
+ __( 'INFO', 'theme-check' ),
48
+ $filename,
49
+ $check,
50
+ $grep
51
+ );
52
+ }
53
+ }
54
+ }
55
+
56
+ return true;
57
+ }
58
+
59
+ /**
60
+ * Get error messages from the checks.
61
+ *
62
+ * @return array Error message.
63
+ */
64
+ public function getError() {
65
+ return $this->error;
66
+ }
67
+ }
68
+
69
+ $themechecks[] = new Include_Check();
checks/class-included-zip-check.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check if zip files are included
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check if zip files are included.
10
+ */
11
+ class Included_Zip_Check 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
+
29
+ $filenames = array();
30
+
31
+ foreach ( $other_files as $other_key => $otherfile ) {
32
+ array_push( $filenames, strtolower( basename( $other_key ) ) );
33
+ }
34
+
35
+ $blocklist = array(
36
+ '\.zip' => __( 'Zipped Plugin', 'theme-check' ),
37
+ );
38
+
39
+ checkcount();
40
+
41
+ foreach ( $blocklist as $file => $reason ) {
42
+ if ( $filename = preg_grep( '/' . $file . '/', $filenames ) ) {
43
+ $error = implode( ' ', array_unique( $filename ) );
44
+ $this->error[] = sprintf(
45
+ '<span class="tc-lead tc-required">%s</span>: %s',
46
+ __( 'REQUIRED', 'theme-check' ),
47
+ sprintf(
48
+ __( '<strong>Zip file found.</strong> Plugins are not allowed in themes. The zip file found was <em>%s</em>.', 'theme-check' ),
49
+ $error
50
+ )
51
+ );
52
+ $ret = false;
53
+ }
54
+ }
55
+
56
+ return $ret;
57
+ }
58
+
59
+ /**
60
+ * Get error messages from the checks.
61
+ *
62
+ * @return array Error message.
63
+ */
64
+ public function getError() {
65
+ return $this->error;
66
+ }
67
+ }
68
+
69
+ $themechecks[] = new Included_Zip_Check();
checks/class-line-endings-check.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check if more than one line ending style is used.
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check if more than one line ending style is used.
10
+ */
11
+ class Line_Endings_Check 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
+ foreach ( $php_files as $php_key => $phpfile ) {
29
+ if ( preg_match( "/\r\n/", $phpfile ) ) {
30
+ if ( preg_match( "/[^\r]\n/", $phpfile ) ) {
31
+ $filename = tc_filename( $php_key );
32
+ $this->error[] = sprintf(
33
+ '<span class="tc-lead tc-required">%s</span>: %s',
34
+ __( 'REQUIRED', 'theme-check' ),
35
+ sprintf(
36
+ __( 'Both DOS and UNIX style line endings were found in the file %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' ),
37
+ '<strong>' . $filename . '</strong>'
38
+ )
39
+ );
40
+ $ret = false;
41
+ }
42
+ }
43
+ }
44
+ foreach ( $css_files as $css_key => $cssfile ) {
45
+ if ( preg_match( "/\r\n/", $cssfile ) ) {
46
+ if ( preg_match( "/[^\r]\n/", $cssfile ) ) {
47
+ $filename = tc_filename( $css_key );
48
+ $this->error[] = sprintf(
49
+ '<span class="tc-lead tc-required">%s</span>: %s',
50
+ __( 'REQUIRED', 'theme-check' ),
51
+ sprintf(
52
+ __( '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' ),
53
+ '<strong>' . $filename . '</strong>'
54
+ )
55
+ );
56
+ $ret = false;
57
+ }
58
+ }
59
+ }
60
+ foreach ( $other_files as $oth_key => $othfile ) {
61
+ $e = pathinfo( $oth_key );
62
+ if ( isset( $e['extension'] ) && in_array( $e['extension'], array( 'txt', 'js' ) ) ) {
63
+ if ( preg_match( "/\r\n/", $othfile ) ) {
64
+ if ( preg_match( "/[^\r]\n/", $othfile ) ) {
65
+ $filename = tc_filename( $oth_key );
66
+ $this->error[] = sprintf(
67
+ '<span class="tc-lead tc-required">%s</span>: %s',
68
+ __( 'REQUIRED', 'theme-check' ),
69
+ sprintf(
70
+ __( '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' ),
71
+ '<strong>' . $filename . '</strong>'
72
+ )
73
+ );
74
+ $ret = false;
75
+ }
76
+ }
77
+ }
78
+ }
79
+ return $ret;
80
+ }
81
+
82
+ /**
83
+ * Get error messages from the checks.
84
+ *
85
+ * @return array Error message.
86
+ */
87
+ public function getError() {
88
+ return $this->error;
89
+ }
90
+ }
91
+
92
+ $themechecks[] = new Line_Endings_Check();
checks/class-link-check.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check if there are hard-coded links
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check if there are hard-coded links
10
+ *
11
+ * Check if there are hard-coded links other than theme or author URI.
12
+ */
13
+ class Link_Check implements themecheck {
14
+ /**
15
+ * Error messages, warnings and info notices.
16
+ *
17
+ * @var array $error
18
+ */
19
+ protected $error = array();
20
+
21
+ /**
22
+ * Theme information. Author URI, theme URI, Author name
23
+ *
24
+ * @var object $theme
25
+ */
26
+ protected $theme;
27
+
28
+ function set_context( $data ) {
29
+ if ( isset( $data['theme'] ) ) {
30
+ $this->theme = $data['theme'];
31
+ }
32
+ }
33
+
34
+ /**
35
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
36
+ *
37
+ * @param array $php_files File paths and content for PHP files.
38
+ * @param array $css_files File paths and content for CSS files.
39
+ * @param array $other_files Folder names, file paths and content for other files.
40
+ */
41
+ public function check( $php_files, $css_files, $other_files ) {
42
+
43
+ foreach ( $php_files as $php_key => $phpfile ) {
44
+ checkcount();
45
+ $grep = '';
46
+ // Regex borrowed from TAC.
47
+ $url_re = '([[:alnum:]\-\.])+(\\.)([[:alnum:]]){2,4}([[:blank:][:alnum:]\/\+\=\%\&\_\\\.\~\?\-]*)';
48
+ $title_re = '[[:blank:][:alnum:][:punct:]]*'; // 0 or more: any num, letter(upper/lower) or any punc symbol.
49
+ $space_re = '(\\s*)';
50
+ if ( preg_match_all( '/(<a)(\\s+)(href' . $space_re . '=' . $space_re . '"' . $space_re . '((http|https|ftp):\\/\\/)?)' . $url_re . '("' . $space_re . $title_re . $space_re . '>)' . $title_re . '(<\\/a>)/is', $phpfile, $out, PREG_SET_ORDER ) ) {
51
+ $filename = tc_filename( $php_key );
52
+ foreach ( $out as $key ) {
53
+ if ( preg_match( '/\<a\s?href\s?=\s?["|\'](.*?)[\'|"](.*?)\>(.*?)\<\/a\>/is', $key[0], $stripped ) ) {
54
+ if (
55
+ ! empty( $this->theme->get( 'AuthorURI' ) ) &&
56
+ ! empty( $this->theme->get( 'ThemeURI' ) ) &&
57
+ $stripped[1] &&
58
+ ! strpos( $stripped[1], $this->theme->get( 'ThemeURI' ) ) &&
59
+ ! strpos( $stripped[1], $this->theme->get( 'AuthorURI' ) ) &&
60
+ ! stripos( $stripped[1], 'WordPress.' )
61
+ ) {
62
+ $grep .= tc_grep( $stripped[1], $php_key );
63
+ }
64
+ }
65
+ }
66
+ if ( $grep ) {
67
+ $this->error[] = sprintf(
68
+ '<span class="tc-lead tc-info">%s</span>: %s %s',
69
+ __( 'INFO', 'theme-check' ),
70
+ sprintf(
71
+ __( 'Possible hard-coded links were found in the file %s.', 'theme-check' ),
72
+ '<strong>' . $filename . '</strong>'
73
+ ),
74
+ $grep
75
+ );
76
+ }
77
+ }
78
+ }
79
+
80
+ return true;
81
+ }
82
+
83
+ /**
84
+ * Get error messages from the checks.
85
+ *
86
+ * @return array Error message.
87
+ */
88
+ public function getError() {
89
+ return $this->error;
90
+ }
91
+ }
92
+
93
+ $themechecks[] = new Link_Check();
checks/class-nav-menu-check.php ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Checks if nav menus are supported and if theme location or menu names are used
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Checks if nav menus are supported and if theme location or menu names are used.
10
+ */
11
+ class Nav_Menu_Check 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
+ $name_check = false;
30
+
31
+ $php = implode( ' ', $php_files );
32
+
33
+ checkcount();
34
+ if ( strpos( $php, 'nav_menu' ) === false ) {
35
+ $this->error[] = sprintf(
36
+ '<span class="tc-lead tc-recommended">%s</span>: %s',
37
+ __( 'RECOMMENDED', 'theme-check' ),
38
+ __( "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' )
39
+ );
40
+ }
41
+
42
+ // Look for add_theme_support( 'menus' ).
43
+ checkcount();
44
+ if ( preg_match( '/add_theme_support\s*\(\s?("|\')menus("|\')\s?\)/', $php ) ) {
45
+ /* translators: 1: function found, 2: function to be used */
46
+ $this->error[] = sprintf(
47
+ '<span class="tc-lead tc-required">%s</span>: %s',
48
+ __( 'REQUIRED', 'theme-check' ),
49
+ sprintf(
50
+ __( 'Reference to %1$s was found in the theme. This should be removed and %2$s used instead.', 'theme-check' ),
51
+ '<strong>add_theme_support( "menus" )</strong>',
52
+ '<a href="https://developer.wordpress.org/reference/functions/register_nav_menus/">register_nav_menus()</a>'
53
+ )
54
+ );
55
+ $ret = false;
56
+ }
57
+
58
+ foreach ( $php_files as $file_path => $file_content ) {
59
+ $filename = tc_filename( $file_path );
60
+
61
+ // We are checking for wp_nav_menu( specifically, to allow wp_nav_menu and wp_nav_menu_item in filters etc.
62
+ if ( strpos( $file_content, 'wp_nav_menu(' ) !== false ) {
63
+ $menu_part = explode( 'wp_nav_menu(', $file_content );
64
+ $menu_part = explode( ';', $menu_part[1] );
65
+
66
+ // If there is a menu, check for a theme location, which is required.
67
+ // Check if the arguments are placed outside wp_nav_menu.
68
+ checkcount();
69
+ if ( strpos( $menu_part[0], '$' ) !== false && strpos( $menu_part[0], 'theme_location' ) === false ) {
70
+ $menu_args = explode( '$', $menu_part[0], 1 );
71
+ $name = explode( ')', $menu_args[0] );
72
+ $this->error[] = sprintf(
73
+ '<span class="tc-lead tc-warning">%s</span>: %s',
74
+ __( 'WARNING', 'theme-check' ),
75
+ sprintf(
76
+ __( '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' ),
77
+ '<strong>' . $filename . '</strong>',
78
+ '<code>' . $name[0] . '</code>'
79
+ )
80
+ );
81
+ $name_check = true;
82
+ } else {
83
+ checkcount();
84
+ if ( strpos( $menu_part[0], 'theme_location' ) === false ) {
85
+ $this->error[] = sprintf(
86
+ '<span class="tc-lead tc-required">%s</span>: %s',
87
+ __( 'REQUIRED', 'theme-check' ),
88
+ sprintf(
89
+ __( 'A menu without a theme_location was found in %1$s.', 'theme-check' ),
90
+ '<strong>' . $filename . '</strong>'
91
+ )
92
+ );
93
+ $ret = false;
94
+ $name_check = true;
95
+ }
96
+ }
97
+
98
+ // We only need to warn for the menu name if theme location is not set.
99
+ checkcount();
100
+ if ( $name_check === true && preg_match( '/("|\')menu("|\').*?=>/', $menu_part[0] ) ) {
101
+ $this->error[] = sprintf(
102
+ '<span class="tc-lead tc-required">%s</span>: %s',
103
+ __( 'REQUIRED', 'theme-check' ),
104
+ sprintf(
105
+ __( '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' ),
106
+ '<strong>' . $filename . '</strong>'
107
+ )
108
+ );
109
+ $ret = false;
110
+ }
111
+ }
112
+ }
113
+
114
+ return $ret;
115
+ }
116
+
117
+ /**
118
+ * Get error messages from the checks.
119
+ *
120
+ * @return array Error message.
121
+ */
122
+ public function getError() {
123
+ return $this->error;
124
+ }
125
+ }
126
+
127
+ $themechecks[] = new Nav_Menu_Check();
checks/class-no-hidden-admin-bar-check.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Checks if the admin bar gets hidden by the theme
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Checks if the admin bar gets hidden by the theme.
10
+ */
11
+ class No_Hidden_Admin_Bar_Check 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
+ $php_regex = "/(add_filter(\s*)\((\s*)(\"|')show_admin_bar(\"|')(\s*)(.*))|(([^\S])show_admin_bar(\s*)\((.*))/";
29
+ $css_regex = '/(#wpadminbar)/';
30
+
31
+ checkcount();
32
+ // Check php files for filter show_admin_bar, show_admin_bar_front, and show_admin_bar().
33
+ foreach ( $php_files as $file_path => $file_content ) {
34
+
35
+ if ( preg_match( $php_regex, $file_content, $matches ) ) {
36
+ $grep = tc_preg( '/show_admin_bar/', $file_path );
37
+ $this->error[] = sprintf(
38
+ '<span class="tc-lead tc-warning">%s</span>: %s %s',
39
+ __( 'WARNING', 'theme-check' ),
40
+ sprintf(
41
+ __( '%1$s Themes are not allowed to hide the admin bar. This warning must be manually checked.', 'theme-check' ),
42
+ '<strong>' . tc_filename( $file_path ) . '</strong>'
43
+ ),
44
+ $grep
45
+ );
46
+ }
47
+ }
48
+
49
+ checkcount();
50
+ // Check CSS Files for #wpadminbar.
51
+ foreach ( $css_files as $file_path => $file_content ) {
52
+
53
+ // Don't print minified files.
54
+ if ( strpos( $file_path, '.min.' ) === false ) {
55
+ $grep = tc_preg( '/#wpadminbar/', $file_path );
56
+ } else {
57
+ $grep = '';
58
+ }
59
+
60
+ if ( preg_match( $css_regex, $file_content, $matches ) ) {
61
+ $this->error[] = sprintf(
62
+ '<span class="tc-lead tc-warning">%s</span>: %s %s',
63
+ __( 'WARNING', 'theme-check' ),
64
+ sprintf(
65
+ __( 'The theme is using `#wpadminbar` in %1$s. Hiding the admin bar is not allowed. This warning must be manually checked.', 'theme-check' ),
66
+ '<strong>' . tc_filename( $file_path ) . '</strong>'
67
+ ),
68
+ $grep
69
+ );
70
+ }
71
+ }
72
+
73
+ return true;
74
+ }
75
+
76
+ /**
77
+ * Get error messages from the checks.
78
+ *
79
+ * @return array Error message.
80
+ */
81
+ public function getError() {
82
+ return $this->error;
83
+ }
84
+ }
85
+
86
+ $themechecks[] = new No_Hidden_Admin_Bar_Check();
checks/class-non-gpl-check.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Checks if the theme includes resoruces from websites that does not use a GPL compatible license.
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Checks if the theme includes resoruces from websites that does not use a GPL compatible license.
10
+ */
11
+ class Non_GPL_Check 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
+ $code = implode( ' ', $other_files ); // The references are usually in the readme.
30
+
31
+ checkcount();
32
+
33
+ $link_list = array(
34
+ 'unsplash.com' => 'https://unsplash.com/license',
35
+ 'pixabay' => 'https://pixabay.com/service/license/',
36
+ 'freeimages' => 'https://www.freeimages.com/license',
37
+ 'photopin' => 'https://www.vecteezy.com/licensing-agreement',
38
+ 'vecteezy' => 'https://www.vecteezy.com/licensing-agreement',
39
+ 'splitshire' => 'https://www.splitshire.com/licence/',
40
+ 'freepik' => 'https://www.freepikcompany.com/legal',
41
+ 'flaticon' => 'https://www.freepikcompany.com/legal',
42
+ 'pikwizard' => 'https://pikwizard.com/standard-license',
43
+ 'stock.adobe' => 'https://stock.adobe.com/license-terms',
44
+ 'elements.envato' => 'https://elements.envato.com/license-terms',
45
+ 'undraw.co' => 'https://undraw.co/license',
46
+ );
47
+
48
+ foreach ( $link_list as $link_slug => $link_url ) {
49
+ if ( false !== stripos( $code, $link_slug ) ) {
50
+ $this->error[] = sprintf(
51
+ '<span class="tc-lead tc-required">%s</span>: %s %s',
52
+ __( 'REQUIRED', 'theme-check' ),
53
+ sprintf(
54
+ __( 'Found a reference to %s. Assets from this website does not use a license that is compatible with GPL.', 'theme-check' ),
55
+ '<code>' . esc_html( $link_slug ) . '</code>'
56
+ ),
57
+ '<a href="' . esc_url( $link_url ) . '" target="_blank">' . __( 'View license (opens in a new window).', 'theme-check' ) . '</a>'
58
+ );
59
+ }
60
+ }
61
+
62
+ return $ret;
63
+ }
64
+
65
+ /**
66
+ * Get error messages from the checks.
67
+ *
68
+ * @return array Error message.
69
+ */
70
+ public function getError() {
71
+ return $this->error;
72
+ }
73
+ }
74
+
75
+ $themechecks[] = new Non_GPL_Check();
checks/class-non-printable-check.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check if non-printable characters are included
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check if non-printable characters are included.
10
+ */
11
+ class Non_Printable_Check 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
+ foreach ( $php_files as $file_path => $file_content ) {
29
+ checkcount();
30
+
31
+ // 09 = tab.
32
+ // 0A = line feed.
33
+ // 0D = new line.
34
+ if ( preg_match( '/[\x00-\x08\x0B-\x0C\x0E-\x1F]/', $file_content, $matches ) ) {
35
+ $grep = tc_preg( '/[\x00-\x08\x0B-\x0C\x0E-\x1F]/', $file_path );
36
+ $this->error[] = sprintf(
37
+ '<span class="tc-lead tc-warning">%s</span>: %s %s',
38
+ __( 'WARNING', 'theme-check' ),
39
+ sprintf(
40
+ __( 'Non-printable characters were found in the %s file. You may want to check this file for errors.', 'theme-check' ),
41
+ '<strong>' . tc_filename( $file_path ) . '</strong>'
42
+ ),
43
+ $grep
44
+ );
45
+ }
46
+ }
47
+
48
+ return true;
49
+ }
50
+
51
+ /**
52
+ * Get error messages from the checks.
53
+ *
54
+ * @return array Error message.
55
+ */
56
+ public function getError() {
57
+ return $this->error;
58
+ }
59
+ }
60
+
61
+ $themechecks[] = new Non_Printable_Check();
checks/class-php-short-tags-check.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check if PHP short tags are used
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check if PHP short tags are used.
10
+ */
11
+ class PHP_Short_Tags_Check 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
+ foreach ( $php_files as $file_path => $file_content ) {
29
+ checkcount();
30
+
31
+ if ( preg_match( '/<\?(\=?)(?!php|xml)/i', $file_content ) ) {
32
+ $grep = tc_preg( '/<\?(\=?)(?!php|xml)/', $file_path );
33
+ $this->error[] = sprintf(
34
+ '<span class="tc-lead tc-warning">%s</span>: %s %s',
35
+ __( 'WARNING', 'theme-check' ),
36
+ sprintf(
37
+ __( 'Found PHP short tags in file %s.', 'theme-check' ),
38
+ '<strong>' . tc_filename( $file_path ) . '</strong>'
39
+ ),
40
+ $grep
41
+ );
42
+ }
43
+ }
44
+
45
+ return true;
46
+ }
47
+
48
+ /**
49
+ * Get error messages from the checks.
50
+ *
51
+ * @return array Error message.
52
+ */
53
+ public function getError() {
54
+ return $this->error;
55
+ }
56
+ }
57
+
58
+ $themechecks[] = new PHP_Short_Tags_Check();
checks/{plugin-territory.php → class-plugin-territory-check.php} RENAMED
@@ -1,14 +1,16 @@
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
  *
@@ -38,7 +40,14 @@ class Plugin_Territory implements themecheck {
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
  }
@@ -46,7 +55,14 @@ class Plugin_Territory implements themecheck {
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
 
@@ -66,7 +82,15 @@ class Plugin_Territory implements themecheck {
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
  }
@@ -96,7 +120,7 @@ class Plugin_Territory implements themecheck {
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/
@@ -112,9 +136,14 @@ class Plugin_Territory implements themecheck {
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
  }
@@ -134,4 +163,4 @@ class Plugin_Territory implements themecheck {
134
  }
135
  }
136
 
137
- $themechecks[] = new Plugin_Territory();
1
+ <?php
2
  /**
3
  * Checks for Plugin Territory Guidelines.
4
  *
5
  * @link https://make.wordpress.org/themes/handbook/review/required/#presentation-vs-functionality
6
+ *
7
+ * @package Theme Check
8
  */
9
 
10
  /**
11
  * Checks for Plugin Territory
12
  */
13
+ class Plugin_Territory_Check implements themecheck {
14
  /**
15
  * Error messages, warnings and info notices.
16
  *
40
  foreach ( $forbidden_functions as $function ) {
41
  checkcount();
42
  if ( preg_match( '/[\s?]' . $function . '\s?\(/', $php ) ) {
43
+ $this->error[] = sprintf(
44
+ '<span class="tc-lead tc-required">%s</span> %s',
45
+ __( 'REQUIRED', 'theme-check' ),
46
+ sprintf(
47
+ __( 'The theme uses the %s function, which is plugin-territory functionality.', 'theme-check' ),
48
+ '<strong>' . esc_html( $function ) . '()</strong>'
49
+ )
50
+ );
51
  $ret = false;
52
  }
53
  }
55
  // Shortcodes can't be used in the post content, so warn about them.
56
  if ( false !== strpos( $php, 'add_shortcode(' ) ) {
57
  checkcount();
58
+ $this->error[] = sprintf(
59
+ '<span class="tc-lead tc-required">%s</span> %s',
60
+ __( 'REQUIRED', 'theme-check' ),
61
+ sprintf(
62
+ __( 'The theme uses the %s function. Custom post-content shortcodes are plugin-territory functionality.', 'theme-check' ),
63
+ '<strong>add_shortcode()</strong>'
64
+ )
65
+ );
66
  $ret = false;
67
  }
68
 
82
  foreach ( $hooks as $hook ) {
83
  checkcount();
84
  if ( preg_match( '/[\s?]add_' . $type . '\s*\(\s*([\'"])' . $hook . '([\'"])\s*,/', $php ) ) {
85
+ $this->error[] = sprintf(
86
+ '<span class="tc-lead tc-required">%s</span>: %s',
87
+ __( 'REQUIRED', 'theme-check' ),
88
+ sprintf(
89
+ __( 'The theme uses the %1$s %2$s, which is plugin-territory functionality.', 'theme-check' ),
90
+ '<strong>' . esc_html( $hook ) . '</strong>',
91
+ esc_html( $type )
92
+ )
93
+ );
94
  $ret = false;
95
  }
96
  }
120
  'print_emoji_styles', // @link https://developer.wordpress.org/reference/functions/print_emoji_styles/
121
  ),
122
  'admin_print_scripts' => array(
123
+ 'print_emoji_detection_script', // @link https://developer.wordpress.org/reference/functions/print_emoji_detection_script/
124
  ),
125
  'admin_print_styles' => array(
126
  'print_emoji_styles', // @link https://developer.wordpress.org/reference/functions/print_emoji_styles/
136
  foreach ( $functions as $function ) {
137
  checkcount();
138
  if ( preg_match( '/[\s?]remove_action\s*\(\s*([\'"])' . $hook . '([\'"])\s*,\s*([\'"])' . $function . '([\'"])/', $php ) ) {
139
+ $this->error[] = sprintf(
140
+ '<span class="tc-lead tc-required">%s</span> %s',
141
+ __( 'REQUIRED', 'theme-check' ),
142
+ sprintf(
143
+ __( 'The theme uses <strong>remove_action %1$s %2$s</strong>, which is plugin-territory functionality.', 'theme-check' ),
144
+ esc_html( $hook ),
145
+ esc_html( $function )
146
+ )
147
  );
148
  $ret = false;
149
  }
163
  }
164
  }
165
 
166
+ $themechecks[] = new Plugin_Territory_Check();
checks/class-post-format-check.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check if post formats are supported
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check if post formats are supported.
10
+ */
11
+ class Post_Format_Check 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
+ $php = implode( ' ', $php_files );
29
+ $css = implode( ' ', $css_files );
30
+
31
+ checkcount();
32
+
33
+ $checks = array(
34
+ '/add_theme_support\(\s?("|\')post-formats("|\')/m',
35
+ );
36
+
37
+ foreach ( $php_files as $php_key => $phpfile ) {
38
+ foreach ( $checks as $check ) {
39
+ checkcount();
40
+ if ( preg_match( $check, $phpfile, $matches ) ) {
41
+ if (
42
+ ! strpos( $php, 'get_post_format' ) &&
43
+ ! strpos( $php, 'has_post_format' ) &&
44
+ ! strpos( $css, '.format' )
45
+ ) {
46
+ $filename = tc_filename( $php_key );
47
+ $matches[0] = str_replace( array( '"', "'" ), '', $matches[0] );
48
+ $error = esc_html( rtrim( $matches[0], '(' ) );
49
+ $grep = tc_grep( rtrim( $matches[0], '(' ), $php_key );
50
+ $this->error[] = sprintf(
51
+ '<span class="tc-lead tc-info">%s</span> %s',
52
+ __( 'INFO', 'theme-check' ),
53
+ sprintf(
54
+ __( '%1$s was found in the file %2$s. However get_post_format and/or has_post_format were not found, and no use of formats in the CSS was detected.', 'theme-check' ),
55
+ '<strong>' . $error . '</strong>',
56
+ '<strong>' . $filename . '</strong>'
57
+ )
58
+ );
59
+ }
60
+ }
61
+ }
62
+ }
63
+
64
+ return true;
65
+ }
66
+
67
+ /**
68
+ * Get error messages from the checks.
69
+ *
70
+ * @return array Error message.
71
+ */
72
+ public function getError() {
73
+ return $this->error;
74
+ }
75
+ }
76
+
77
+ $themechecks[] = new Post_Format_Check();
checks/class-post-pagination-check.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check if post pagination and navigation is supported
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check if post pagination and navigation is supported
10
+ */
11
+ class Post_Pagination_Check 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
+ // Combine all the php files into one string to make it easier to search.
29
+ $php = implode( ' ', $php_files );
30
+ checkcount();
31
+ if (
32
+ strpos( $php, 'posts_nav_link' ) === false &&
33
+ strpos( $php, 'paginate_links' ) === false &&
34
+ strpos( $php, 'the_posts_pagination' ) === false &&
35
+ strpos( $php, 'the_posts_navigation' ) === false &&
36
+ (
37
+ strpos( $php, 'previous_posts_link' ) === false &&
38
+ strpos( $php, 'next_posts_link' ) === false
39
+ )
40
+ ) {
41
+ $this->error[] = sprintf(
42
+ '<span class="tc-lead tc-recommended">%s</span> %s',
43
+ __( 'RECOMMENDED', 'theme-check' ),
44
+ __( "The theme doesn't have post pagination code in it. Use <strong>posts_nav_link()</strong> or <strong>paginate_links()</strong> or <strong>the_posts_pagination()</strong> or <strong>the_posts_navigation()</strong> or <strong>next_posts_link()</strong> and <strong>previous_posts_link()</strong> to add post pagination.", 'theme-check' )
45
+ );
46
+ }
47
+
48
+ return true;
49
+ }
50
+
51
+ /**
52
+ * Get error messages from the checks.
53
+ *
54
+ * @return array Error message.
55
+ */
56
+ public function getError() {
57
+ return $this->error;
58
+ }
59
+ }
60
+ $themechecks[] = new Post_Pagination_Check();
checks/class-post-thumbnail-check.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check if post thumbnails are supported
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check if post thumbnails are supported
10
+ */
11
+ class Post_Thumbnail_Check 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
+ // Combine all the php files into one string to make it easier to search.
31
+ $php = implode( ' ', $php_files );
32
+ checkcount();
33
+
34
+ if ( strpos( $php, 'the_post_thumbnail' ) === false ) {
35
+ $this->error[] = sprintf(
36
+ '<span class="tc-lead tc-recommended">%s</span> %s',
37
+ __( 'RECOMMENDED', 'theme-check' ),
38
+ __( 'No reference to <strong>the_post_thumbnail()</strong> was found in the theme. It is recommended that the theme implement this functionality instead of using custom fields for thumbnails.', 'theme-check' )
39
+ );
40
+ }
41
+
42
+ if ( strpos( $php, 'post-thumbnails' ) === false ) {
43
+ $this->error[] = sprintf(
44
+ '<span class="tc-lead tc-recommended">%s</span> %s',
45
+ __( 'RECOMMENDED', 'theme-check' ),
46
+ __( 'No reference to post-thumbnails was found in the theme. If the theme has a thumbnail like functionality, it should be implemented with <strong>add_theme_support( "post-thumbnails" )</strong> in the functions.php file.', 'theme-check' )
47
+ );
48
+ }
49
+
50
+ return $ret;
51
+ }
52
+
53
+ /**
54
+ * Get error messages from the checks.
55
+ *
56
+ * @return array Error message.
57
+ */
58
+ public function getError() {
59
+ return $this->error;
60
+ }
61
+ }
62
+
63
+ $themechecks[] = new Post_Thumbnail_Check();
checks/class-screen-reader-text-check.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check if the screen-reader-text class is included
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check if the screen-reader-text class is included.
10
+ */
11
+ class Screen_Reader_Text_Check 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
+ $css = implode( ' ', $css_files );
29
+ $ret = true;
30
+
31
+ $checks = array(
32
+ '\.screen-reader-text' => __( '<strong>.screen-reader-text</strong> CSS class is generated by WordPress and needs to be styled with your theme CSS. See <a href="http://codex.wordpress.org/CSS#WordPress_Generated_Classes">the Codex</a> for an example implementation.', 'theme-check' ),
33
+ );
34
+
35
+ foreach ( $checks as $key => $check ) {
36
+ checkcount();
37
+ if ( ! preg_match( '/' . $key . '/i', $css, $matches ) ) {
38
+ $this->error[] = sprintf(
39
+ '<span class="tc-lead tc-required">%s</span> %s',
40
+ __( 'REQUIRED', 'theme-check' ),
41
+ $check
42
+ );
43
+ $ret = false;
44
+ }
45
+ }
46
+
47
+ return $ret;
48
+ }
49
+
50
+ /**
51
+ * Get error messages from the checks.
52
+ *
53
+ * @return array Error message.
54
+ */
55
+ public function getError() {
56
+ return $this->error;
57
+ }
58
+ }
59
+
60
+ $themechecks[] = new Screen_Reader_Text_Check();
checks/class-screenshot-check.php ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check if the screenshot size is correct
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check if the screenshot size is correct.
10
+ */
11
+ class Screenshot_Check 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
+ $filenames = array();
30
+
31
+ foreach ( $other_files as $other_key => $otherfile ) {
32
+ array_push( $filenames, strtolower( basename( $other_key ) ) );
33
+ }
34
+
35
+ checkcount();
36
+
37
+ if (
38
+ in_array( 'screenshot.png', $filenames ) ||
39
+ in_array( 'screenshot.jpg', $filenames )
40
+ ) {
41
+
42
+ foreach ( $other_files as $other_key => $otherfile ) {
43
+
44
+ if (
45
+ (
46
+ basename( $other_key ) === 'screenshot.png' ||
47
+ basename( $other_key ) === 'screenshot.jpg'
48
+ ) &&
49
+ preg_match( '/.*themes\/[^\/]*\/screenshot\.(png|jpg)/', $other_key )
50
+ ) {
51
+ // we have our screenshot!
52
+ $image = getimagesize( $other_key );
53
+ if ( $image[0] > 1200 || $image[1] > 900 ) {
54
+ $this->error[] = sprintf(
55
+ '<span class="tc-lead tc-required">%s</span> %s',
56
+ __( 'REQUIRED', 'theme-check' ),
57
+ sprintf(
58
+ __( 'Screenshot is wrong size! Detected: %s. Maximum allowed size is 1200x900px.', 'theme-check' ),
59
+ '<strong>' . $image[0] . 'x' . $image[1] . '</strong>'
60
+ )
61
+ );
62
+ $ret = false;
63
+ }
64
+ if ( $image[1] / $image[0] != 0.75 ) {
65
+ $this->error[] = sprintf(
66
+ '<span class="tc-lead tc-required">%s</span> %s',
67
+ __( 'REQUIRED', 'theme-check' ),
68
+ __( 'Screenshot dimensions are wrong! Ratio of width to height should be 4:3.', 'theme-check' )
69
+ );
70
+ $ret = false;
71
+ }
72
+ if ( $image[0] != 1200 || $image[1] != 900 ) {
73
+ $this->error[] = sprintf(
74
+ '<span class="tc-lead tc-recommended">%s</span> %s',
75
+ __( 'RECOMMENDED', 'theme-check' ),
76
+ __( 'Screenshot size should be 1200x900, to account for HiDPI displays. Any 4:3 image size is acceptable, but 1200x900 is preferred.', 'theme-check' )
77
+ );
78
+ }
79
+ }
80
+ }
81
+ } else {
82
+ $this->error[] = sprintf(
83
+ '<span class="tc-lead tc-required">%s</span> %s',
84
+ __( 'REQUIRED', 'theme-check' ),
85
+ __( 'No screenshot detected! Please include a screenshot.png or screenshot.jpg.', 'theme-check' )
86
+ );
87
+ $ret = false;
88
+ }
89
+ return $ret;
90
+ }
91
+
92
+ /**
93
+ * Get error messages from the checks.
94
+ *
95
+ * @return array Error message.
96
+ */
97
+ public function getError() {
98
+ return $this->error;
99
+ }
100
+ }
101
+
102
+ $themechecks[] = new Screenshot_Check();
checks/class-script-tag-check.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check if a <script> tag is included in header.php or footer.php
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check if:
10
+ * A <script> tag is included in header.php or footer.php
11
+ */
12
+ class Script_Tag_Check implements themecheck {
13
+ /**
14
+ * Error messages, warnings and info notices.
15
+ *
16
+ * @var array $error
17
+ */
18
+ protected $error = array();
19
+
20
+ /**
21
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
22
+ *
23
+ * @param array $php_files File paths and content for PHP files.
24
+ * @param array $css_files File paths and content for CSS files.
25
+ * @param array $other_files Folder names, file paths and content for other files.
26
+ */
27
+ public function check( $php_files, $css_files, $other_files ) {
28
+ foreach ( $php_files as $file_path => $file_content ) {
29
+ checkcount();
30
+
31
+ // This check is limited to header.php and footer.php.
32
+ $filename = tc_filename( $file_path );
33
+ if ( ! in_array( $filename, array( 'header.php', 'footer.php' ) ) ) {
34
+ continue;
35
+ }
36
+
37
+ if ( false !== stripos( $file_content, '<script' ) ) {
38
+ $grep = tc_preg( '/<script/i', $file_path );
39
+ $this->error[] = sprintf(
40
+ '<span class="tc-lead tc-required">%s</span>: %s %s',
41
+ __( 'REQUIRED', 'theme-check' ),
42
+ sprintf(
43
+ __( 'Found a script tag in %s. Scripts and styles needs to be enqueued or added via a hook, not hard coded.', 'theme-check' ),
44
+ '<strong>' . $filename . '</strong>'
45
+ ),
46
+ $grep
47
+ );
48
+ }
49
+ }
50
+
51
+ return true;
52
+ }
53
+
54
+ /**
55
+ * Get error messages from the checks.
56
+ *
57
+ * @return array Error message.
58
+ */
59
+ public function getError() {
60
+ return $this->error;
61
+ }
62
+ }
63
+
64
+ $themechecks[] = new Script_Tag_Check();
checks/class-search-form-check.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check that searchform.php is not included directly
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check that searchform.php is not included directly.
10
+ */
11
+ class Search_Form_Check 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
+ $checks = array(
28
+ '/searchform.php/' => __( 'Use <strong>get_search_form()</strong> instead of including searchform.php directly. Otherwise, the form can not be filtered.', 'theme-check' ),
29
+ );
30
+
31
+ foreach ( $php_files as $file_path => $file_contents ) {
32
+ foreach ( $checks as $regex => $check_text ) {
33
+ checkcount();
34
+ if ( preg_match( $regex, $file_contents, $out ) ) {
35
+ $grep = tc_preg( $regex, $file_path );
36
+ $this->error[] = sprintf(
37
+ '<span class="tc-lead tc-warning">%s</span>: %s %s',
38
+ __( 'WARNING', 'theme-check' ),
39
+ sprintf(
40
+ __( '<strong>searchform.php</strong> was found in %1$s. %2$s', 'theme-check' ),
41
+ '<strong>' . tc_filename( $file_path ) . '</strong>',
42
+ $check_text
43
+ ),
44
+ $grep
45
+ );
46
+ }
47
+ }
48
+
49
+ $filename = tc_filename( $file_path );
50
+ // This doesn't apply to searchform.php or WooCommerce product-searchform.php.
51
+ if ( $filename === 'searchform.php' || $filename === 'product-searchform.php' ) {
52
+ continue;
53
+ }
54
+
55
+ checkcount();
56
+
57
+ // Checking for role="search" instead of form because it has a low risk of false positives.
58
+ if ( false !== strpos( $file_contents, 'role="search"' ) ) {
59
+ $grep = tc_preg( $regex, $file_path );
60
+ $this->error[] = sprintf(
61
+ '<span class="tc-lead tc-warning">%s</span>: %s %s',
62
+ __( 'WARNING', 'theme-check' ),
63
+ sprintf(
64
+ __( '<strong>role="search"</strong> was found in %1$s. %2$s', 'theme-check' ),
65
+ '<strong>' . tc_filename( $file_path ) . '</strong>',
66
+ __( 'Use <strong>get_search_form()</strong> instead of hard coding forms. Otherwise, the form can not be filtered.', 'theme-check' )
67
+ ),
68
+ $grep
69
+ );
70
+ }
71
+ }
72
+
73
+ return true;
74
+ }
75
+
76
+ /**
77
+ * Get error messages from the checks.
78
+ *
79
+ * @return array Error message.
80
+ */
81
+ public function getError() {
82
+ return $this->error;
83
+ }
84
+ }
85
+
86
+ $themechecks[] = new Search_Form_Check();
checks/{siteurl.php → class-site-url-check.php} RENAMED
@@ -1,54 +1,59 @@
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
2
+ /**
3
+ * Checks if site_url is used, and adds an info.
4
+ *
5
+ * @link https://developer.wordpress.org/reference/functions/site_url/
6
+ * @package Theme Check
7
+ */
8
+
9
+ /**
10
+ * Check for site_url
11
+ */
12
+ class Site_URL_Check implements themecheck {
13
+ /**
14
+ * Error messages, warnings and info notices.
15
+ *
16
+ * @var array $error
17
+ */
18
+ protected $error = array();
19
+
20
+ /**
21
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
22
+ *
23
+ * @param array $php_files File paths and content for PHP files.
24
+ * @param array $css_files File paths and content for CSS files.
25
+ * @param array $other_files Folder names, file paths and content for other files.
26
+ */
27
+ public function check( $php_files, $css_files, $other_files ) {
28
+
29
+ checkcount();
30
+
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">%s</span> %s',
37
+ __( 'INFO', 'theme-check' ),
38
+ sprintf(
39
+ __( 'site_url() or get_site_url() was found in %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' ),
40
+ '<strong>' . $filename . '</strong>'
41
+ )
42
+ );
43
+ }
44
+ }
45
+
46
+ return true;
47
+ }
48
+
49
+ /**
50
+ * Get error messages from the checks.
51
+ *
52
+ * @return array Error message.
53
+ */
54
+ public function getError() {
55
+ return $this->error;
56
+ }
57
+ }
58
+
59
+ $themechecks[] = new Site_URL_Check();
checks/class-style-css-header-check.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Checks if the style.css file header includes the required items.
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Checks if the style.css file header includes the required items.
10
+ */
11
+ class Style_CSS_Header_Check 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
+ $css = implode( ' ', $css_files );
29
+ $ret = true;
30
+
31
+ $checks = array(
32
+ '[ \t\/*#]*Theme Name:' => __( '<strong>Theme name:</strong> is missing from your style.css header.', 'theme-check' ),
33
+ '[ \t\/*#]*Description:' => __( '<strong>Description:</strong> is missing from your style.css header.', 'theme-check' ),
34
+ '[ \t\/*#]*Author:' => __( '<strong>Author:</strong> is missing from your style.css header.', 'theme-check' ),
35
+ '[ \t\/*#]*Version' => __( '<strong>Version:</strong> is missing from your style.css header.', 'theme-check' ),
36
+ '[ \t\/*#]*License:' => __( '<strong>License:</strong> is missing from your style.css header.', 'theme-check' ),
37
+ '[ \t\/*#]*License URI:' => __( '<strong>License URI:</strong> is missing from your style.css header.', 'theme-check' ),
38
+ '[ \t\/*#]*Text Domain:' => __( '<strong>Text Domain:</strong> is missing from your style.css header.', 'theme-check' ),
39
+ '[ \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' ),
40
+ '[ \t\/*#]*Requires PHP:' => __( '<strong>Requires PHP:</strong> is missing from your style.css header.', 'theme-check' ),
41
+ );
42
+
43
+ foreach ( $checks as $key => $check ) {
44
+ checkcount();
45
+ if ( ! preg_match( '/' . $key . '/i', $css, $matches ) ) {
46
+ $this->error[] = sprintf(
47
+ '<span class="tc-lead tc-required">%s</span> %s',
48
+ __( 'REQUIRED', 'theme-check' ),
49
+ $check
50
+ );
51
+ $ret = false;
52
+ }
53
+ }
54
+
55
+ return $ret;
56
+ }
57
+
58
+ /**
59
+ * Get error messages from the checks.
60
+ *
61
+ * @return array Error message.
62
+ */
63
+ public function getError() {
64
+ return $this->error;
65
+ }
66
+ }
67
+
68
+ $themechecks[] = new Style_CSS_Header_Check();
checks/class-style-tags-check.php ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Checks if the tags in style.css are valid
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Checks if the tags in style.css are valid.
10
+ */
11
+ class Style_Tags_Check implements themecheck {
12
+ /**
13
+ * Error messages, warnings and info notices.
14
+ *
15
+ * @var array $error
16
+ */
17
+ protected $error = array();
18
+
19
+ /**
20
+ * Array of theme tags in style.css
21
+ *
22
+ * @var array $tags
23
+ */
24
+ protected $tags = array();
25
+
26
+ function set_context( $data ) {
27
+ if ( isset( $data['theme'] ) ) {
28
+ $this->tags = $data['theme']['Tags'];
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
34
+ *
35
+ * @param array $php_files File paths and content for PHP files.
36
+ * @param array $css_files File paths and content for CSS files.
37
+ * @param array $other_files Folder names, file paths and content for other files.
38
+ */
39
+ public function check( $php_files, $css_files, $other_files ) {
40
+ checkcount();
41
+ $ret = true;
42
+
43
+ if ( ! $this->tags ) {
44
+ $this->error[] = sprintf(
45
+ '<span class="tc-lead tc-recommended">%s</span> %s',
46
+ __( 'RECOMMENDED', 'theme-check' ),
47
+ __( '<strong>Tags:</strong> is either empty or missing in style.css header.', 'theme-check' )
48
+ );
49
+ } else {
50
+ $deprecated_tags = $this->get_deprecated_tags();
51
+ $allowed_tags = $this->get_allowed_tags();
52
+ $subject_tags = $this->get_subject_tags();
53
+ $subject_tags_count = 0;
54
+ $subject_tags_name = '';
55
+
56
+ foreach ( $this->tags as $tag ) {
57
+
58
+ if ( strpos( strtolower( $tag ), 'accessibility-ready' ) !== false ) {
59
+ $this->error[] = sprintf(
60
+ '<span class="tc-lead tc-info">%s</span> %s',
61
+ __( 'INFO', 'theme-check' ),
62
+ __( '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' )
63
+ );
64
+ }
65
+
66
+ if ( ! in_array( strtolower( $tag ), $allowed_tags ) ) {
67
+ if ( in_array( strtolower( $tag ), $deprecated_tags ) ) {
68
+ $this->error[] = sprintf(
69
+ '<span class="tc-lead tc-required">%s</span> %s',
70
+ __( 'REQUIRED', 'theme-check' ),
71
+ sprintf(
72
+ __( 'The tag %s has been deprecated, please remove it from your style.css header.', 'theme-check' ),
73
+ '<strong>' . $tag . '</strong>'
74
+ )
75
+ );
76
+ $ret = false;
77
+ } else {
78
+ $this->error[] = sprintf(
79
+ '<span class="tc-lead tc-required">%s</span> %s',
80
+ __( 'REQUIRED', 'theme-check' ),
81
+ sprintf(
82
+ __( 'Found wrong tag, remove %s from your style.css header.', 'theme-check' ),
83
+ '<strong>' . $tag . '</strong>'
84
+ )
85
+ );
86
+ $ret = false;
87
+ }
88
+ }
89
+
90
+ if ( in_array( strtolower( $tag ), $subject_tags ) ) {
91
+ $subject_tags_name .= strtolower( $tag ) . ', ';
92
+ $subject_tags_count++;
93
+ }
94
+
95
+ if ( in_array( strtolower( $tag ), $allowed_tags ) ) {
96
+ if ( count( array_keys( $this->tags, $tag ) ) > 1 ) {
97
+ $this->error[] = sprintf(
98
+ '<span class="tc-lead tc-required">%s</span> %s',
99
+ __( 'REQUIRED', 'theme-check' ),
100
+ sprintf(
101
+ __( 'The tag %s is being used more than once, please remove it from your style.css header.', 'theme-check' ),
102
+ '<strong>' . $tag . '</strong>'
103
+ )
104
+ );
105
+ $ret = false;
106
+ }
107
+ }
108
+ }
109
+
110
+ if ( $subject_tags_count > 3 ) {
111
+ $this->error[] = sprintf(
112
+ '<span class="tc-lead tc-required">%s</span>: %s %s',
113
+ __( 'REQUIRED', 'theme-check' ),
114
+ sprintf(
115
+ __( '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' ),
116
+ $subject_tags_count,
117
+ '<strong>' . rtrim( $subject_tags_name, ', ' ) . '</strong>'
118
+ ),
119
+ sprintf(
120
+ '<a href="%s">%s</a>',
121
+ 'https://make.wordpress.org/themes/handbook/review/required/theme-tags/',
122
+ __( 'See Theme Tags', 'theme-check' )
123
+ )
124
+ );
125
+ $ret = false;
126
+ }
127
+ }
128
+
129
+ return $ret;
130
+ }
131
+
132
+ /**
133
+ * Get error messages from the checks.
134
+ *
135
+ * @return array Error message.
136
+ */
137
+ public function getError() {
138
+ return $this->error;
139
+ }
140
+
141
+ /**
142
+ * Get full list of allowed tags - including subject tags.
143
+ *
144
+ * @return array
145
+ */
146
+ private function get_allowed_tags() {
147
+ $allowed_tags = array(
148
+ 'grid-layout',
149
+ 'one-column',
150
+ 'two-columns',
151
+ 'three-columns',
152
+ 'four-columns',
153
+ 'left-sidebar',
154
+ 'right-sidebar',
155
+ 'wide-blocks',
156
+ 'flexible-header',
157
+ 'footer-widgets',
158
+ 'accessibility-ready',
159
+ 'block-patterns',
160
+ 'block-styles',
161
+ 'buddypress',
162
+ 'custom-background',
163
+ 'custom-colors',
164
+ 'custom-header',
165
+ 'custom-logo',
166
+ 'custom-menu',
167
+ 'editor-style',
168
+ 'featured-image-header',
169
+ 'featured-images',
170
+ 'front-page-post-form',
171
+ 'full-width-template',
172
+ 'full-site-editing',
173
+ 'microformats',
174
+ 'post-formats',
175
+ 'rtl-language-support',
176
+ 'sticky-post',
177
+ 'theme-options',
178
+ 'threaded-comments',
179
+ 'translation-ready',
180
+ );
181
+ return array_merge( $allowed_tags, self::get_subject_tags() );
182
+ }
183
+
184
+ /**
185
+ * Get the list of subject tags.
186
+ *
187
+ * @return array
188
+ */
189
+ private function get_subject_tags() {
190
+ return array(
191
+ 'blog',
192
+ 'e-commerce',
193
+ 'education',
194
+ 'entertainment',
195
+ 'food-and-drink',
196
+ 'holiday',
197
+ 'news',
198
+ 'photography',
199
+ 'portfolio',
200
+ );
201
+ }
202
+
203
+ /**
204
+ * Get the list of deprecated tags.
205
+ *
206
+ * @return array
207
+ */
208
+ private function get_deprecated_tags() {
209
+ return array(
210
+ 'flexible-width',
211
+ 'fixed-width',
212
+ 'black',
213
+ 'blue',
214
+ 'brown',
215
+ 'gray',
216
+ 'green',
217
+ 'orange',
218
+ 'pink',
219
+ 'purple',
220
+ 'red',
221
+ 'silver',
222
+ 'tan',
223
+ 'white',
224
+ 'yellow',
225
+ 'dark',
226
+ 'light',
227
+ 'fixed-layout',
228
+ 'fluid-layout',
229
+ 'responsive-layout',
230
+ 'blavatar',
231
+ 'holiday',
232
+ 'photoblogging',
233
+ 'seasonal',
234
+ );
235
+ }
236
+ }
237
+
238
+ $themechecks[] = new Style_Tags_Check();
checks/class-suggested-styles-check.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Checks if style.css includes theme and author URI
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Checks if style.css includes theme and author URI
10
+ */
11
+ class Suggested_Styles_Check 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
+ // Combine all the css files into one string to make it easier to search.
29
+ $css = implode( ' ', $css_files );
30
+
31
+ checkcount();
32
+
33
+ $checks = array(
34
+ '[ \t\/*#]*Theme URI:' => 'Theme URI:',
35
+ '[ \t\/*#]*Author URI:' => 'Author URI:',
36
+ );
37
+
38
+ foreach ( $checks as $key => $check ) {
39
+ if ( ! preg_match( '/' . $key . '/i', $css, $matches ) ) {
40
+ $this->error[] = sprintf( '<span class="tc-lead tc-recommended">' . __( 'RECOMMENDED', 'theme-check' ) . '</span>: ' . __( '%s is missing from your style.css header.', 'theme-check' ), '<strong>' . $check . '</strong>' );
41
+ }
42
+ }
43
+
44
+ $css_class_checks = array(
45
+ '\.sticky' => __( '<strong>.sticky</strong> css class is recommended in your theme css.', 'theme-check' ),
46
+ '\.bypostauthor' => __( '<strong>.bypostauthor</strong> css class is recommended in your theme css.', 'theme-check' ),
47
+ '\.alignleft' => __( '<strong>.alignleft</strong> css class is recommended in your theme css.', 'theme-check' ),
48
+ '\.alignright' => __( '<strong>.alignright</strong> css class is recommended in your theme css.', 'theme-check' ),
49
+ '\.aligncenter' => __( '<strong>.aligncenter</strong> css class is recommended in your theme css.', 'theme-check' ),
50
+ '\.wp-caption' => __( '<strong>.wp-caption</strong> css class is recommended in your theme css.', 'theme-check' ),
51
+ '\.wp-caption-text' => __( '<strong>.wp-caption-text</strong> css class is recommended in your theme css.', 'theme-check' ),
52
+ '\.gallery-caption' => __( '<strong>.gallery-caption</strong> css class is recommended in your theme css.', 'theme-check' ),
53
+ );
54
+
55
+ foreach ( $css_class_checks as $key => $check ) {
56
+ if ( ! preg_match( '/' . $key . '/i', $css, $matches ) ) {
57
+ $this->error[] = sprintf(
58
+ '<span class="tc-lead tc-recommended">%s</span> %s',
59
+ __( 'RECOMMENDED', 'theme-check' ),
60
+ $check
61
+ );
62
+ }
63
+ }
64
+
65
+ return true;
66
+ }
67
+
68
+ /**
69
+ * Get error messages from the checks.
70
+ *
71
+ * @return array Error message.
72
+ */
73
+ public function getError() {
74
+ return $this->error;
75
+ }
76
+ }
77
+
78
+ $themechecks[] = new Suggested_Styles_Check();
checks/class-tag-check.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Checks if tags are supported
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Checks if tags are supported.
10
+ */
11
+ class Tag_Check implements themecheck {
12
+ protected $error = array();
13
+
14
+ function check( $php_files, $css_files, $other_files ) {
15
+
16
+ // Combine all the php files into one string to make it easier to search.
17
+ $php = implode( ' ', $php_files );
18
+ checkcount();
19
+
20
+ if (
21
+ strpos( $php, 'the_tags' ) === false &&
22
+ strpos( $php, 'the_taxonomies' ) === false &&
23
+ strpos( $php, 'get_the_tag_list' ) === false &&
24
+ strpos( $php, 'get_the_term_list' ) === false
25
+ ) {
26
+ $this->error[] = sprintf(
27
+ '<span class="tc-lead tc-recommended">%s</span> %s',
28
+ __( 'RECOMMENDED', 'theme-check' ),
29
+ __( "This theme doesn't seem to display tags. Modify it to display tags in appropriate locations.", 'theme-check' )
30
+ );
31
+ }
32
+
33
+ return true;
34
+ }
35
+
36
+ function getError() {
37
+ return $this->error;
38
+ }
39
+ }
40
+
41
+ $themechecks[] = new Tag_Check();
checks/class-theme-support-check.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check for recommended theme support in classic themes
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check for recommended theme support in classic themes.
10
+ */
11
+ class Theme_Support_Check 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
+ $php = implode( ' ', $php_files );
29
+
30
+ $checks = array(
31
+ '#add_theme_support\s?\(\s?[\'|"]custom-header#' => __( 'No reference to <strong>add_theme_support( "custom-header", $args )</strong> was found in the theme. It is recommended that the theme implement this functionality if using an image for the header.', 'theme-check' ),
32
+ '#add_theme_support\s?\(\s?[\'|"]custom-background#' => __( 'No reference to <strong>add_theme_support( "custom-background", $args )</strong> was found in the theme. If the theme uses background images or solid colors for the background, then it is recommended that the theme implement this functionality.', 'theme-check' ),
33
+ '#add_theme_support\s?\(\s?[\'|"]custom-logo#' => __( 'No reference to <strong>add_theme_support( "custom-logo", $args )</strong> was found in the theme. It is recommended that the theme implement this functionality.', 'theme-check' ),
34
+ '#add_theme_support\s?\(\s?[\'|"]html5#' => __( 'No reference to <strong>add_theme_support( "html5", $args )</strong> was found in the theme. It is strongly recommended that the theme implement this functionality.', 'theme-check' ),
35
+ '#add_theme_support\s?\(\s?[\'|"]responsive-embeds#' => __( 'No reference to <strong>add_theme_support( "responsive-embeds" )</strong> was found in the theme. It is recommended that the theme implement this functionality.', 'theme-check' ),
36
+ '#add_theme_support\s?\(\s?[\'|"]align-wide#' => __( 'No reference to <strong>add_theme_support( "align-wide" )</strong> was found in the theme. It is recommended that the theme implement this functionality.', 'theme-check' ),
37
+ '#add_theme_support\s?\(\s?[\'|"]wp-block-styles#' => __( 'No reference to <strong>add_theme_support( "wp-block-styles" )</strong> was found in the theme. It is recommended that the theme implement this functionality.', 'theme-check' ),
38
+ );
39
+
40
+ foreach ( $checks as $key => $check ) {
41
+ checkcount();
42
+ if ( ! preg_match( $key, $php ) ) {
43
+ $this->error[] = sprintf(
44
+ '<span class="tc-lead tc-recommended">%s</span>: %s',
45
+ __( 'RECOMMENDED', 'theme-check' ),
46
+ $check
47
+ );
48
+ }
49
+ }
50
+
51
+ return true;
52
+ }
53
+
54
+ /**
55
+ * Get error messages from the checks.
56
+ *
57
+ * @return array Error message.
58
+ */
59
+ public function getError() {
60
+ return $this->error;
61
+ }
62
+ }
63
+
64
+ $themechecks[] = new Theme_Support_Check();
checks/class-theme-support-title-tag.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check classic themes for add_theme_support( 'title-tag' ).
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check classic themes for add_theme_support( 'title-tag' ).
10
+ */
11
+ class Theme_Support_Title_Tag_Check 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
+
30
+ // Look for add_theme_support( 'title-tag' ).
31
+ if ( ! preg_match( '#add_theme_support\s?\(\s?[\'|"]title-tag#', $php ) ) {
32
+ $ret = false;
33
+ $this->error[] = sprintf(
34
+ '<span class="tc-lead tc-required">%s</span>: %s',
35
+ __( 'REQUIRED', 'theme-check' ),
36
+ __( 'No reference to <strong>add_theme_support( "title-tag" )</strong> was found in the theme.', 'theme-check' )
37
+ );
38
+ }
39
+
40
+ return $ret;
41
+ }
42
+
43
+ /**
44
+ * Get error messages from the checks.
45
+ *
46
+ * @return array Error message.
47
+ */
48
+ public function getError() {
49
+ return $this->error;
50
+ }
51
+ }
52
+
53
+ $themechecks[] = new Theme_Support_Title_Tag_Check();
checks/class-time-date-check.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check if hard coded dates are used
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check if hard coded dates are used.
10
+ */
11
+ class Time_Date_Check 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
+ $checks = array(
29
+ '/\sdate_i18n\(\s?["|\'][A-Za-z\s]+\s?["|\']\)/' => 'date_i18n( get_option( \'date_format\' ) )',
30
+ '/[^get_]the_date\(\s?["|\'][A-Za-z\s]+\s?["|\']\)/' => 'the_date( get_option( \'date_format\' ) )',
31
+ '/[^get_]the_time\(\s?["|\'][A-Za-z\s]+\s?["|\']\)/' => 'the_time( get_option( \'date_format\' ) )',
32
+ );
33
+
34
+ foreach ( $php_files as $php_key => $phpfile ) {
35
+ foreach ( $checks as $key => $check ) {
36
+ checkcount();
37
+ if ( preg_match( $key, $phpfile, $matches ) ) {
38
+ $filename = tc_filename( $php_key );
39
+ $matches[0] = str_replace( array( '"', "'" ), '', $matches[0] );
40
+ $error = trim( esc_html( rtrim( $matches[0], '(' ) ) );
41
+ $this->error[] = sprintf(
42
+ '<span class="tc-lead tc-info">%s</span> %s',
43
+ __( 'INFO', 'theme-check' ),
44
+ sprintf(
45
+ __( 'At least one hard coded date was found in the file %1$s. Consider %2$s instead.', 'theme-check' ),
46
+ '<strong>' . $filename . '</strong>',
47
+ "<strong>get_option( 'date_format' )</strong>"
48
+ )
49
+ );
50
+ }
51
+ }
52
+ }
53
+
54
+ return true;
55
+ }
56
+
57
+ /**
58
+ * Get error messages from the checks.
59
+ *
60
+ * @return array Error message.
61
+ */
62
+ public function getError() {
63
+ return $this->error;
64
+ }
65
+ }
66
+
67
+ $themechecks[] = new Time_Date_Check();
checks/class-title-check.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check for wp_title and title tags.
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Checks for the title:
10
+ * Is there a call to wp_title()?
11
+ * Are there <title> and </title> tags?
12
+ *
13
+ * See: https://make.wordpress.org/themes/handbook/review/required/theme-check-plugin/
14
+ */
15
+ class Title_Check implements themecheck {
16
+ /**
17
+ * Error messages, warnings and info notices.
18
+ *
19
+ * @var array $error
20
+ */
21
+ protected $error = array();
22
+
23
+ /**
24
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
25
+ *
26
+ * @param array $php_files File paths and content for PHP files.
27
+ * @param array $css_files File paths and content for CSS files.
28
+ * @param array $other_files Folder names, file paths and content for other files.
29
+ */
30
+ public function check( $php_files, $css_files, $other_files ) {
31
+ $ret = true;
32
+ $php = implode( ' ', $php_files );
33
+
34
+ foreach ( $php_files as $file_path => $file_content ) {
35
+
36
+ // Check whether there is a call to wp_title().
37
+ checkcount();
38
+ if ( false !== strpos( $file_content, 'wp_title(' ) ) {
39
+ $ret = false;
40
+ $this->error[] = sprintf(
41
+ '<span class="tc-lead tc-required">%s</span>: %s',
42
+ __( 'REQUIRED', 'theme-check' ),
43
+ sprintf(
44
+ __( 'The theme must not use <strong>wp_title()</strong>. Found wp_title() in %1$s.', 'theme-check' ),
45
+ '<strong>' . tc_filename( $file_path ) . '</strong>'
46
+ )
47
+ );
48
+ }
49
+
50
+ // Look for anything that looks like <svg>...</svg> and exclude it (inline svg's have titles too).
51
+ $file_content = preg_replace( '/<svg.*>.*<\/svg>/s', '', $file_content );
52
+
53
+ // Look for <title> and </title> tags.
54
+ checkcount();
55
+ if ( ( false !== strpos( $file_content, '<title>' ) ) || ( false !== strpos( $file_content, '</title>' ) ) ) {
56
+ $ret = false;
57
+ $this->error[] = sprintf(
58
+ '<span class="tc-lead tc-required">%s</span>: %s',
59
+ __( 'REQUIRED', 'theme-check' ),
60
+ sprintf(
61
+ __( 'The theme must not use <strong>&lt;title&gt;</strong> tags. Found the tag in %1$s.', 'theme-check' ),
62
+ '<strong>' . tc_filename( $file_path ) . '</strong>'
63
+ )
64
+ );
65
+ }
66
+ }
67
+
68
+ return $ret;
69
+ }
70
+
71
+
72
+ /**
73
+ * Get error messages from the checks.
74
+ *
75
+ * @return array Error message.
76
+ */
77
+ public function getError() {
78
+ return $this->error;
79
+ }
80
+ }
81
+
82
+ $themechecks[] = new Title_Check();
checks/class-underscores-check.php ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check if the theme is a copy of underscores.
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check if:
10
+ * Theme or author URI refers to _s
11
+ * The readme is a copy of _s
12
+ * footer credit link refers to _s
13
+ */
14
+ class Underscores_Check implements themecheck {
15
+ /**
16
+ * Error messages, warnings and info notices.
17
+ *
18
+ * @var array $error
19
+ */
20
+ protected $error = array();
21
+
22
+ /**
23
+ * Theme information. Author URI, theme URI, Author name
24
+ *
25
+ * @var object $theme
26
+ */
27
+ protected $theme;
28
+
29
+ function set_context( $data ) {
30
+ if ( isset( $data['theme'] ) ) {
31
+ $this->theme = $data['theme'];
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
37
+ *
38
+ * @param array $php_files File paths and content for PHP files.
39
+ * @param array $css_files File paths and content for CSS files.
40
+ * @param array $other_files Folder names, file paths and content for other files.
41
+ */
42
+ public function check( $php_files, $css_files, $other_files ) {
43
+ $ret = true;
44
+
45
+ checkcount();
46
+ if ( ! empty( $this->theme->get( 'AuthorURI' ) ) || ! empty( $this->theme->get( 'ThemeURI' ) ) ) {
47
+
48
+ if (
49
+ stripos( $this->theme->get( 'ThemeURI' ), 'underscores.me' ) ||
50
+ stripos( $this->theme->get( 'AuthorURI' ), 'underscores.me' )
51
+ ) {
52
+ $ret = false;
53
+ $this->error[] = sprintf(
54
+ '<span class="tc-lead tc-required">%s</span>: %s',
55
+ __( 'REQUIRED', 'theme-check' ),
56
+ __( 'Found a copy of Underscores. Using underscores.me as Theme URI or Author URI is not allowed. Update the files for your own theme.', 'theme-check' )
57
+ );
58
+ }
59
+ }
60
+
61
+ checkcount();
62
+ foreach ( $other_files as $file_path => $file_content ) {
63
+ if (
64
+ preg_match( "/Hi. I'm a starter theme called `_s`, or `underscores`, if you like./", $file_content ) ||
65
+ preg_match( "/Hi. I'm a starter theme called <code>_s<\/code>, or <em>underscores<\/em>, if/", $file_content )
66
+ ) {
67
+ $ret = false;
68
+ $grep = tc_preg( "/Hi. I'm a starter theme called/", $file_path );
69
+ $this->error[] = sprintf(
70
+ '<span class="tc-lead tc-required">%s</span>: %s %s',
71
+ __( 'REQUIRED', 'theme-check' ),
72
+ sprintf(
73
+ __( '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' ),
74
+ '<strong>' . tc_filename( $file_path ) . '</strong>'
75
+ ),
76
+ $grep
77
+ );
78
+ }
79
+ }
80
+
81
+ /**
82
+ * This check is limited to footer.php, since we are looking for clones of underscores.
83
+ */
84
+ checkcount();
85
+ foreach ( $php_files as $file_path => $file_content ) {
86
+ $filename = tc_filename( $file_path );
87
+ if ( 'footer.php' === $filename && preg_match( '/Underscores.me/i', $file_content ) ) {
88
+ $ret = false;
89
+ $grep = tc_preg( '/Underscores.me/i', $file_path );
90
+ $this->error[] = sprintf(
91
+ '<span class="tc-lead tc-required">%s</span>: %s %s',
92
+ __( 'REQUIRED', 'theme-check' ),
93
+ sprintf(
94
+ __( 'Found a copy of Underscores. See %1$s. Update the files for your own theme.', 'theme-check' ),
95
+ '<strong>' . $filename . '</strong>'
96
+ ),
97
+ $grep
98
+ );
99
+ }
100
+ }
101
+
102
+ return $ret;
103
+ }
104
+
105
+ /**
106
+ * Get error messages from the checks.
107
+ *
108
+ * @return array Error message.
109
+ */
110
+ public function getError() {
111
+ return $this->error;
112
+ }
113
+ }
114
+
115
+ $themechecks[] = new Underscores_Check();
checks/class-uri-check.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check if theme and author URI are the same and that wordpress.org is not used for theme URI
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check if theme and author URI are the same and that wordpress.org is not used for theme URI.
10
+ */
11
+ class URI_Check implements themecheck {
12
+ /**
13
+ * Error messages, warnings and info notices.
14
+ *
15
+ * @var array $error
16
+ */
17
+ protected $error = array();
18
+
19
+ /**
20
+ * Theme information. Author URI, theme URI, Author name
21
+ *
22
+ * @var object $theme
23
+ */
24
+ protected $theme;
25
+
26
+ function set_context( $data ) {
27
+ if ( isset( $data['theme'] ) ) {
28
+ $this->theme = $data['theme'];
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Check that return true for good/okay/acceptable, false for bad/not-okay/unacceptable.
34
+ *
35
+ * @param array $php_files File paths and content for PHP files.
36
+ * @param array $css_files File paths and content for CSS files.
37
+ * @param array $other_files Folder names, file paths and content for other files.
38
+ */
39
+ public function check( $php_files, $css_files, $other_files ) {
40
+ checkcount();
41
+ $ret = true;
42
+
43
+ if ( ! empty( $this->theme->get( 'AuthorURI' ) ) && ! empty( $this->theme->get( 'ThemeURI' ) ) ) {
44
+
45
+ if ( strtolower( preg_replace( '/https?:\/\/|www./i', '', trim( $this->theme->get( 'ThemeURI' ), '/' ) ) ) == strtolower( preg_replace( '/https?:\/\/|www./i', '', trim( $this->theme->get( 'AuthorURI' ), '/' ) ) ) ) {
46
+ $this->error[] = sprintf(
47
+ '<span class="tc-lead tc-required">%s</span>: %s',
48
+ __( 'REQUIRED', 'theme-check' ),
49
+ __( 'Your Theme URI and Author URI must not be the same.', 'theme-check' )
50
+ );
51
+ $ret = false;
52
+ }
53
+
54
+ // We allow .org user profiles as Author URI, so only check the Theme URI. We also allow WordPress.com links.
55
+ if (
56
+ $this->theme->get( 'Author' ) != 'the WordPress team' &&
57
+ ( stripos( $this->theme->get( 'ThemeURI' ), 'wordpress.org' ) || stripos( $this->theme->get( 'ThemeURI' ), 'w.org' ) )
58
+ ) {
59
+ $this->error[] = sprintf(
60
+ '<span class="tc-lead tc-required">%s</span>: %s',
61
+ __( 'REQUIRED', 'theme-check' ),
62
+ __( 'Using a WordPress.org Theme URI is reserved for default and bundled themes (Twenty * series).', 'theme-check' )
63
+ );
64
+ $ret = false;
65
+ }
66
+ }
67
+
68
+ return $ret;
69
+ }
70
+
71
+ /**
72
+ * Get error messages from the checks.
73
+ *
74
+ * @return array Error message.
75
+ */
76
+ public function getError() {
77
+ return $this->error;
78
+ }
79
+ }
80
+
81
+ $themechecks[] = new URI_Check();
checks/class-widgets-check.php ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check if widgets are supported in classic themes
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check if widgets are supported in classic themes.
10
+ */
11
+ class Widgets_Check 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
+ // Combine all the php files into one string to make it easier to search.
31
+ $php = implode( ' ', $php_files );
32
+ checkcount();
33
+
34
+ // No widgets registered or used.
35
+ if (
36
+ strpos( $php, 'register_sidebar' ) === false &&
37
+ strpos( $php, 'dynamic_sidebar' ) === false
38
+ ) {
39
+ $this->error[] = sprintf(
40
+ '<span class="tc-lead tc-recommended">%s</span> %s',
41
+ __( 'RECOMMENDED', 'theme-check' ),
42
+ __( "This theme contains no sidebars/widget areas. See <a href='https://codex.wordpress.org/Widgets_API'>Widgets API</a>", 'theme-check' )
43
+ );
44
+ $ret = true;
45
+ }
46
+
47
+ // Widget area is registered but not used.
48
+ if (
49
+ strpos( $php, 'register_sidebar' ) !== false &&
50
+ strpos( $php, 'dynamic_sidebar' ) === false
51
+ ) {
52
+ $this->error[] = sprintf(
53
+ '<span class="tc-lead tc-required">%s</span> %s',
54
+ __( 'REQUIRED', 'theme-check' ),
55
+ __( "The theme appears to use <strong>register_sidebar()</strong> but no <strong>dynamic_sidebar()</strong> was found. See: <a href='https://developer.wordpress.org/reference/functions/dynamic_sidebar/'>dynamic_sidebar</a><pre> &lt;?php dynamic_sidebar( \$index ); ?&gt;</pre>", 'theme-check' )
56
+ );
57
+ $ret = false;
58
+ }
59
+
60
+ // Widget area is used but not registered.
61
+ if (
62
+ strpos( $php, 'register_sidebar' ) === false &&
63
+ strpos( $php, 'dynamic_sidebar' ) !== false
64
+ ) {
65
+ $this->error[] = sprintf(
66
+ '<span class="tc-lead tc-required">%s</span> %s',
67
+ __( 'REQUIRED', 'theme-check' ),
68
+ __( "The theme appears to use <strong>dynamic_sidebars()</strong> but no <strong>register_sidebar()</strong> was found. See: <a href='https://developer.wordpress.org/reference/functions/register_sidebar/'>register_sidebar</a><pre> &lt;?php register_sidebar( \$args ); ?&gt;</pre>", 'theme-check' )
69
+ );
70
+ $ret = false;
71
+ }
72
+
73
+ /**
74
+ * There are widgets registered, is the widgets_init action present?
75
+ */
76
+ if (
77
+ strpos( $php, 'register_sidebar' ) !== false &&
78
+ preg_match( '/add_action\s*\(\s*("|\')widgets_init("|\')\s*,/', $php ) == false
79
+ ) {
80
+ $this->error[] = sprintf(
81
+ '<span class="tc-lead tc-required">%s</span> %s',
82
+ __( 'REQUIRED', 'theme-check' ),
83
+ sprintf(
84
+ __( 'Sidebars need to be registered in a custom function hooked to the <strong>widgets_init</strong> action. See: %s.', 'theme-check' ),
85
+ '<a href="https://developer.wordpress.org/reference/functions/register_sidebar/">register_sidebar()</a>'
86
+ )
87
+ );
88
+ $ret = false;
89
+ }
90
+ return $ret;
91
+ }
92
+
93
+ /**
94
+ * Get error messages from the checks.
95
+ *
96
+ * @return array Error message.
97
+ */
98
+ public function getError() {
99
+ return $this->error;
100
+ }
101
+ }
102
+
103
+ $themechecks[] = new Widgets_Check();
checks/class-worms-check.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Check for signs of worms and hacks
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Check for signs of worms and hacks.
10
+ */
11
+ class Worms_Check implements themecheck {
12
+ /**
13
+ * Error messages, warnings and info notices.
14
+ *
15
+ * @var array $error
16
+ */
17
+ protected $error = array();
18
+
19
+ function check( $php_files, $css_files, $other_files ) {
20
+ $ret = true;
21
+ $php_files = array_merge( $php_files, $other_files );
22
+ $checks = array(
23
+ '/wshell\.php/' => __( 'This may be a script used by hackers to get control of your server!', 'theme-check' ),
24
+ '/ShellBOT/' => __( 'This may be a script used by hackers to get control of your server', 'theme-check' ),
25
+ '/uname -a/' => __( 'Tells a hacker what operating system your server is running', 'theme-check' ),
26
+ '/php \$[a-zA-Z]*=\'as\';/' => __( 'Symptom of the "Pharma Hack" <a href="http://blog.sucuri.net/2010/07/understanding-and-cleaning-the-pharma-hack-on-wordpress.html">[1]</a>', 'theme-check' ),
27
+ '/defined?\(\'wp_class_support/' => __( 'Symptom of the "Pharma Hack" <a href="http://blog.sucuri.net/2010/07/understanding-and-cleaning-the-pharma-hack-on-wordpress.html">[1]</a>', 'theme-check' ),
28
+ );
29
+
30
+ foreach ( $php_files as $php_key => $phpfile ) {
31
+ foreach ( $checks as $key => $check ) {
32
+ checkcount();
33
+ if ( preg_match( $key, $phpfile, $matches ) ) {
34
+ $filename = tc_filename( $php_key );
35
+ $error = $matches[0];
36
+ $grep = tc_grep( $error, $php_key );
37
+ $this->error[] = sprintf(
38
+ '<span class="tc-lead tc-required">%s</span>: %s %s %s',
39
+ __( 'REQUIRED', 'theme-check' ),
40
+ '<strong>' . $filename . '</strong>',
41
+ $check,
42
+ $grep
43
+ );
44
+ $ret = false;
45
+ }
46
+ }
47
+ }
48
+ return $ret;
49
+ }
50
+
51
+ /**
52
+ * Get error messages from the checks.
53
+ *
54
+ * @return array Error message.
55
+ */
56
+ public function getError() {
57
+ return $this->error;
58
+ }
59
+ }
60
+
61
+ $themechecks[] = new Worms_Check();
checks/comment_reply.php DELETED
@@ -1,27 +0,0 @@
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/commpage.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
-
3
- class CommentPaginationCheck implements themecheck {
4
- protected $error = array();
5
-
6
- function check( $php_files, $css_files, $other_files ) {
7
- $ret = true;
8
-
9
- // combine all the php files into one string to make it easier to search
10
- $php = implode( ' ', $php_files );
11
- checkcount();
12
- if (strpos( $php, 'paginate_comments_links' ) === false &&
13
- strpos( $php, 'the_comments_navigation' ) === false &&
14
- strpos( $php, 'the_comments_pagination' ) === false &&
15
- (strpos( $php, 'next_comments_link' ) === false && strpos( $php, 'previous_comments_link' ) === false ) ) {
16
-
17
- $this->error[] = '<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('The theme doesn\'t have comment pagination code in it. Use <strong>paginate_comments_links()</strong> or <strong>the_comments_navigation</strong> or <strong>the_comments_pagination</strong> or <strong>next_comments_link()</strong> and <strong>previous_comments_link()</strong> to add comment pagination.', 'theme-check' );
18
- $ret = false;
19
- }
20
-
21
- return $ret;
22
- }
23
-
24
- function getError() { return $this->error; }
25
- }
26
- $themechecks[] = new CommentPaginationCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/constants.php DELETED
@@ -1,41 +0,0 @@
1
- <?php
2
-
3
- class Constants implements themecheck {
4
- protected $error = array();
5
-
6
- function check( $php_files, $css_files, $other_files ) {
7
-
8
- $ret = true;
9
-
10
- $checks = array(
11
- 'STYLESHEETPATH' => 'get_stylesheet_directory()',
12
- 'TEMPLATEPATH' => 'get_template_directory()',
13
- 'PLUGINDIR' => 'WP_PLUGIN_DIR',
14
- 'MUPLUGINDIR' => 'WPMU_PLUGIN_DIR',
15
- 'HEADER_IMAGE' => 'add_theme_support( \'custom-header\' )',
16
- 'NO_HEADER_TEXT' => 'add_theme_support( \'custom-header\' )',
17
- 'HEADER_TEXTCOLOR' => 'add_theme_support( \'custom-header\' )',
18
- 'HEADER_IMAGE_WIDTH' => 'add_theme_support( \'custom-header\' )',
19
- 'HEADER_IMAGE_HEIGHT' => 'add_theme_support( \'custom-header\' )',
20
- 'BACKGROUND_COLOR' => 'add_theme_support( \'custom-background\' )',
21
- 'BACKGROUND_IMAGE' => 'add_theme_support( \'custom-background\' )',
22
- );
23
-
24
- foreach ( $php_files as $php_key => $phpfile ) {
25
- foreach ( $checks as $key => $check ) {
26
- checkcount();
27
- if ( preg_match( '/[\s|\'|\"]' . $key . '(?:\'|"|;|\s)/', $phpfile, $matches ) ) {
28
- $filename = tc_filename( $php_key );
29
- $error = ltrim( rtrim( $matches[0], '(' ), '\'"' );
30
- $grep = tc_grep( $error, $php_key );
31
- $this->error[] = sprintf('<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('%1$s was found in the file %2$s. Use %3$s instead.%4$s', 'theme-check'), '<strong>' . $error . '</strong>', '<strong>' . $filename . '</strong>', '<strong>' . $check . '</strong>', $grep );
32
- $ret = false;
33
- }
34
- }
35
- }
36
- return $ret;
37
- }
38
-
39
- function getError() { return $this->error; }
40
- }
41
- $themechecks[] = new Constants;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/content-width.php CHANGED
@@ -5,19 +5,27 @@ class ContentWidthCheck implements themecheck {
5
 
6
  function check( $php_files, $css_files, $other_files ) {
7
 
8
- $ret = true;
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, '$content_width' ) === false && strpos( $php, '$GLOBALS' . "['content_width']" ) === false && !preg_match( '/add_filter\(\s?("|\')embed_defaults/', $php ) && !preg_match( '/add_filter\(\s?("|\')content_width/', $php ) ) {
14
- $this->error[] = '<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('No content width has been defined. Example: <pre>if ( ! isset( $content_width ) ) $content_width = 900;</pre>', 'theme-check' );
15
- $ret = false;
 
 
 
 
 
 
 
 
16
  }
17
 
18
- return $ret;
19
  }
20
 
21
- function getError() { return $this->error; }
 
 
22
  }
23
- $themechecks[] = new ContentWidthCheck;
5
 
6
  function check( $php_files, $css_files, $other_files ) {
7
 
 
 
8
  // combine all the php files into one string to make it easier to search
9
  $php = implode( ' ', $php_files );
10
  checkcount();
11
+ if (
12
+ strpos( $php, '$content_width' ) === false &&
13
+ strpos( $php, '$GLOBALS' . "['content_width']" ) === false &&
14
+ ! preg_match( '/add_filter\(\s?("|\')embed_defaults/', $php ) &&
15
+ ! preg_match( '/add_filter\(\s?("|\')content_width/', $php )
16
+ ) {
17
+ $this->error[] = sprintf(
18
+ '<span class="tc-lead tc-recommended">%s</span>: %s',
19
+ __( 'RECOMMENDED', 'theme-check' ),
20
+ __( 'No content width has been defined. Example: <pre>if ( ! isset( $content_width ) ) $content_width = 900;</pre>', 'theme-check' )
21
+ );
22
  }
23
 
24
+ return true;
25
  }
26
 
27
+ function getError() {
28
+ return $this->error;
29
+ }
30
  }
31
+ $themechecks[] = new ContentWidthCheck();
checks/customizer.php DELETED
@@ -1,59 +0,0 @@
1
- <?php
2
- /**
3
- * Checks for the Customizer.
4
- */
5
-
6
- class CustomizerCheck implements themecheck {
7
- protected $error = array();
8
-
9
- function check( $php_files, $css_files, $other_files ) {
10
-
11
- $ret = true;
12
-
13
- checkcount();
14
-
15
- /**
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
- }
49
- }
50
- }
51
- }
52
-
53
- return $ret;
54
- }
55
-
56
- function getError() { return $this->error; }
57
- }
58
-
59
- $themechecks[] = new CustomizerCheck();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/customs.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
-
3
- class CustomCheck implements themecheck {
4
- protected $error = array();
5
-
6
- function check( $php_files, $css_files, $other_files) {
7
-
8
- $ret = true;
9
- $php = implode( ' ', $php_files );
10
-
11
- checkcount();
12
-
13
- if ( ! preg_match( '#add_theme_support\s?\(\s?[\'|"]custom-header#', $php ) ) {
14
- $this->error[] = '<span class="tc-lead tc-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__('No reference to <strong>add_theme_support( "custom-header", $args )</strong> was found in the theme. It is recommended that the theme implement this functionality if using an image for the header.', 'theme-check' );
15
- }
16
-
17
- if ( ! preg_match( '#add_theme_support\s?\(\s?[\'|"]custom-background#', $php ) ) {
18
- $this->error[] = '<span class="tc-lead tc-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__('No reference to <strong>add_theme_support( "custom-background", $args )</strong> was found in the theme. If the theme uses background images or solid colors for the background, then it is recommended that the theme implement this functionality.', 'theme-check' );
19
- }
20
-
21
- return $ret;
22
- }
23
-
24
- function getError() { return $this->error; }
25
- }
26
- $themechecks[] = new CustomCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/dep_recommend.php DELETED
@@ -1,67 +0,0 @@
1
- <?php
2
- // recommended deprecations checks... After some time, these will move into deprecated.php and become required.
3
- class Deprecated_Recommended implements themecheck {
4
- protected $error = array();
5
-
6
- function check( $php_files, $css_files, $other_files ) {
7
- $grep = '';
8
-
9
- $ret = true;
10
-
11
- $checks = array(
12
- array( 'preview_theme' => '', '4.3' ),
13
- array( '_preview_theme_template_filter' => '', '4.3' ),
14
- array( '_preview_theme_stylesheet_filter' => '', '4.3' ),
15
- array( 'preview_theme_ob_filter' => '', '4.3' ),
16
- array( 'preview_theme_ob_filter_callback' => '', '4.3' ),
17
- array( 'wp_richedit_pre' => '', '4.3' ),
18
- array( 'wp_htmledit_pre' => '', '4.3' ),
19
- array( 'wp_ajax_wp_fullscreen_save_post' => '', '4.3' ),
20
-
21
- array( 'post_permalink' => 'get_permalink', '4.4'),
22
- array( 'wp_get_http' => 'WP_Http', '4.4'),
23
- array( 'force_ssl_login' => 'force_ssl_admin', '4.4'),
24
- array( 'create_empty_blog' => '', '4.4'),
25
- array( 'get_admin_users_for_domain' => '', '4.4'),
26
- //array( 'flush_widget_cache' => '', '4.4'),
27
- );
28
-
29
- foreach ( $php_files as $php_key => $phpfile ) {
30
- foreach ( $checks as $alt => $check ) {
31
- checkcount();
32
- $version = $check;
33
- $key = key( $check );
34
- $alt = $check[ $key ];
35
- if ( preg_match( '/[\s?]' . $key . '\(/', $phpfile, $matches ) ) {
36
- $filename = tc_filename( $php_key );
37
- $error = ltrim( rtrim( $matches[0], '(' ) );
38
- $version = $check[0];
39
- $grep = tc_grep( $error, $php_key );
40
-
41
- // Point out the deprecated function.
42
- $error_msg = sprintf(
43
- __( '%1$s found in the file %2$s. Deprecated since version %3$s.', 'theme-check' ),
44
- '<strong>' . $error . '()</strong>',
45
- '<strong>' . $filename . '</strong>',
46
- '<strong>' . $version . '</strong>'
47
- );
48
-
49
- // Add alternative function when available.
50
- if ( $alt ) {
51
- $error_msg .= ' ' . sprintf( __( 'Use %s instead.', 'theme-check' ), '<strong>' . $alt . '</strong>' );
52
- }
53
-
54
- // Add the precise code match that was found.
55
- $error_msg .= $grep;
56
-
57
- // Add the finalized error message.
58
- $this->error[] = '<span class="tc-lead tc-recommended">' . __('RECOMMENDED','theme-check') . '</span>: ' . $error_msg;
59
- }
60
- }
61
- }
62
- return $ret;
63
- }
64
-
65
- function getError() { return $this->error; }
66
- }
67
- $themechecks[] = new Deprecated_Recommended;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/deprecated.php DELETED
@@ -1,345 +0,0 @@
1
- <?php
2
-
3
- class Deprecated implements themecheck {
4
- protected $error = array();
5
-
6
- function check( $php_files, $css_files, $other_files ) {
7
- $grep = '';
8
-
9
- $ret = true;
10
-
11
- $checks = array(
12
- // start wp-includes deprecated
13
- array( 'get_postdata' => 'get_post()', '1.5.1' ),
14
- array( 'start_wp' => 'the Loop', '1.5' ),
15
- array( 'the_category_id' => 'get_the_category()', '0.71' ),
16
- array( 'the_category_head' => 'get_the_category_by_ID()', '0.71' ),
17
- array( 'previous_post' => 'previous_post_link()', '2.0' ),
18
- array( 'next_post' => 'next_post_link()', '2.0' ),
19
- array( 'user_can_create_post' => 'current_user_can()', '2.0' ),
20
- array( 'user_can_create_draft' => 'current_user_can()', '2.0' ),
21
- array( 'user_can_edit_post' => 'current_user_can()', '2.0' ),
22
- array( 'user_can_delete_post' => 'current_user_can()', '2.0' ),
23
- array( 'user_can_set_post_date' => 'current_user_can()', '2.0' ),
24
- array( 'user_can_edit_post_comments' => 'current_user_can()', '2.0' ),
25
- array( 'user_can_delete_post_comments' => 'current_user_can()', '2.0' ),
26
- array( 'user_can_edit_user' => 'current_user_can()', '2.0' ),
27
- array( 'get_linksbyname' => 'get_bookmarks()', '2.1' ),
28
- array( 'wp_get_linksbyname' => 'wp_list_bookmarks()', '2.1' ),
29
- array( 'get_linkobjectsbyname' => 'get_bookmarks()', '2.1' ),
30
- array( 'get_linkobjects' => 'get_bookmarks()', '2.1' ),
31
- array( 'get_linksbyname_withrating' => 'get_bookmarks()', '2.1' ),
32
- array( 'get_links_withrating' => 'get_bookmarks()', '2.1' ),
33
- array( 'get_autotoggle' => '', '2.1' ),
34
- array( 'list_cats' => 'wp_list_categories', '2.1' ),
35
- array( 'wp_list_cats' => 'wp_list_categories', '2.1' ),
36
- array( 'dropdown_cats' => 'wp_dropdown_categories()', '2.1' ),
37
- array( 'list_authors' => 'wp_list_authors()', '2.1' ),
38
- array( 'wp_get_post_cats' => 'wp_get_post_categories()', '2.1' ),
39
- array( 'wp_set_post_cats' => 'wp_set_post_categories()', '2.1' ),
40
- array( 'get_archives' => 'wp_get_archives', '2.1' ),
41
- array( 'get_author_link' => 'get_author_posts_url()', '2.1' ),
42
- array( 'link_pages' => 'wp_link_pages()', '2.1' ),
43
- array( 'get_settings' => 'get_option()', '2.1' ),
44
- array( 'permalink_link' => 'the_permalink()', '1.2' ),
45
- array( 'permalink_single_rss' => 'permalink_rss()', '2.3' ),
46
- array( 'wp_get_links' => 'wp_list_bookmarks()', '2.1' ),
47
- array( 'get_links' => 'get_bookmarks()', '2.1' ),
48
- array( 'get_links_list' => 'wp_list_bookmarks()', '2.1' ),
49
- array( 'links_popup_script' => '', '2.1' ),
50
- array( 'get_linkrating' => 'sanitize_bookmark_field()', '2.1' ),
51
- array( 'get_linkcatname' => 'get_category()', '2.1' ),
52
- array( 'comments_rss_link' => 'post_comments_feed_link()', '2.5' ),
53
- array( 'get_category_rss_link' => 'get_category_feed_link()'. '2.5' ),
54
- array( 'get_author_rss_link' => 'get_author_feed_link()', '2.5' ),
55
- array( 'comments_rss' => 'get_post_comments_feed_link()', '2.2' ),
56
- array( 'create_user' => 'wp_create_user()', '2.0' ),
57
- array( 'gzip_compression' => '', '2.5' ),
58
- array( 'get_commentdata' => 'get_comment()', '2.7' ),
59
- array( 'get_catname' => 'get_cat_name()', '2.8' ),
60
- array( 'get_category_children' => 'get_term_children', '2.8' ),
61
- array( 'get_the_author_description' => 'get_the_author_meta(\'description\')', '2.8' ),
62
- array( 'the_author_description' => 'the_author_meta(\'description\')', '2.8' ),
63
- array( 'get_the_author_login' => 'the_author_meta(\'login\')', '2.8' ),
64
- array( 'get_the_author_firstname' => 'get_the_author_meta(\'first_name\')', '2.8' ),
65
- array( 'the_author_firstname' => 'the_author_meta(\'first_name\')', '2.8' ),
66
- array( 'get_the_author_lastname' => 'get_the_author_meta(\'last_name\')', '2.8' ),
67
- array( 'the_author_lastname' => 'the_author_meta(\'last_name\')', '2.8' ),
68
- array( 'get_the_author_nickname' => 'get_the_author_meta(\'nickname\')', '2.8' ),
69
- array( 'the_author_nickname' => 'the_author_meta(\'nickname\')', '2.8' ),
70
- array( 'get_the_author_email' => 'get_the_author_meta(\'email\')', '2.8' ),
71
- array( 'the_author_email' => 'the_author_meta(\'email\')', '2.8' ),
72
- array( 'get_the_author_icq' => 'get_the_author_meta(\'icq\')', '2.8' ),
73
- array( 'the_author_icq' => 'the_author_meta(\'icq\')', '2.8' ),
74
- array( 'get_the_author_yim' => 'get_the_author_meta(\'yim\')', '2.8' ),
75
- array( 'the_author_yim' => 'the_author_meta(\'yim\')', '2.8' ),
76
- array( 'get_the_author_msn' => 'get_the_author_meta(\'msn\')', '2.8' ),
77
- array( 'the_author_msn' => 'the_author_meta(\'msn\')', '2.8' ),
78
- array( 'get_the_author_aim' => 'get_the_author_meta(\'aim\')', '2.8' ),
79
- array( 'the_author_aim' => 'the_author_meta(\'aim\')', '2.8' ),
80
- array( 'get_author_name' => 'get_the_author_meta(\'display_name\')', '2.8' ),
81
- array( 'get_the_author_url' => 'get_the_author_meta(\'url\')', '2.8' ),
82
- array( 'the_author_url' => 'the_author_meta(\'url\')', '2.8' ),
83
- array( 'get_the_author_ID' => 'get_the_author_meta(\'ID\')', '2.8' ),
84
- array( 'the_author_ID' => 'the_author_meta(\'ID\')', '2.8' ),
85
- array( 'the_content_rss' => 'the_content_feed()', '2.9' ),
86
- array( 'make_url_footnote' => '', '2.9' ),
87
- array( '_c' => '_x()', '2.9' ),
88
- array( 'translate_with_context' => '_x()', '3.0' ),
89
- array( 'nc' => 'nx()', '3.0' ),
90
- array( '__ngettext' => '_n_noop()', '2.8' ),
91
- array( '__ngettext_noop' => '_n_noop()', '2.8' ),
92
- array( 'get_alloptions' => 'wp_load_alloptions()', '3.0' ),
93
- array( 'get_the_attachment_link' => 'wp_get_attachment_link()', '2.5' ),
94
- array( 'get_attachment_icon_src' => 'wp_get_attachment_image_src()', '2.5' ),
95
- array( 'get_attachment_icon' => 'wp_get_attachment_image()', '2.5' ),
96
- array( 'get_attachment_innerhtml' => 'wp_get_attachment_image()', '2.5' ),
97
- array( 'get_link' => 'get_bookmark()', '2.1' ),
98
- array( 'sanitize_url' => 'esc_url()', '2.8' ),
99
- array( 'clean_url' => 'esc_url()', '3.0' ),
100
- array( 'js_escape' => 'esc_js()', '2.8' ),
101
- array( 'wp_specialchars' => 'esc_html()', '2.8' ),
102
- array( 'attribute_escape' => 'esc_attr()', '2.8' ),
103
- array( 'register_sidebar_widget' => 'wp_register_sidebar_widget()', '2.8' ),
104
- array( 'unregister_sidebar_widget' => 'wp_unregister_sidebar_widget()', '2.8' ),
105
- array( 'register_widget_control' => 'wp_register_widget_control()', '2.8' ),
106
- array( 'unregister_widget_control' => 'wp_unregister_widget_control()', '2.8' ),
107
- array( 'delete_usermeta' => 'delete_user_meta()', '3.0' ),
108
- array( 'get_usermeta' => 'get_user_meta()', '3.0' ),
109
- array( 'update_usermeta' => 'update_user_meta()', '3.0' ),
110
- array( 'automatic_feed_links' => 'add_theme_support( \'automatic-feed-links\' )', '3.0' ),
111
- array( 'get_profile' => 'get_the_author_meta()', '3.0' ),
112
- array( 'get_usernumposts' => 'count_user_posts()', '3.0' ),
113
- array( 'funky_javascript_callback' => '', '3.0' ),
114
- array( 'funky_javascript_fix' => '', '3.0' ),
115
- array( 'is_taxonomy' => 'taxonomy_exists()', '3.0' ),
116
- array( 'is_term' => 'term_exists()', '3.0' ),
117
- array( 'is_plugin_page' => '$plugin_page and/or get_plugin_page_hookname() hooks', '3.1' ),
118
- array( 'update_category_cache' => 'No alternatives', '3.1' ),
119
- array( 'get_users_of_blog' => 'get_users()', '3.1' ),
120
- array( 'wp_timezone_supported' => '', '3.2' ),
121
- array( 'the_editor' => 'wp_editor', '3.3' ),
122
- array( 'get_user_metavalues' => '', '3.3' ),
123
- array( 'sanitize_user_object' => '', '3.3' ),
124
- array( 'get_boundary_post_rel_link' => '', '3.3' ),
125
- array( 'start_post_rel_link' => 'none available ', '3.3' ),
126
- array( 'get_index_rel_link' => '', '3.3' ),
127
- array( 'index_rel_link' => '', '3.3' ),
128
- array( 'get_parent_post_rel_link' => '', '3.3' ),
129
- array( 'parent_post_rel_link' => '', '3.3' ),
130
- array( 'wp_admin_bar_dashboard_view_site_menu' => '', '3.3' ),
131
- array( 'is_blog_user' => 'is_member_of_blog()', '3.3' ),
132
- array( 'debug_fopen' => 'error_log()', '3.3' ),
133
- array( 'debug_fwrite' => 'error_log()', '3.3' ),
134
- array( 'debug_fclose' => 'error_log()', '3.3' ),
135
- array( 'get_themes' => 'wp_get_themes()', '3.4' ),
136
- array( 'get_theme' => 'wp_get_theme()', '3.4' ),
137
- array( 'get_current_theme' => 'wp_get_theme()', '3.4' ),
138
- array( 'clean_pre' => '', '3.4' ),
139
- array( 'add_custom_image_header' => 'add_theme_support( \'custom-header\', $args )', '3.4' ),
140
- array( 'remove_custom_image_header' => 'remove_theme_support( \'custom-header\' )', '3.4' ),
141
- array( 'add_custom_background' => 'add_theme_support( \'custom-background\', $args )', '3.4' ),
142
- array( 'remove_custom_background' => 'remove_theme_support( \'custom-background\' )', '3.4' ),
143
- array( 'get_theme_data' => 'wp_get_theme()', '3.4' ),
144
- array( 'update_page_cache' => 'update_post_cache()', '3.4' ),
145
- array( 'clean_page_cache' => 'clean_post_cache()', '3.4' ),
146
- array( 'wp_explain_nonce' => 'wp_nonce_ays', '3.4.1' ),
147
- array( 'sticky_class' => 'post_class()', '3.5' ),
148
- array( '_get_post_ancestors' => '', '3.5' ),
149
- array( 'wp_load_image' => 'wp_get_image_editor()', '3.5' ),
150
- array( 'image_resize' => 'wp_get_image_editor()', '3.5' ),
151
- array( 'wp_get_single_post' => 'get_post()', '3.5' ),
152
- array( 'user_pass_ok' => 'wp_authenticate()', '3.5' ),
153
- array( '_save_post_hook' => '', '3.5' ),
154
- array( 'gd_edit_image_support' => 'wp_image_editor_supports', '3.5' ),
155
- array( 'get_user_id_from_string' => 'get_user_by()', '3.6' ),
156
- array( 'wp_convert_bytes_to_hr' => 'size_format()', '3.6' ),
157
-
158
- array( 'tinymce_include' => 'wp_tiny_mce()', '2.1' ),
159
-
160
- array( 'documentation_link' => '', '2.5' ),
161
-
162
- array( 'dropdown_categories' => 'wp_category_checklist()','2.6' ),
163
- array( 'dropdown_link_categories' => 'wp_link_category_checklist()','2.6' ),
164
-
165
- array( 'wp_dropdown_cats' => 'wp_dropdown_categories()','3.0' ),
166
- array( 'add_option_update_handler' => 'register_setting()','3.0' ),
167
- array( 'remove_option_update_handler' => 'unregister_setting()','3.0' ),
168
- array( 'codepress_get_lang' => '','3.0' ),
169
- array( 'codepress_footer_js' => '','3.0' ),
170
- array( 'use_codepress' => '','3.0' ),
171
- array( 'wp_shrink_dimensions' => 'wp_constrain_dimensions()','3.0' ),
172
-
173
- array( 'get_author_user_ids' => '','3.1' ),
174
- array( 'get_editable_authors' => '','3.1' ),
175
- array( 'get_editable_user_ids' => '','3.1' ),
176
- array( 'get_nonauthor_user_ids' => '','3.1' ),
177
- array( 'WP_User_Search' => 'WP_User_Query','3.1' ),
178
- array( 'get_others_unpublished_posts' => '','3.1' ),
179
- array( 'get_others_drafts' => '','3.1' ),
180
- array( 'get_others_pending' => '', '3.1' ),
181
-
182
- array( 'wp_dashboard_quick_press()' => '', '3.2' ),
183
- array( 'wp_tiny_mce' => 'wp_editor', '3.2' ),
184
- array( 'wp_preload_dialogs' => 'wp_editor()', '3.2' ),
185
- array( 'wp_print_editor_js' => 'wp_editor()', '3.2' ),
186
- array( 'wp_quicktags' => 'wp_editor()', '3.2' ),
187
- array( 'favorite_actions' => 'WP_Admin_Bar', '3.2' ),
188
-
189
- array( 'screen_layout' => '$current_screen->render_screen_layout()', '3.3' ),
190
- array( 'screen_options' => '$current_screen->render_per_page_options()', '3.3' ),
191
- array( 'screen_meta' => ' $current_screen->render_screen_meta()', '3.3' ),
192
- array( 'media_upload_image' => 'wp_media_upload_handler()', '3.3' ),
193
- array( 'media_upload_audio' => 'wp_media_upload_handler()', '3.3' ),
194
- array( 'media_upload_video' => 'wp_media_upload_handler()', '3.3' ),
195
- array( 'media_upload_file' => 'wp_media_upload_handler()', '3.3' ),
196
- array( 'type_url_form_image' => 'wp_media_insert_url_form( \'image\' )', '3.3' ),
197
- array( 'type_url_form_audio' => 'wp_media_insert_url_form( \'audio\' )', '3.3' ),
198
- array( 'type_url_form_video' => 'wp_media_insert_url_form( \'video\' )', '3.3' ),
199
- array( 'type_url_form_file' => 'wp_media_insert_url_form( \'file\' )', '3.3' ),
200
- array( 'add_contextual_help' => 'get_current_screen()->add_help_tab()', '3.3' ),
201
-
202
- array( 'get_allowed_themes' => 'wp_get_themes( array( \'allowed\' => true ) )', '3.4' ),
203
- array( 'get_broken_themes' => 'wp_get_themes( array( \'errors\' => true )', '3.4' ),
204
- array( 'current_theme_info' => 'wp_get_theme()', '3.4' ),
205
-
206
- array( '_insert_into_post_button' => '', '3.5' ),
207
- array( '_media_button' => '', '3.5' ),
208
- array( 'get_post_to_edit' => 'get_post()', '3.5' ),
209
- array( 'get_default_page_to_edit' => 'get_default_post_to_edit()', '3.5' ),
210
- array( 'wp_create_thumbnail' => 'image_resize()', '3.5' ),
211
-
212
- array( 'wp_nav_menu_locations_meta_box' => '', '3.6' ),
213
-
214
- array( 'the_attachment_links' => '', '3.7'),
215
- array( 'wp_update_core' => 'new Core_Upgrader()', '3.7'),
216
- array( 'wp_update_plugin' => 'new Plugin_Upgrader()', '3.7'),
217
- array( 'wp_update_theme' => 'new Theme_Upgrader()', '3.7'),
218
- array( '_search_terms_tidy' => '', '3.7' ),
219
- array( 'get_blogaddress_by_domain' => '', '3.7' ),
220
-
221
- array( 'get_screen_icon' => '', '3.8' ),
222
- array( 'screen_icon' => '', '3.8' ),
223
- array( 'wp_dashboard_incoming_links' => '', '3.8' ),
224
- array( 'wp_dashboard_incoming_links_control' => '', '3.8' ),
225
- array( 'wp_dashboard_incoming_links_output' => '', '3.8' ),
226
- array( 'wp_dashboard_plugins' => '', '3.8' ),
227
- array( 'wp_dashboard_primary_control' => '', '3.8' ),
228
- array( 'wp_dashboard_recent_comments_control' => '', '3.8' ),
229
- array( 'wp_dashboard_secondary' => '', '3.8' ),
230
- array( 'wp_dashboard_secondary_control' => '', '3.8' ),
231
- array( 'wp_dashboard_secondary_output' => '', '3.8' ),
232
-
233
- array( 'rich_edit_exists' => '', '3.9'),
234
- array( 'default_topic_count_text' => '', '3.9'),
235
- array( 'format_to_post' => '', '3.9'),
236
- array( 'get_current_site_name' => 'get_current_site()', '3.9'),
237
- array( 'wpmu_current_site' => '', '3.9'),
238
- array( '_relocate_children' => '', '3.9' ),
239
-
240
- array( 'get_all_category_ids' => 'get_terms()', '4.0' ),
241
- array( 'like_escape' => 'wpdb::esc_like()', '4.0' ),
242
- array( 'url_is_accessable_via_ssl' => '', '4.0' ),
243
- array( 'get_all_category_ids' => 'get_terms()', '4.0' ),
244
- array( 'like_escape' => 'wpdb::esc_like()', '4.0' ),
245
- array( 'url_is_accessable_via_ssl' => '', '4.0' ),
246
-
247
- array( 'prepare_control' => '', '4.1' ),
248
- array( 'add_tab' => '', '4.1' ),
249
- array( 'remove_tab' => '', '4.1' ),
250
- array( 'print_tab_image' => '', '4.1' ),
251
-
252
- array( 'setup_widget_addition_previews' => 'customize_dynamic_setting_args', '4.2' ),
253
- array( 'prepreview_added_sidebars_widgets' => 'customize_dynamic_setting_args', '4.2' ),
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' ),
267
- array( 'add_utility_page' => 'add_menu_page', '4.5' ),
268
- array( 'get_comments_popup_template' => '', '4.5' ),
269
- array( 'comments_popup_script' => '', '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 ) {
308
- checkcount();
309
- $key = key( $check );
310
- $alt = $check[ $key ];
311
- if ( preg_match( '/(?<!function)[\s?]' . $key . '\s?\(/', $phpfile, $matches ) ) {
312
- $filename = tc_filename( $php_key );
313
- $error = ltrim( rtrim( $matches[0], '(' ) );
314
- $version = $check[0];
315
- $grep = tc_grep( $error, $php_key );
316
-
317
- // Point out the deprecated function.
318
- $error_msg = sprintf(
319
- __( '%1$s found in the file %2$s. Deprecated since version %3$s.', 'theme-check' ),
320
- '<strong>' . $error . '()</strong>',
321
- '<strong>' . $filename . '</strong>',
322
- '<strong>' . $version . '</strong>'
323
- );
324
-
325
- // Add alternative function when available.
326
- if ( $alt ) {
327
- $error_msg .= ' ' . sprintf( __( 'Use %s instead.', 'theme-check' ), '<strong>' . $alt . '</strong>' );
328
- }
329
-
330
- // Add the precise code match that was found.
331
- $error_msg .= $grep;
332
-
333
- // Add the finalized error message.
334
- $this->error[] = '<span class="tc-lead tc-required">' . __('REQUIRED','theme-check') . '</span>: ' . $error_msg;
335
-
336
- $ret = false;
337
- }
338
- }
339
- }
340
- return $ret;
341
- }
342
-
343
- function getError() { return $this->error; }
344
- }
345
- $themechecks[] = new Deprecated;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/deregister.php DELETED
@@ -1,29 +0,0 @@
1
- <?php
2
- class DeregisterCheck implements themecheck {
3
- protected $error = array();
4
-
5
- function check( $php_files, $css_files, $other_files ) {
6
-
7
- $ret = true;
8
- checkcount();
9
-
10
- foreach ( $php_files as $file_path => $file_content ) {
11
-
12
- $filename = tc_filename( $file_path );
13
-
14
- if ( preg_match( '/wp_deregister_script/', $file_content) ) {
15
-
16
- $error = '/wp_deregister_script/';
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;
24
-
25
- }
26
-
27
- function getError() { return $this->error; }
28
- }
29
- $themechecks[] = new DeregisterCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/directories.php DELETED
@@ -1,36 +0,0 @@
1
- <?php
2
-
3
- class DirectoriesCheck implements themecheck {
4
- protected $error = array();
5
-
6
- function check( $php_files, $css_files, $other_files ) {
7
-
8
- $ret = true;
9
- $found = false;
10
-
11
- foreach ( $php_files as $name => $file ) {
12
- checkcount();
13
- if ( strpos( $name, '.git' ) !== false || strpos( $name, '.svn' ) !== false ) $found = true;
14
- }
15
-
16
- foreach ( $css_files as $name => $file ) {
17
- checkcount();
18
- if ( strpos( $name, '.git' ) !== false || strpos( $name, '.svn' ) !== false || strpos( $name, '.hg' ) !== false || strpos( $name, '.bzr' ) !== false ) $found = true;
19
- }
20
-
21
- foreach ( $other_files as $name => $file ) {
22
- checkcount();
23
- if ( strpos( $name, '.git' ) !== false || strpos( $name, '.svn' ) !== false || strpos( $name, '.hg' ) !== false || strpos( $name, '.bzr' ) !== false ) $found = true;
24
- }
25
-
26
- if ($found) {
27
- $this->error[] = sprintf('<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: ' . __( 'Please remove any extraneous directories like .git or .svn from the ZIP file before uploading it.', 'theme-check') );
28
- $ret = false;
29
- }
30
-
31
- return $ret;
32
- }
33
-
34
- function getError() { return $this->error; }
35
- }
36
- $themechecks[] = new DirectoriesCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/editorstyle.php DELETED
@@ -1,21 +0,0 @@
1
- <?php
2
-
3
- class EditorStyleCheck implements themecheck {
4
- protected $error = array();
5
-
6
- function check( $php_files, $css_files, $other_files ) {
7
- checkcount();
8
- $ret = true;
9
-
10
- $php = implode( ' ', $php_files );
11
-
12
- if ( strpos( $php, 'add_editor_style' ) === false ) {
13
- $this->error[] = '<span class="tc-lead tc-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__('No reference to <strong>add_editor_style()</strong> was found in the theme. It is recommended that the theme implement editor styling, so as to make the editor content match the resulting post output in the theme, for a better user experience.', 'theme-check' );
14
- }
15
-
16
- return $ret;
17
- }
18
-
19
- function getError() { return $this->error; }
20
- }
21
- $themechecks[] = new EditorStyleCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/favicon.php DELETED
@@ -1,33 +0,0 @@
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();
9
-
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;
28
- }
29
-
30
- function getError() { return $this->error; }
31
- }
32
-
33
- $themechecks[] = new FaviconCheck();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/generated.php DELETED
@@ -1,42 +0,0 @@
1
- <?php
2
-
3
- class GeneratedCheck implements themecheck {
4
- protected $error = array();
5
-
6
- function check( $php_files, $css_files, $other_files) {
7
-
8
- // combine all the php files into one string to make it easier to search
9
- $php = implode( ' ', $php_files );
10
-
11
- checkcount();
12
-
13
- $ret = true;
14
- if (
15
- //Artisteer
16
- strpos( $php, 'art_normalize_widget_style_tokens' ) !== false
17
- || strpos( $php, 'art_include_lib' ) !== false
18
- || strpos( $php, '_remove_last_slash($url) {' ) !== false
19
- || strpos( $php, 'adi_normalize_widget_style_tokens' ) !== false
20
- || strpos( $php, 'm_normalize_widget_style_tokens' ) !== false
21
- || strpos ( $php, "bw = '<!--- BEGIN Widget --->';" ) !== false
22
- || strpos ( $php, "ew = '<!-- end_widget -->';" ) !== false
23
- || strpos ( $php, "end_widget' => '<!-- end_widget -->'") !== false
24
- //Lubith
25
- || strpos ( $php, "Lubith") !== false
26
- //Templatetoaster
27
- || strpos ( $php, "templatetoaster_") !== false
28
- || strpos ( $php, "Templatetoaster_") !== false
29
- || strpos ( $php, "@package templatetoaster") !== false
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
-
37
- return $ret;
38
- }
39
-
40
- function getError() { return $this->error; }
41
- }
42
- $themechecks[] = new GeneratedCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/gravatar.php DELETED
@@ -1,24 +0,0 @@
1
- <?php
2
-
3
- class GravatarCheck implements themecheck {
4
- protected $error = array();
5
-
6
- function check( $php_files, $css_files, $other_files ) {
7
-
8
- $php = implode( ' ', $php_files );
9
-
10
- checkcount();
11
-
12
- $ret = true;
13
-
14
- if ( ( strpos( $php, 'get_avatar' ) === false ) && ( strpos( $php, 'wp_list_comments' ) === false ) ) {
15
- $this->error[] = '<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__("This theme doesn't seem to support the standard avatar functions. Use <strong>get_avatar</strong> or <strong>wp_list_comments</strong> to add this support.", 'theme-check' );
16
- $ret = false;
17
- }
18
-
19
- return $ret;
20
- }
21
-
22
- function getError() { return $this->error; }
23
- }
24
- $themechecks[] = new GravatarCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/i18n.php DELETED
@@ -1,70 +0,0 @@
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/iframes.php DELETED
@@ -1,29 +0,0 @@
1
- <?php
2
- class IframeCheck implements themecheck {
3
- protected $error = array();
4
-
5
- function check( $php_files, $css_files, $other_files ) {
6
- $ret = true;
7
-
8
- $checks = array(
9
- '/<(iframe)[^>]*>/' => __( 'iframes are sometimes used to load unwanted adverts and code on your site', 'theme-check' )
10
- );
11
-
12
- foreach ( $php_files as $php_key => $phpfile ) {
13
- foreach ( $checks as $key => $check ) {
14
- checkcount();
15
- if ( preg_match( $key, $phpfile, $matches ) ) {
16
- $filename = tc_filename( $php_key );
17
- $error = ltrim( $matches[1], '(' );
18
- $error = rtrim( $error, '(' );
19
- $grep = tc_grep( $error, $php_key );
20
- $this->error[] = sprintf('<span class="tc-lead tc-info">'.__('INFO','theme-check').'</span>: '.__('%1$s was found in the file %2$s %3$s.%4$s', 'theme-check'), '<strong>' . $error . '</strong>', '<strong>' . $filename . '</strong>', $check, $grep ) ;
21
- }
22
- }
23
- }
24
- return $ret;
25
- }
26
-
27
- function getError() { return $this->error; }
28
- }
29
- $themechecks[] = new IframeCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/include.php DELETED
@@ -1,29 +0,0 @@
1
- <?php
2
-
3
- class IncludeCheck implements themecheck {
4
- protected $error = array();
5
-
6
- function check( $php_files, $css_files, $other_files ) {
7
-
8
- $ret = true;
9
-
10
- $checks = array( '/(?<![a-z0-9_\'"])(?:requir|includ)e(?:_once)?\s?[\'"\(]/' => __( 'The theme appears to use include or require. If these are being used to include separate sections of a template from independent files, then <strong>get_template_part()</strong> should be used instead.', 'theme-check' ) );
11
-
12
- foreach ( $php_files as $php_key => $phpfile ) {
13
- foreach ( $checks as $key => $check ) {
14
- checkcount();
15
- if ( preg_match( $key, $phpfile, $matches ) ) {
16
- $filename = tc_filename( $php_key );
17
- $error = '/(?<![a-z0-9_\'"])(?:requir|includ)e(?:_once)?\s?[\'"\(]/';
18
- $grep = tc_preg( $error, $php_key );
19
- if ( basename($filename) !== 'functions.php' ) $this->error[] = sprintf ( '<span class="tc-lead tc-info">'.__('INFO','theme-check').'</span>: '.__('%1$s %2$s %3$s', 'theme-check' ), '<strong>' . $filename . '</strong>', $check, $grep );
20
- }
21
- }
22
-
23
- }
24
- return $ret;
25
- }
26
-
27
- function getError() { return $this->error; }
28
- }
29
- $themechecks[] = new IncludeCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/included-plugins.php DELETED
@@ -1,34 +0,0 @@
1
- <?php
2
- class IncludedPlugins implements themecheck {
3
- protected $error = array();
4
-
5
- function check( $php_files, $css_files, $other_files ) {
6
- $ret = true;
7
-
8
- $filenames = array();
9
-
10
- foreach ( $other_files as $other_key => $otherfile ) {
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 );
24
- $ret = false;
25
- }
26
- }
27
-
28
- return $ret;
29
- }
30
-
31
- function getError() { return $this->error; }
32
- }
33
-
34
- $themechecks[] = new IncludedPlugins;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/lineendings.php DELETED
@@ -1,43 +0,0 @@
1
- <?php
2
- class LineEndingsCheck implements themecheck {
3
- protected $error = array();
4
-
5
- function check( $php_files, $css_files, $other_files ) {
6
- $ret = true;
7
- foreach ( $php_files as $php_key => $phpfile ) {
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
- }
15
- }
16
- foreach ( $css_files as $css_key => $cssfile ) {
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
- }
24
- }
25
- foreach ( $other_files as $oth_key => $othfile ) {
26
- $e = pathinfo($oth_key);
27
- if ( isset( $e['extension'] ) && in_array( $e['extension'], array( 'txt','js' ) ) ) {
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
- }
35
- }
36
- }
37
- return $ret;
38
- }
39
-
40
- function getError() { return $this->error; }
41
- }
42
-
43
- $themechecks[] = new LineEndingsCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/links.php DELETED
@@ -1,34 +0,0 @@
1
- <?php
2
- class Check_Links implements themecheck {
3
- protected $error = array();
4
-
5
- function check( $php_files, $css_files, $other_files ) {
6
-
7
- $ret = true;
8
- global $data;
9
- foreach ( $php_files as $php_key => $phpfile ) {
10
- checkcount();
11
- $grep = '';
12
- // regex borrowed from TAC
13
- $url_re = '([[:alnum:]\-\.])+(\\.)([[:alnum:]]){2,4}([[:blank:][:alnum:]\/\+\=\%\&\_\\\.\~\?\-]*)';
14
- $title_re = '[[:blank:][:alnum:][:punct:]]*'; // 0 or more: any num, letter(upper/lower) or any punc symbol
15
- $space_re = '(\\s*)';
16
- if ( preg_match_all( "/(<a)(\\s+)(href" . $space_re . "=" . $space_re . "\"" . $space_re . "((http|https|ftp):\\/\\/)?)" . $url_re . "(\"" . $space_re . $title_re . $space_re . ">)" . $title_re . "(<\\/a>)/is", $phpfile, $out, PREG_SET_ORDER ) ) {
17
- $filename = tc_filename( $php_key );
18
- foreach( $out as $key ) {
19
- if ( preg_match( '/\<a\s?href\s?=\s?["|\'](.*?)[\'|"](.*?)\>(.*?)\<\/a\>/is', $key[0], $stripped ) ) {
20
- if ( !empty( $data['AuthorURI'] ) && !empty( $data['URI'] ) && $stripped[1] && !strpos( $stripped[1], $data['URI'] ) && !strpos( $stripped[1], $data['AuthorURI'] ) && !strpos( $stripped[1], 'wordpress.' ) ) {
21
- $grep .= tc_grep( $stripped[1], $php_key );
22
- }
23
- }
24
- }
25
- if ( $grep ) {
26
- $this->error[] = sprintf('<span class="tc-lead tc-info">'.__('INFO','theme-check').'</span>: '.__('Possible hard-coded links were found in the file %1$s.%2$s', 'theme-check'), '<strong>' . $filename . '</strong>', $grep);
27
- }
28
- }
29
- }
30
- return $ret;
31
- }
32
- function getError() { return $this->error; }
33
- }
34
- $themechecks[] = new Check_Links;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/malware.php DELETED
@@ -1,34 +0,0 @@
1
- <?php
2
- class MalwareCheck implements themecheck {
3
- protected $error = array();
4
-
5
- function check( $php_files, $css_files, $other_files ) {
6
- $ret = true;
7
-
8
- $checks = array(
9
- '/[^a-z0-9](?<!_)(file_get_contents|curl_exec|curl_init|readfile|fopen|fsockopen|pfsockopen|fclose|fread|fwrite|file_put_contents)\s?\(/' => __( 'File operations should use the WP_Filesystem methods instead of direct PHP filesystem calls', 'theme-check' ),
10
- );
11
-
12
- foreach ( $php_files as $php_key => $phpfile ) {
13
- foreach ( $checks as $key => $check ) {
14
- checkcount();
15
-
16
- if ( preg_match_all( $key, $phpfile, $matches ) ) {
17
- $filename = tc_filename( $php_key );
18
-
19
- foreach ($matches[1] as $match ) {
20
- $error = ltrim( $match, '(' );
21
- $error = rtrim( $error, '(' );
22
- $grep = tc_grep( $error, $php_key );
23
- $this->error[] = sprintf('<span class="tc-lead tc-warning">'.__('WARNING','theme-check').'</span>: '.__('%1$s was found in the file %2$s %3$s.%4$s', 'theme-check'), '<strong>' . $error. '</strong>', '<strong>' . $filename . '</strong>', $check, $grep );
24
- $ret = false;
25
- }
26
- }
27
- }
28
- }
29
- return $ret;
30
- }
31
-
32
- function getError() { return $this->error; }
33
- }
34
- $themechecks[] = new MalwareCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/navmenu.php DELETED
@@ -1,73 +0,0 @@
1
- <?php
2
-
3
- class NavMenuCheck implements themecheck {
4
- protected $error = array();
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;
68
- }
69
-
70
- function getError() { return $this->error; }
71
- }
72
-
73
- $themechecks[] = new NavMenuCheck();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/nongplsites.php DELETED
@@ -1,46 +0,0 @@
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 DELETED
@@ -1,27 +0,0 @@
1
- <?php
2
- class NonPrintableCheck implements themecheck {
3
- protected $error = array();
4
-
5
- function check( $php_files, $css_files, $other_files ) {
6
- $ret = true;
7
-
8
- foreach ( $php_files as $name => $content ) {
9
- checkcount();
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
-
20
- // return the pass/fail
21
- return $ret;
22
- }
23
-
24
- function getError() { return $this->error; }
25
- }
26
-
27
- $themechecks[] = new NonPrintableCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/phpshort.php DELETED
@@ -1,24 +0,0 @@
1
- <?php
2
- class PHPShortTagsCheck implements themecheck {
3
- protected $error = array();
4
-
5
- function check( $php_files, $css_files, $other_files ) {
6
-
7
- $ret = true;
8
-
9
- foreach ( $php_files as $php_key => $phpfile ) {
10
- checkcount();
11
- if ( preg_match( '/<\?(\=?)(?!php|xml)/i', $phpfile ) ) {
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
-
18
- return $ret;
19
- }
20
-
21
- function getError() { return $this->error; }
22
- }
23
-
24
- $themechecks[] = new PHPShortTagsCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/post-formats.php DELETED
@@ -1,38 +0,0 @@
1
- <?php
2
-
3
- class PostFormatCheck implements themecheck {
4
- protected $error = array();
5
-
6
- function check( $php_files, $css_files, $other_files ) {
7
- $ret = true;
8
-
9
- $php = implode( ' ', $php_files );
10
- $css = implode( ' ', $css_files );
11
-
12
- checkcount();
13
-
14
- $checks = array(
15
- '/add_theme_support\(\s?("|\')post-formats("|\')/m'
16
- );
17
-
18
- foreach ( $php_files as $php_key => $phpfile ) {
19
- foreach ( $checks as $check ) {
20
- checkcount();
21
- if ( preg_match( $check, $phpfile, $matches ) ) {
22
- if ( !strpos( $php, 'get_post_format' ) && !strpos( $php, 'has_post_format' ) && !strpos( $css, '.format' ) ) {
23
- $filename = tc_filename( $php_key );
24
- $matches[0] = str_replace(array('"',"'"),'', $matches[0]);
25
- $error = esc_html( rtrim($matches[0], '(' ) );
26
- $grep = tc_grep( rtrim($matches[0], '(' ), $php_key);
27
- $this->error[] = sprintf('<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('%1$s was found in the file %2$s. However get_post_format and/or has_post_format were not found, and no use of formats in the CSS was detected.', 'theme-check'), '<strong>' . $error . '</strong>', '<strong>' . $filename . '</strong>');
28
- $ret = false;
29
- }
30
- }
31
- }
32
- }
33
- return $ret;
34
- }
35
-
36
- function getError() { return $this->error; }
37
- }
38
- $themechecks[] = new PostFormatCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/postsnav.php DELETED
@@ -1,28 +0,0 @@
1
- <?php
2
-
3
- class PostPaginationCheck implements themecheck {
4
- protected $error = array();
5
-
6
- function check( $php_files, $css_files, $other_files ) {
7
-
8
- $ret = true;
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, 'posts_nav_link' ) === false &&
14
- strpos( $php, 'paginate_links' ) === false &&
15
- strpos( $php, 'the_posts_pagination' ) === false &&
16
- strpos( $php, 'the_posts_navigation' ) === false &&
17
- ( strpos( $php, 'previous_posts_link' ) === false && strpos( $php, 'next_posts_link' ) === false )
18
- ) {
19
- $this->error[] = '<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__("The theme doesn't have post pagination code in it. Use <strong>posts_nav_link()</strong> or <strong>paginate_links()</strong> or <strong>the_posts_pagination()</strong> or <strong>the_posts_navigation()</strong> or <strong>next_posts_link()</strong> and <strong>previous_posts_link()</strong> to add post pagination.", 'theme-check' );
20
- $ret = false;
21
- }
22
-
23
- return $ret;
24
- }
25
-
26
- function getError() { return $this->error; }
27
- }
28
- $themechecks[] = new PostPaginationCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/postthumb.php DELETED
@@ -1,27 +0,0 @@
1
- <?php
2
-
3
- class PostThumbnailCheck implements themecheck {
4
- protected $error = array();
5
-
6
- function check( $php_files, $css_files, $other_files ) {
7
-
8
- $ret = true;
9
-
10
- // combine all the php files into one string to make it easier to search
11
- $php = implode( ' ', $php_files );
12
- checkcount();
13
-
14
- if ( strpos( $php, 'the_post_thumbnail' ) === false ) {
15
- $this->error[] = '<span class="tc-lead tc-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__('No reference to <strong>the_post_thumbnail()</strong> was found in the theme. It is recommended that the theme implement this functionality instead of using custom fields for thumbnails.', 'theme-check' );
16
- }
17
-
18
- if ( strpos( $php, 'post-thumbnails' ) === false ) {
19
- $this->error[] = '<span class="tc-lead tc-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__('No reference to post-thumbnails was found in the theme. If the theme has a thumbnail like functionality, it should be implemented with <strong>add_theme_support( "post-thumbnails" )</strong> in the functions.php file.', 'theme-check' );
20
- }
21
-
22
- return $ret;
23
- }
24
-
25
- function getError() { return $this->error; }
26
- }
27
- $themechecks[] = new PostThumbnailCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/screenshot.php DELETED
@@ -1,45 +0,0 @@
1
- <?php
2
- class Screenshot_Checks implements themecheck {
3
- protected $error = array();
4
-
5
- function check( $php_files, $css_files, $other_files ) {
6
-
7
- $ret = true;
8
- $filenames = array();
9
-
10
- foreach ( $other_files as $other_key => $otherfile ) {
11
- array_push( $filenames, strtolower( basename( $other_key ) ) );
12
- }
13
-
14
- checkcount();
15
-
16
- if ( in_array( 'screenshot.png', $filenames ) || in_array( 'screenshot.jpg', $filenames ) ) {
17
-
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');
33
- }
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;
41
- }
42
-
43
- function getError() { return $this->error; }
44
- }
45
- $themechecks[] = new Screenshot_Checks;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/searchform.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
-
3
- class SearchFormCheck implements themecheck {
4
- protected $error = array();
5
-
6
- function check( $php_files, $css_files, $other_files ) {
7
-
8
- $ret = true;
9
- $checks = array( '/(include\s?\(\s?TEMPLATEPATH\s?\.?\s?["|\']\/searchform.php["|\']\s?\))/' => __( 'Please use <strong>get_search_form()</strong> instead of including searchform.php directly.', 'theme-check' ) );
10
- foreach ( $php_files as $php_key => $phpfile ) {
11
- foreach ($checks as $key => $check) {
12
- checkcount();
13
- if ( preg_match( $key, $phpfile, $out ) ) {
14
- $grep = tc_preg( $key, $php_key );
15
- $filename = tc_filename( $php_key );
16
- $this->error[] = sprintf('<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('%1$s %2$s%3$s', 'theme-check'), '<strong>' . $filename . '</strong>', $check, $grep);
17
- $ret = false;
18
- }
19
- }
20
- }
21
- return $ret;
22
- }
23
-
24
- function getError() { return $this->error; }
25
- }
26
- $themechecks[] = new SearchFormCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/style_needed.php DELETED
@@ -1,43 +0,0 @@
1
- <?php
2
- class Style_Needed implements themecheck {
3
- protected $error = array();
4
-
5
- function check( $php_files, $css_files, $other_files ) {
6
-
7
- $css = implode( ' ', $css_files );
8
- $ret = true;
9
-
10
- $checks = array(
11
- '[ \t\/*#]*Theme Name:' => __( '<strong>Theme name:</strong> is missing from your style.css header.', 'theme-check' ),
12
- '[ \t\/*#]*Description:' => __( '<strong>Description:</strong> is missing from your style.css header.', 'theme-check' ),
13
- '[ \t\/*#]*Author:' => __( '<strong>Author:</strong> is missing from your style.css header.', 'theme-check' ),
14
- '[ \t\/*#]*Version' => __( '<strong>Version:</strong> is missing from your style.css header.', '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' ),
23
- '\.alignright' => __( '<strong>.alignright</strong> css class is needed in your theme css.', 'theme-check' ),
24
- '\.aligncenter' => __( '<strong>.aligncenter</strong> css class is needed in your theme css.', 'theme-check' ),
25
- '\.wp-caption' => __( '<strong>.wp-caption</strong> css class is needed in your theme css.', 'theme-check' ),
26
- '\.wp-caption-text' => __( '<strong>.wp-caption-text</strong> css class is needed in your theme css.', 'theme-check' ),
27
- '\.gallery-caption' => __( '<strong>.gallery-caption</strong> css class is needed in your theme css.', 'theme-check' ),
28
- '\.screen-reader-text' => __( '<strong>.screen-reader-text</strong> css class is needed in your theme css. See See: <a href="http://codex.wordpress.org/CSS#WordPress_Generated_Classes">the Codex</a> for an example implementation.', 'theme-check' )
29
- );
30
-
31
- foreach ($checks as $key => $check) {
32
- checkcount();
33
- if ( !preg_match( '/' . $key . '/i', $css, $matches ) ) {
34
- $this->error[] = "<span class='tc-lead tc-required'>" . __('REQUIRED', 'theme-check' ) . "</span>: " . $check;
35
- $ret = false;
36
- }
37
- }
38
-
39
- return $ret;
40
- }
41
- function getError() { return $this->error; }
42
- }
43
- $themechecks[] = new Style_Needed;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/style_suggested.php DELETED
@@ -1,29 +0,0 @@
1
- <?php
2
- class Style_Suggested implements themecheck {
3
- protected $error = array();
4
-
5
- function check( $php_files, $css_files, $other_files ) {
6
-
7
- // combine all the css files into one string to make it easier to search
8
- $css = implode( ' ', $css_files );
9
-
10
- checkcount();
11
- $ret = true;
12
-
13
- $checks = array(
14
- '[ \t\/*#]*Theme URI:' => 'Theme URI:',
15
- '[ \t\/*#]*Author URI:' => 'Author URI:',
16
- );
17
-
18
- foreach ($checks as $key => $check) {
19
- if ( !preg_match( '/' . $key . '/i', $css, $matches ) ) {
20
- $this->error[] = sprintf('<span class="tc-lead tc-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__('%s is missing from your style.css header.', 'theme-check'), '<strong>' . $check . '</strong>' );
21
- }
22
- }
23
-
24
- return $ret;
25
- }
26
-
27
- function getError() { return $this->error; }
28
- }
29
- $themechecks[] = new Style_Suggested;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/style_tags.php DELETED
@@ -1,158 +0,0 @@
1
- <?php
2
- class Style_Tags implements themecheck {
3
- protected $error = array();
4
-
5
- function check( $php_files, $css_files, $other_files ) {
6
-
7
- checkcount();
8
- $ret = true;
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
- } else {
19
- $deprecated_tags = $this->get_deprecated_tags();
20
- $allowed_tags = $this->get_allowed_tags();
21
- $subject_tags = $this->get_subject_tags();
22
- $subject_tags_count = 0;
23
- $subject_tags_name = '';
24
-
25
- foreach ( $data['Tags'] as $tag ) {
26
-
27
- if ( strpos( strtolower( $tag ), "accessibility-ready") !== false ) {
28
- $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' );
29
- }
30
-
31
- if ( ! in_array( strtolower( $tag ), $allowed_tags ) ) {
32
- if ( in_array( strtolower( $tag ), $deprecated_tags ) ) {
33
- $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>' );
34
- $ret = false;
35
- } else {
36
- $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>' );
37
- $ret = false;
38
- }
39
- }
40
-
41
- if ( in_array( strtolower( $tag ), $subject_tags ) ) {
42
- $subject_tags_name .= strtolower( $tag ) . ', ';
43
- $subject_tags_count++;
44
- }
45
-
46
- if ( in_array( strtolower( $tag ), $allowed_tags ) ) {
47
- if ( count( array_keys ($data[ 'Tags' ], $tag ) ) > 1) {
48
- $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>' );
49
- $ret = false;
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
- }
60
- }
61
-
62
- return $ret;
63
- }
64
-
65
- function getError() { return $this->error; }
66
-
67
- /**
68
- * Get full list of allowed tags - including subject tags.
69
- *
70
- * @return array
71
- */
72
- private function get_allowed_tags() {
73
- $allowed_tags = array(
74
- 'grid-layout',
75
- 'one-column',
76
- 'two-columns',
77
- 'three-columns',
78
- 'four-columns',
79
- 'left-sidebar',
80
- 'right-sidebar',
81
- 'wide-blocks',
82
- 'flexible-header',
83
- 'footer-widgets',
84
- 'accessibility-ready',
85
- 'block-patterns',
86
- 'block-styles',
87
- 'buddypress',
88
- 'custom-background',
89
- 'custom-colors',
90
- 'custom-header',
91
- 'custom-logo',
92
- 'custom-menu',
93
- 'editor-style',
94
- 'featured-image-header',
95
- 'featured-images',
96
- 'front-page-post-form',
97
- 'full-width-template',
98
- 'full-site-editing',
99
- 'microformats',
100
- 'post-formats',
101
- 'rtl-language-support',
102
- 'sticky-post',
103
- 'theme-options',
104
- 'threaded-comments',
105
- 'translation-ready',
106
- );
107
- return array_merge( $allowed_tags, self::get_subject_tags() );
108
- }
109
-
110
- /**
111
- * Get the list of subject tags.
112
- *
113
- * @return array
114
- */
115
- private function get_subject_tags() {
116
- return array(
117
- 'blog',
118
- 'e-commerce',
119
- 'education',
120
- 'entertainment',
121
- 'food-and-drink',
122
- 'holiday',
123
- 'news',
124
- 'photography',
125
- 'portfolio',
126
- );
127
- }
128
-
129
- private function get_deprecated_tags() {
130
- return array(
131
- 'flexible-width',
132
- 'fixed-width',
133
- 'black',
134
- 'blue',
135
- 'brown',
136
- 'gray',
137
- 'green',
138
- 'orange',
139
- 'pink',
140
- 'purple',
141
- 'red',
142
- 'silver',
143
- 'tan',
144
- 'white',
145
- 'yellow',
146
- 'dark',
147
- 'light',
148
- 'fixed-layout',
149
- 'fluid-layout',
150
- 'responsive-layout',
151
- 'blavatar',
152
- 'holiday',
153
- 'photoblogging',
154
- 'seasonal',
155
- );
156
- }
157
- }
158
- $themechecks[] = new Style_Tags();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/tags.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- class TagCheck implements themecheck {
4
- protected $error = array();
5
-
6
- function check( $php_files, $css_files, $other_files ) {
7
-
8
- // combine all the php files into one string to make it easier to search
9
- $php = implode( ' ', $php_files );
10
- checkcount();
11
- $ret = true;
12
- if ( strpos( $php, 'the_tags' ) === false && strpos( $php, 'the_taxonomies' ) === false && strpos( $php, 'get_the_tag_list' ) === false && strpos( $php, 'get_the_term_list' ) === false ) {
13
- $this->error[] = "<span class='tc-lead tc-required'>" . __( 'REQUIRED', 'theme-check' ) . '</span>: '. __( "This theme doesn't seem to display tags. Modify it to display tags in appropriate locations.", "theme-check" );
14
- $ret = false;
15
- }
16
-
17
- return $ret;
18
- }
19
-
20
- function getError() { return $this->error; }
21
- }
22
- $themechecks[] = new TagCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/textdomain.php CHANGED
@@ -2,117 +2,136 @@
2
  class TextDomainCheck implements themecheck {
3
  protected $error = array();
4
 
5
- // rules come from WordPress core tool makepot.php, modified by me to have domain info
6
  var $rules = array(
7
- '__' => array('string', 'domain'),
8
- '_e' => array('string', 'domain'),
9
- '_c' => array('string', 'domain'),
10
- '_n' => array('singular', 'plural', 'domain'),
11
- '_n_noop' => array('singular', 'plural', 'domain'),
12
- '_nc' => array('singular', 'plural', 'domain'),
13
- '__ngettext' => array('singular', 'plural', 'domain'),
14
- '__ngettext_noop' => array('singular', 'plural', 'domain'),
15
- '_x' => array('string', 'context', 'domain'),
16
- '_ex' => array('string', 'context', 'domain'),
17
- '_nx' => array('singular', 'plural', 'context', 'domain'),
18
- '_nx_noop' => array('singular', 'plural', 'context', 'domain'),
19
- '_n_js' => array('singular', 'plural', 'domain'),
20
- '_nx_js' => array('singular', 'plural', 'context', 'domain'),
21
- 'esc_attr__' => array('string', 'domain'),
22
- 'esc_html__' => array('string', 'domain'),
23
- 'esc_attr_e' => array('string', 'domain'),
24
- 'esc_html_e' => array('string', 'domain'),
25
- 'esc_attr_x' => array('string', 'context', 'domain'),
26
- 'esc_html_x' => array('string', 'context', 'domain'),
27
- 'comments_number_link' => array('string', 'singular', 'plural', 'domain'),
28
  );
29
 
30
  // core names their themes differently
31
- var $exceptions = array( 'twentyten', 'twentyeleven', 'twentytwelve', 'twentythirteen', 'twentyfourteen', 'twentyfifteen', 'twentysixteen', 'twentyseventeen', 'twentyeighteen', 'twentynineteen', 'twentytwenty' );
32
 
33
- function check( $php_files, $css_files, $other_files ) {
34
- global $data, $themename;
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
- $ret = true;
 
37
  $error = '';
38
  checkcount();
39
 
40
  // make sure the tokenizer is available
41
- if ( !function_exists( 'token_get_all' ) ) {
42
  return true;
43
  }
44
 
45
- $funcs = array_keys($this->rules);
46
 
47
  $domains = array();
48
 
49
  foreach ( $php_files as $php_key => $phpfile ) {
50
- $error='';
51
 
52
  // tokenize the file
53
- $tokens = token_get_all($phpfile);
54
 
55
- $in_func = false;
56
- $args_started = false;
57
  $parens_balance = 0;
58
- $found_domain = false;
59
 
60
- foreach($tokens as $token) {
61
  $string_success = false;
62
 
63
- if (is_array($token)) {
64
  list($id, $text) = $token;
65
- if (T_STRING == $id && in_array($text, $funcs)) {
66
- $in_func = true;
67
- $func = $text;
68
  $parens_balance = 0;
69
- $args_started = false;
70
- $found_domain = false;
71
- } elseif (T_CONSTANT_ENCAPSED_STRING == $id) {
72
- if ($in_func && $args_started) {
73
- if (! isset( $this->rules[$func][$args_count] ) ) {
74
  // avoid a warning when too many arguments are in a function, cause a fail case
75
- $new_args = $args;
76
- $new_args[] = $text;
77
- $this->error[] = '<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check' ) . '</span>: '
78
- . sprintf (
79
- __( 'Found a translation function that has an incorrect number of arguments. Function %1$s, with the arguments %2$s', 'theme-check' ),
80
- '<strong>' . $func . '</strong>',
81
- '<strong>' . implode(', ',$new_args) . '</strong>'
 
 
 
82
  );
83
- } else if ($this->rules[$func][$args_count] == 'domain') {
84
  // strip quotes from the domain, avoids 'domain' and "domain" not being recognized as the same
85
- $text = str_replace(array('"', "'"), '', $text);
86
- $domains[] = $text;
87
- $found_domain=true;
88
  }
89
- if ($parens_balance == 1) {
90
  $args_count++;
91
  $args[] = $text;
92
  }
93
  }
94
  }
95
  $token = $text;
96
- } elseif ('(' == $token){
97
- if ($parens_balance == 0) {
98
- $args=array();
99
  $args_started = true;
100
- $args_count = 0;
101
  }
102
  ++$parens_balance;
103
- } elseif (')' == $token) {
104
  --$parens_balance;
105
- if ($in_func && 0 == $parens_balance) {
106
- if (!$found_domain) {
107
- $this->error[] = '<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check' ) . '</span>: '
108
- . sprintf (
109
- __( 'Found a translation function that is missing a text-domain. Function %1$s, with the arguments %2$s', 'theme-check' ),
110
- '<strong>' . $func . '</strong>',
111
- '<strong>' . implode(', ',$args) . '</strong>'
 
 
 
112
  );
113
  }
114
- $in_func = false;
115
- $func='';
116
  $args_started = false;
117
  $found_domain = false;
118
  }
@@ -120,35 +139,60 @@ class TextDomainCheck implements themecheck {
120
  }
121
  }
122
 
123
- $domains = array_unique($domains);
124
- $domainlist = implode( ', ', $domains );
125
- $domainscount = count($domains);
126
 
127
  // ignore core themes and uploads on w.org for this one check
128
- if ( !in_array($themename, $this->exceptions) && ! defined( 'WPORGPATH' ) ) {
129
- $correct_domain = sanitize_title_with_dashes($data['Name']);
130
- if ( $themename != $correct_domain ) {
131
- $this->error[] = '<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check' ) . '</span>: '
132
- . sprintf ( __( "Your theme appears to be in the wrong directory for the theme name. The directory name must match the slug of the theme. This theme's correct slug and text-domain is %s.", 'theme-check' ), '<strong>' . $correct_domain . '</strong>' ).
133
- '<br>'. __( '(If this is a child theme, you can ignore this error.)' , 'theme-check' );
 
 
 
 
 
 
134
  } elseif ( ! in_array( $correct_domain, $domains ) ) {
135
- $this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check' ) . '</span>: '
136
- . sprintf ( __( "This theme text domain does not match the theme's slug. The text domain used: %s", 'theme-check' ), '<strong>' . $domainlist . '</strong>' )
137
- . sprintf ( __( "This theme's correct slug and text-domain is %s.", 'theme-check' ), '<strong>' . $correct_domain . '</strong>' );
138
- $ret = false;
 
 
 
 
 
 
 
 
 
139
  }
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>' );
 
 
 
 
 
147
  } else {
148
- $this->error[] = '<span class="tc-lead tc-info">' . __( 'INFO', 'theme-check' ) . '</span>: '
149
- . __( "Only one text-domain is being used in this theme. Make sure it matches the theme's slug correctly so that the theme will be compatible with WordPress.org language packs.", 'theme-check' )
150
- . '<br>'
151
- . sprintf( __( 'The domain found is %s', 'theme-check'), '<strong>' . $domainlist . '</strong>' );
 
 
 
 
 
152
 
153
  }
154
 
@@ -159,6 +203,8 @@ class TextDomainCheck implements themecheck {
159
  return $ret;
160
  }
161
 
162
- function getError() { return $this->error; }
 
 
163
  }
164
- $themechecks[] = new TextDomainCheck;
2
  class TextDomainCheck implements themecheck {
3
  protected $error = array();
4
 
5
+ // rules come from WordPress core tool makepot.php, modified to have domain info.
6
  var $rules = array(
7
+ '__' => array( 'string', 'domain' ),
8
+ '_e' => array( 'string', 'domain' ),
9
+ '_c' => array( 'string', 'domain' ),
10
+ '_n' => array( 'singular', 'plural', 'domain' ),
11
+ '_n_noop' => array( 'singular', 'plural', 'domain' ),
12
+ '_nc' => array( 'singular', 'plural', 'domain' ),
13
+ '__ngettext' => array( 'singular', 'plural', 'domain' ),
14
+ '__ngettext_noop' => array( 'singular', 'plural', 'domain' ),
15
+ '_x' => array( 'string', 'context', 'domain' ),
16
+ '_ex' => array( 'string', 'context', 'domain' ),
17
+ '_nx' => array( 'singular', 'plural', 'context', 'domain' ),
18
+ '_nx_noop' => array( 'singular', 'plural', 'context', 'domain' ),
19
+ '_n_js' => array( 'singular', 'plural', 'domain' ),
20
+ '_nx_js' => array( 'singular', 'plural', 'context', 'domain' ),
21
+ 'esc_attr__' => array( 'string', 'domain' ),
22
+ 'esc_html__' => array( 'string', 'domain' ),
23
+ 'esc_attr_e' => array( 'string', 'domain' ),
24
+ 'esc_html_e' => array( 'string', 'domain' ),
25
+ 'esc_attr_x' => array( 'string', 'context', 'domain' ),
26
+ 'esc_html_x' => array( 'string', 'context', 'domain' ),
27
+ 'comments_number_link' => array( 'string', 'singular', 'plural', 'domain' ),
28
  );
29
 
30
  // core names their themes differently
31
+ var $exceptions = array( 'twentyten', 'twentyeleven', 'twentytwelve', 'twentythirteen', 'twentyfourteen', 'twentyfifteen', 'twentysixteen', 'twentyseventeen', 'twentyeighteen', 'twentynineteen', 'twentytwenty', 'twentytwentyone' );
32
 
33
+ protected $name = '';
34
+ protected $slug = '';
35
+ protected $is_wporg = false;
36
+
37
+ function set_context( $data ) {
38
+ if ( isset( $data['theme']['Name'] ) ) {
39
+ $this->name = $data['theme']['Name'];
40
+ }
41
+ if ( isset( $data['slug'] ) ) {
42
+ $this->slug = $data['slug'];
43
+ }
44
+
45
+ $this->is_wporg = ! empty( $data['is_wporg'] );
46
+ }
47
 
48
+ function check( $php_files, $css_files, $other_files ) {
49
+ $ret = true;
50
  $error = '';
51
  checkcount();
52
 
53
  // make sure the tokenizer is available
54
+ if ( ! function_exists( 'token_get_all' ) ) {
55
  return true;
56
  }
57
 
58
+ $funcs = array_keys( $this->rules );
59
 
60
  $domains = array();
61
 
62
  foreach ( $php_files as $php_key => $phpfile ) {
63
+ $error = '';
64
 
65
  // tokenize the file
66
+ $tokens = token_get_all( $phpfile );
67
 
68
+ $in_func = false;
69
+ $args_started = false;
70
  $parens_balance = 0;
71
+ $found_domain = false;
72
 
73
+ foreach ( $tokens as $token ) {
74
  $string_success = false;
75
 
76
+ if ( is_array( $token ) ) {
77
  list($id, $text) = $token;
78
+ if ( T_STRING == $id && in_array( $text, $funcs ) ) {
79
+ $in_func = true;
80
+ $func = $text;
81
  $parens_balance = 0;
82
+ $args_started = false;
83
+ $found_domain = false;
84
+ } elseif ( T_CONSTANT_ENCAPSED_STRING == $id ) {
85
+ if ( $in_func && $args_started ) {
86
+ if ( ! isset( $this->rules[ $func ][ $args_count ] ) ) {
87
  // avoid a warning when too many arguments are in a function, cause a fail case
88
+ $new_args = $args;
89
+ $new_args[] = $text;
90
+ $this->error[] = sprintf(
91
+ '<span class="tc-lead tc-warning">%s</span>: %s',
92
+ __( 'WARNING', 'theme-check' ),
93
+ sprintf(
94
+ __( 'Found a translation function that has an incorrect number of arguments. Function %1$s, with the arguments %2$s', 'theme-check' ),
95
+ '<strong>' . $func . '</strong>',
96
+ '<strong>' . implode( ', ', $new_args ) . '</strong>'
97
+ )
98
  );
99
+ } elseif ( $this->rules[ $func ][ $args_count ] == 'domain' ) {
100
  // strip quotes from the domain, avoids 'domain' and "domain" not being recognized as the same
101
+ $text = str_replace( array( '"', "'" ), '', $text );
102
+ $domains[] = $text;
103
+ $found_domain = true;
104
  }
105
+ if ( $parens_balance == 1 ) {
106
  $args_count++;
107
  $args[] = $text;
108
  }
109
  }
110
  }
111
  $token = $text;
112
+ } elseif ( '(' == $token ) {
113
+ if ( $parens_balance == 0 ) {
114
+ $args = array();
115
  $args_started = true;
116
+ $args_count = 0;
117
  }
118
  ++$parens_balance;
119
+ } elseif ( ')' == $token ) {
120
  --$parens_balance;
121
+ if ( $in_func && 0 == $parens_balance ) {
122
+ if ( ! $found_domain ) {
123
+ $this->error[] = sprintf(
124
+ '<span class="tc-lead tc-warning">%s</span>: %s',
125
+ __( 'WARNING', 'theme-check' ),
126
+ sprintf(
127
+ __( 'Found a translation function that is missing a text-domain. Function %1$s, with the arguments %2$s', 'theme-check' ),
128
+ '<strong>' . $func . '</strong>',
129
+ '<strong>' . implode( ', ', $args ) . '</strong>'
130
+ )
131
  );
132
  }
133
+ $in_func = false;
134
+ $func = '';
135
  $args_started = false;
136
  $found_domain = false;
137
  }
139
  }
140
  }
141
 
142
+ $domains = array_unique( $domains );
143
+ $domainlist = implode( ', ', $domains );
144
+ $domainscount = count( $domains );
145
 
146
  // ignore core themes and uploads on w.org for this one check
147
+ if ( ! in_array( $this->slug, $this->exceptions ) && ! $this->is_wporg ) {
148
+ $correct_domain = sanitize_title_with_dashes( $this->name );
149
+ if ( $this->slug != $correct_domain ) {
150
+ $this->error[] = sprintf(
151
+ '<span class="tc-lead tc-warning">%s</span> %s %s',
152
+ __( 'WARNING', 'theme-check' ),
153
+ sprintf(
154
+ __( "Your theme appears to be in the wrong directory for the theme name. The directory name must match the slug of the theme. This theme's correct slug and text-domain is %s.", 'theme-check' ),
155
+ '<strong>' . $correct_domain . '</strong>'
156
+ ),
157
+ __( '(If this is a child theme, you can ignore this error.)', 'theme-check' )
158
+ );
159
  } elseif ( ! in_array( $correct_domain, $domains ) ) {
160
+ $this->error[] = sprintf(
161
+ '<span class="tc-lead tc-required">%s</span> %s %s',
162
+ __( 'REQUIRED', 'theme-check' ),
163
+ sprintf(
164
+ __( "This theme text domain does not match the theme's slug. The text domain used: %s", 'theme-check' ),
165
+ '<strong>' . $domainlist . '</strong>'
166
+ ),
167
+ sprintf(
168
+ __( "This theme's correct slug and text-domain is %s.", 'theme-check' ),
169
+ '<strong>' . $correct_domain . '</strong>'
170
+ )
171
+ );
172
+ $ret = false;
173
  }
174
  }
175
 
176
  if ( $domainscount > 1 ) {
177
+ $this->error[] = sprintf(
178
+ '<span class="tc-lead tc-warning">%s</span> %s %s',
179
+ __( 'WARNING', 'theme-check' ),
180
+ __( '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' ),
181
+ sprintf(
182
+ __( 'The domains found are %s', 'theme-check' ),
183
+ '<strong>' . $domainlist . '</strong>'
184
+ )
185
+ );
186
  } else {
187
+ $this->error[] = sprintf(
188
+ '<span class="tc-lead tc-info">%s</span> %s %s',
189
+ __( 'INFO', 'theme-check' ),
190
+ __( "Only one text-domain is being used in this theme. Make sure it matches the theme's slug correctly so that the theme will be compatible with WordPress.org language packs.", 'theme-check' ),
191
+ sprintf(
192
+ __( 'The domain found is %s', 'theme-check' ),
193
+ '<strong>' . $domainlist . '</strong>'
194
+ )
195
+ );
196
 
197
  }
198
 
203
  return $ret;
204
  }
205
 
206
+ function getError() {
207
+ return $this->error;
208
+ }
209
  }
210
+ $themechecks[] = new TextDomainCheck();
checks/time_date.php DELETED
@@ -1,31 +0,0 @@
1
- <?php
2
- class Time_Date implements themecheck {
3
- protected $error = array();
4
-
5
- function check( $php_files, $css_files, $other_files ) {
6
-
7
- $ret = true;
8
-
9
- $checks = array(
10
- '/\sdate_i18n\(\s?["|\'][A-Za-z\s]+\s?["|\']\)/' => 'date_i18n( get_option( \'date_format\' ) )',
11
- '/[^get_]the_date\(\s?["|\'][A-Za-z\s]+\s?["|\']\)/' => 'the_date( get_option( \'date_format\' ) )',
12
- '/[^get_]the_time\(\s?["|\'][A-Za-z\s]+\s?["|\']\)/' => 'the_time( get_option( \'date_format\' ) )'
13
- );
14
-
15
- foreach ( $php_files as $php_key => $phpfile ) {
16
- foreach ( $checks as $key => $check ) {
17
- checkcount();
18
- if ( preg_match( $key, $phpfile, $matches ) ) {
19
- $filename = tc_filename( $php_key );
20
- $matches[0] = str_replace(array('"',"'"),'', $matches[0]);
21
- $error = trim( esc_html( rtrim( $matches[0], '(' ) ) );
22
- $this->error[] = sprintf( '<span class="tc-lead tc-info">' . __( 'INFO', 'theme-check' ) . '</span>: ' . __( 'At least one hard coded date was found in the file %1$s. Consider %2$s instead.', 'theme-check' ), '<strong>' . $filename . '</strong>', "<strong>get_option( 'date_format' )</strong>" );
23
- }
24
- }
25
- }
26
- return $ret;
27
- }
28
-
29
- function getError() { return $this->error; }
30
- }
31
- $themechecks[] = new Time_Date;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/title.php DELETED
@@ -1,70 +0,0 @@
1
- <?php
2
- /**
3
- * Checks for the title:
4
- * Are there <title> and </title> tags?
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>&lt;title&gt;</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>&lt;title&gt;</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
-
64
- return $ret;
65
- }
66
-
67
- function getError() { return $this->error; }
68
- }
69
-
70
- $themechecks[] = new Title_Checks();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/underscores.php DELETED
@@ -1,57 +0,0 @@
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();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/uri.php DELETED
@@ -1,31 +0,0 @@
1
- <?php
2
-
3
- class Check_URI implements themecheck {
4
- protected $error = array();
5
-
6
- function check( $php_files, $css_files, $other_files ) {
7
-
8
- checkcount();
9
- $ret = true;
10
- global $data;
11
-
12
- if ( !empty( $data['AuthorURI'] ) && !empty( $data['URI'] ) ) {
13
-
14
- if ( strtolower( preg_replace('/https?:\/\/|www./i', '', trim( $data['URI'] , '/' ) ) ) == strtolower( preg_replace('/https?:\/\/|www./i', '', trim( $data['AuthorURI'], '/' ) ) ) ) {
15
- $this->error[] = __('<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('Your Theme URI and Author URI should not be the same.', 'theme-check') );
16
- $ret = false;
17
- }
18
-
19
- //We allow .org user profiles as Author URI, so only check the Theme URI. We also allow WordPress.com links.
20
- if ( stripos( $data['URI'], 'wordpress.org' ) && $data[ 'AuthorName' ] <> "the WordPress team" || stripos( $data['URI'], 'w.org' ) && $data[ 'AuthorName' ] <> "the WordPress team" ) {
21
- $this->error[] .= __('<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('Using a WordPress.org Theme URI is reserved for official themes.', 'theme-check') );
22
- $ret = false;
23
- }
24
- }
25
-
26
- return $ret;
27
- }
28
-
29
- function getError() { return $this->error; }
30
- }
31
- $themechecks[] = new Check_URI;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/widgets.php DELETED
@@ -1,42 +0,0 @@
1
- <?php
2
-
3
- class WidgetsCheck implements themecheck {
4
- protected $error = array();
5
-
6
- function check( $php_files, $css_files, $other_files ) {
7
-
8
- $ret = true;
9
-
10
- // combine all the php files into one string to make it easier to search
11
- $php = implode( ' ', $php_files );
12
- checkcount();
13
-
14
- // no widgets registered or used...
15
- if ( strpos( $php, 'register_sidebar' ) === false && strpos( $php, 'dynamic_sidebar' ) === false ) {
16
- $this->error[] = "<span class='tc-lead tc-recommended'>" . __( "RECOMMENDED", 'theme-check') . '</span>: '. __( "This theme contains no sidebars/widget areas. See <a href='https://codex.wordpress.org/Widgets_API'>Widgets API</a>", "theme-check" );
17
- $ret = true;
18
- }
19
-
20
- if ( strpos( $php, 'register_sidebar' ) !== false && strpos( $php, 'dynamic_sidebar' ) === false ) {
21
- $this->error[] = "<span class='tc-lead tc-required'>" . __( "REQUIRED", 'theme-check') . '</span>: '. __( "The theme appears to use <strong>register_sidebar()</strong> but no <strong>dynamic_sidebar()</strong> was found. See: <a href='https://developer.wordpress.org/reference/functions/dynamic_sidebar/'>dynamic_sidebar</a><pre> &lt;?php dynamic_sidebar( \$index ); ?&gt;</pre>", "theme-check" );
22
- $ret = false;
23
- }
24
-
25
- if ( strpos( $php, 'register_sidebar' ) === false && strpos( $php, 'dynamic_sidebar' ) !== false ) {
26
- $this->error[] = "<span class='tc-lead tc-required'>" . __( "REQUIRED", 'theme-check') . '</span>: '. __( "The theme appears to use <strong>dynamic_sidebars()</strong> but no <strong>register_sidebar()</strong> was found. See: <a href='https://developer.wordpress.org/reference/functions/register_sidebar/'>register_sidebar</a><pre> &lt;?php register_sidebar( \$args ); ?&gt;</pre>", "theme-check" );
27
- $ret = false;
28
- }
29
-
30
- /**
31
- * There are widgets registered, is the widgets_init action present?
32
- */
33
- if ( strpos( $php, 'register_sidebar' ) !== false && preg_match( '/add_action\s*\(\s*("|\')widgets_init("|\')\s*,/', $php ) == false ) {
34
- $this->error[] = "<span class='tc-lead tc-required'>" . __( "REQUIRED", 'theme-check') . '</span>: '. sprintf( __( "Sidebars need to be registered in a custom function hooked to the <strong>widgets_init</strong> action. See: %s.", "theme-check" ), '<a href="https://developer.wordpress.org/reference/functions/register_sidebar/">register_sidebar()</a>' );
35
- $ret = false;
36
- }
37
- return $ret;
38
- }
39
-
40
- function getError() { return $this->error; }
41
- }
42
- $themechecks[] = new WidgetsCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
checks/worms.php DELETED
@@ -1,33 +0,0 @@
1
- <?php
2
- class WormCheck implements themecheck {
3
- protected $error = array();
4
-
5
- function check( $php_files, $css_files, $other_files ) {
6
- $ret = true;
7
- $php_files = array_merge( $php_files, $other_files );
8
- $checks = array(
9
- '/wshell\.php/'=> __( 'This may be a script used by hackers to get control of your server!', 'theme-check' ),
10
- '/ShellBOT/' => __( 'This may be a script used by hackers to get control of your server', 'theme-check' ),
11
- '/uname -a/' => __( 'Tells a hacker what operating system your server is running', 'theme-check' ),
12
- '/php \$[a-zA-Z]*=\'as\';/' => __( 'Symptom of the "Pharma Hack" <a href="http://blog.sucuri.net/2010/07/understanding-and-cleaning-the-pharma-hack-on-wordpress.html">[1]</a>', 'theme-check' ),
13
- '/defined?\(\'wp_class_support/' => __( 'Symptom of the "Pharma Hack" <a href="http://blog.sucuri.net/2010/07/understanding-and-cleaning-the-pharma-hack-on-wordpress.html">[1]</a>', 'theme-check' ),
14
- );
15
-
16
- foreach ( $php_files as $php_key => $phpfile ) {
17
- foreach ( $checks as $key => $check ) {
18
- checkcount();
19
- if ( preg_match( $key, $phpfile, $matches ) ) {
20
- $filename = tc_filename( $php_key );
21
- $error = $matches[0];
22
- $grep = tc_grep( $error, $php_key );
23
- $this->error[] = sprintf('<span class="tc-lead tc-required">'. __( 'REQUIRED', 'theme-check') . '</span>: <strong>%1$s</strong> %2$s%3$s', $filename, $check, $grep );
24
- $ret = false;
25
- }
26
- }
27
- }
28
- return $ret;
29
- }
30
-
31
- function getError() { return $this->error; }
32
- }
33
- $themechecks[] = new WormCheck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
main.php CHANGED
@@ -1,173 +1,148 @@
1
  <?php
2
- function check_main( $theme ) {
3
- global $themechecks, $data, $themename;
4
- $themename = $theme;
5
- $theme = get_theme_root( $theme ) . "/$theme";
6
- $files = listdir( $theme );
7
- $data = tc_get_theme_data( $theme . '/style.css' );
8
- if ( $data['Template'] ) {
9
- // This is a child theme, so we need to pull files from the parent, which HAS to be installed.
10
- $parent = get_theme_root( $data['Template'] ) . '/' . $data['Template'];
11
- if ( ! tc_get_theme_data( $parent . '/style.css' ) ) { // This should never happen but we will check while were here!
12
- echo '<h2>';
13
- printf(
14
- /* translators: The parent theme name. */
15
- esc_html__( 'Parent theme %1$s not found! You have to have parent AND child-theme installed!', 'theme-check' ),
16
- '<strong>' . esc_html( $data['Template'] ) . '</strong>'
17
- );
18
- echo '</h2>';
19
- return;
20
- }
21
- $parent_data = tc_get_theme_data( $parent . '/style.css' );
22
- $themename = basename( $parent );
23
- $files = array_merge( listdir( $parent ), $files );
24
  }
25
 
26
- if ( $files ) {
27
- foreach ( $files as $key => $filename ) {
28
- if ( substr( $filename, -4 ) === '.php' && ! is_dir( $filename ) ) {
29
- $php[ $filename ] = file_get_contents( $filename );
30
- $php[ $filename ] = tc_strip_comments( $php[ $filename ] );
31
- } elseif ( substr( $filename, -4 ) === '.css' && ! is_dir( $filename ) ) {
32
- $css[ $filename ] = file_get_contents( $filename );
33
- } else {
34
- // In local development it might be useful to skip other files
35
- // (non .php or .css files) in dev directories.
36
- if ( apply_filters( 'tc_skip_development_directories', false ) ) {
37
- if ( tc_is_other_file_in_dev_directory( $filename ) ) {
38
- continue;
39
- }
40
- }
41
- $other[ $filename ] = ( ! is_dir( $filename ) ) ? file_get_contents( $filename ) : '';
42
- }
43
- }
44
 
45
- // Run the checks.
46
- $success = run_themechecks( $php, $css, $other );
 
47
 
48
- global $checkcount;
 
 
 
 
49
 
50
- // Second loop, to display the errors.
51
- echo '<h2>' . esc_html__( 'Theme Info', 'theme-check' ) . ': </h2>';
52
- echo '<div class="theme-info">';
53
- if ( file_exists( trailingslashit( WP_CONTENT_DIR . '/themes' ) . trailingslashit( basename( $theme ) ) . 'screenshot.png' ) ) {
54
- $image = getimagesize( $theme . '/screenshot.png' );
55
- echo '<div style="float:right" class="theme-info"><img style="max-height:180px;" src="' . trailingslashit( WP_CONTENT_URL . '/themes' ) . trailingslashit( basename( $theme ) ) . 'screenshot.png" />';
56
- echo '<br /><div style="text-align:center">' . $image[0] . 'x' . $image[1] . ' ' . round( filesize( $theme . '/screenshot.png' ) / 1024 ) . 'k</div></div>';
57
- }
58
 
59
- echo ( ! empty( $data['Title'] ) ) ? '<p><label>' . esc_html__( 'Title', 'theme-check' ) . '</label><span class="info">' . esc_html( $data['Title'] ) . '</span></p>' : '';
60
- echo ( ! empty( $data['Version'] ) ) ? '<p><label>' . esc_html__( 'Version', 'theme-check' ) . '</label><span class="info">' . esc_html( $data['Version'] ) . '</span></p>' : '';
61
- echo ( ! empty( $data['AuthorName'] ) ) ? '<p><label>' . esc_html__( 'Author', 'theme-check' ) . '</label><span class="info">' . esc_html( $data['AuthorName'] ) . '</span></p>' : '';
62
- echo ( ! empty( $data['AuthorURI'] ) ) ? '<p><label>' . esc_html__( 'Author URI', 'theme-check' ) . '</label><span class="info"><a href="' . esc_attr( $data['AuthorURI'] ) . '">' . $data['AuthorURI'] . '</a></span></p>' : '';
63
- echo ( ! empty( $data['URI'] ) ) ? '<p><label>' . esc_html__( 'Theme URI', 'theme-check' ) . '</label><span class="info"><a href="' . esc_attr( $data['URI'] ) . '">' . $data['URI'] . '</a></span></p>' : '';
64
- echo ( ! empty( $data['License'] ) ) ? '<p><label>' . esc_html__( 'License', 'theme-check' ) . '</label><span class="info">' . esc_html( $data['License'] ) . '</span></p>' : '';
65
- echo ( ! empty( $data['License URI'] ) ) ? '<p><label>' . esc_html__( 'License URI', 'theme-check' ) . '</label><span class="info">' . $data['License URI'] . '</span></p>' : '';
66
- echo ( ! empty( $data['Tags'] ) ) ? '<p><label>' . esc_html__( 'Tags', 'theme-check' ) . '</label><span class="info">' . implode( ', ', $data['Tags'] ) . '</span></p>' : '';
67
- echo ( ! empty( $data['Description'] ) ) ? '<p><label>' . esc_html__( 'Description', 'theme-check' ) . '</label><span class="info">' . $data['Description'] . '</span></p>' : '';
68
 
69
- if ( $data['Template'] ) {
70
- if ( $data['Template Version'] > $parent_data['Version'] ) {
71
- echo '<p>' . sprintf(
72
- esc_html__( 'This child theme requires at least version %1$s of theme %2$s to be installed. You only have %3$s please update the parent theme.', 'theme-check' ),
73
- '<strong>' . esc_html( $data['Template Version'] ) . '</strong>',
74
- '<strong>' . esc_html( $parent_data['Title'] ) . '</strong>',
75
- '<strong>' . esc_html( $parent_data['Version'] ) . '</strong>'
76
- ) . '</p>';
77
- }
78
- echo '<p>' . sprintf(
79
- /* translators: %s: Name of the parent theme. */
80
- esc_html__( 'This is a child theme. The parent theme is: %s. These files have been included automatically!', 'theme-check' ),
81
- '<strong>' . esc_html( $data['Template'] ) . '</strong>'
82
- ) . '</p>';
83
- if ( empty( $data['Template Version'] ) ) {
84
- echo '<p>' . esc_html__( 'Child theme does not have the <strong>Template Version</strong> tag in style.css.', 'theme-check' ) . '</p>';
85
- } else {
86
- echo ( $data['Template Version'] < $parent_data['Version'] ) ? '<p>' . sprintf( esc_html__( 'Child theme is only tested up to version %1$s of %2$s breakage may occur! %3$s installed version is %4$s', 'theme-check' ), esc_html( $data['Template Version'] ), esc_html( $parent_data['Title'] ), esc_html( $parent_data['Title'] ), esc_html( $parent_data['Version'] ) ) . '</p>' : '';
87
- }
88
- }
89
- echo '</div><!-- .theme-info-->';
90
 
91
- $plugins = get_plugins( '/theme-check' );
92
- $version = explode( '.', $plugins['theme-check.php']['Version'] );
93
- echo '<p>' . sprintf(
94
- esc_html__( ' Running %1$s tests against %2$s using Guidelines Version: %3$s Plugin revision: %4$s', 'theme-check' ),
95
- '<strong>' . esc_html( $checkcount ) . '</strong>',
96
- '<strong>' . esc_html( $data['Title'] ) . '</strong>',
97
- '<strong>' . esc_html( $version[0] ) . '</strong>',
98
- '<strong>' . esc_html( $version[1] ) . '</strong>'
99
- ) . '</p>';
100
- $results = display_themechecks();
101
- if ( ! $success ) {
102
- echo '<h2>' . sprintf( esc_html__( 'One or more errors were found for %1$s.', 'theme-check' ), esc_html( $data['Title'] ) ) . '</h2>';
103
- } else {
104
- echo '<h2>' . sprintf( __( '%1$s passed the tests', 'theme-check' ), esc_html( $data['Title'] ) ) . '</h2>';
105
- tc_success();
106
  }
107
- if ( ! defined( 'WP_DEBUG' ) || WP_DEBUG === false ) {
108
- echo '<div class="updated">';
109
- echo '<span class="tc-fail">';
110
- echo esc_html__( 'WARNING', 'theme-check' );
111
- echo '</span> ';
112
- echo '<strong>';
113
- echo esc_html__( 'WP_DEBUG is not enabled!', 'theme-check' );
114
- echo '</strong>';
115
  printf(
116
- /* translators: %1$s is an opening anchor tag. %2$s is the closing part of the tag. */
117
- esc_html__( 'Please test your theme with %1$sdebug enabled%2$s before you upload!', 'theme-check' ),
118
- '<a href="https://wordpress.org/support/article/editing-wp-config-php/">',
119
- '</a>'
 
120
  );
121
- echo '</div>';
122
  }
123
- echo '<div class="tc-box">';
124
- echo '<ul class="tc-result">';
125
- echo wp_kses(
126
- $results,
127
- array(
128
- 'li' => array(),
129
- 'span' => array(
130
- 'class' => array(),
131
- ),
132
- 'strong' => array(),
133
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  );
135
- echo '</ul></div>';
136
  }
137
- }
138
 
139
- // Strip comments from a PHP file in a way that will not change the underlying structure of the file.
140
- function tc_strip_comments( $code ) {
141
- $strip = array(
142
- T_COMMENT => true,
143
- T_DOC_COMMENT => true,
144
- );
145
- $newlines = array(
146
- "\n" => true,
147
- "\r" => true,
 
 
148
  );
149
- $tokens = token_get_all( $code );
150
- reset( $tokens );
151
- $return = '';
152
- $token = current( $tokens );
153
- while ( $token ) {
154
- if ( ! is_array( $token ) ) {
155
- $return .= $token;
156
- } elseif ( ! isset( $strip[ $token[0] ] ) ) {
157
- $return .= $token[1];
158
- } else {
159
- for ( $i = 0, $token_length = strlen( $token[1] ); $i < $token_length; ++$i ) {
160
- if ( isset( $newlines[ $token[1][ $i ] ] ) ) {
161
- $return .= $token[1][ $i ];
162
- }
163
- }
164
- }
165
- $token = next( $tokens );
166
- }
167
- return $return;
168
  }
169
 
170
-
 
 
171
  function tc_intro() {
172
  ?>
173
  <h2><?php esc_html_e( 'About', 'theme-check' ); ?></h2>
@@ -179,14 +154,19 @@ function tc_intro() {
179
  esc_html__( 'Theme Check is maintained by %1$s and %2$s.', 'theme-check' ),
180
  '<a href="https://profiles.wordpress.org/otto42/">Otto42</a>',
181
  '<a href="https://profiles.wordpress.org/pross/">Pross</a>'
182
- ); ?></p>
183
- <p><?php printf( __( 'If you have found a bug or would like to make a suggestion or contribution, please leave a post on the <a href="%1$s">WordPress forums</a>, or talk about it with the Themes Team on <a href="%2$s">Make WordPress Themes</a> site.', 'theme-check' ), 'https://wordpress.org/tags/theme-check?forum_id=10', 'https://make.wordpress.org/themes/'); ?></p>
 
 
184
  <p><?php printf( __( 'The code for Theme Check can be contributed to on <a href="%s">GitHub</a>.', 'theme-check' ), 'https://github.com/WordPress/theme-check' ); ?></p>
185
  <h3><?php esc_html_e( 'Testers', 'theme-check' ); ?></h3>
186
  <p><a href="https://make.wordpress.org/themes/"><?php esc_html_e( 'The WordPress Themes Team', 'theme-check' ); ?></a></p>
187
  <?php
188
  }
189
 
 
 
 
190
  function tc_success() {
191
  ?>
192
  <div class="tc-success"><p><?php esc_html_e( 'Now that your theme has passed the basic tests you need to check it properly using the test data before you upload it to the WordPress Themes Directory.', 'theme-check' ); ?></p>
@@ -209,20 +189,25 @@ function tc_success() {
209
  <?php
210
  }
211
 
 
 
 
212
  function tc_form() {
213
- $themes = tc_get_themes();
214
  echo '<form action="themes.php?page=themecheck" method="post">';
215
  echo '<select name="themename">';
216
- foreach ( $themes as $name => $location ) {
217
- echo '<option ';
218
- if ( isset( $_POST['themename'] ) ) {
219
- echo ( $location['Stylesheet'] === $_POST['themename'] ) ? 'selected="selected" ' : '';
220
- } else {
221
- echo ( basename( STYLESHEETPATH ) === $location['Stylesheet'] ) ? 'selected="selected" ' : '';
222
- }
223
- echo ( basename( STYLESHEETPATH ) === $location['Stylesheet'] ) ? 'value="' . $location['Stylesheet'] . '" style="font-weight:bold;">' . $name . '</option>' : 'value="' . $location['Stylesheet'] . '">' . $name . '</option>';
 
224
  }
 
225
  echo '</select>';
 
226
  echo '<input class="button" type="submit" value="' . esc_attr__( 'Check it!', 'theme-check' ) . '" />';
227
  if ( defined( 'TC_PRE' ) || defined( 'TC_POST' ) ) {
228
  echo ' <input name="trac" type="checkbox" /> ' . esc_html__( 'Output in Trac format.', 'theme-check' );
@@ -232,28 +217,3 @@ function tc_form() {
232
  echo '</form>';
233
  }
234
 
235
- /**
236
- * Used to allow some directories to be skipped during development.
237
- *
238
- * @param string $filename a filename/path
239
- * @return boolean
240
- */
241
- function tc_is_other_file_in_dev_directory( $filename ) {
242
- $skip = false;
243
- // Filterable List of dirs that you may want to skip other files in during
244
- // development.
245
- $dev_dirs = apply_filters(
246
- 'tc_common_dev_directories',
247
- array(
248
- 'node_modules',
249
- 'vendor',
250
- )
251
- );
252
- foreach ( $dev_dirs as $dev_dir ) {
253
- if ( strpos( $filename, $dev_dir ) ) {
254
- $skip = true;
255
- break;
256
- }
257
- }
258
- return $skip;
259
- }
1
  <?php
2
+ /**
3
+ * Functions for displaying theme information, test results, and the form
4
+ *
5
+ * @package Theme Check
6
+ */
7
+
8
+ /**
9
+ * Present theme information and test results.
10
+ *
11
+ * @param string $theme_slug theme slug of the theme to be tested.
12
+ */
13
+ function check_main( $theme_slug ) {
14
+ global $checkcount;
15
+
16
+ /**
17
+ * Get theme data. Return early if the theme is not found.
18
+ *
19
+ * @link https://developer.wordpress.org/reference/functions/wp_get_theme/
20
+ */
21
+ $theme = wp_get_theme( $theme_slug );
22
+ if ( ! $theme->exists() ) {
23
+ return;
24
  }
25
 
26
+ // Run the checks.
27
+ $success = run_themechecks_against_theme( $theme, $theme_slug );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
+ // Display theme info.
30
+ echo '<h2>' . esc_html__( 'Theme Info', 'theme-check' ) . ': </h2>';
31
+ echo '<div class="theme-info">';
32
 
33
+ $screenshot = $theme->get_screenshot( 'relative' );
34
+ if ( $screenshot ) {
35
+ $screenshot_file = $theme->get_stylesheet_directory() . '/' . $screenshot;
36
+ $image_size = getimagesize( $screenshot_file );
37
+ $image_filesize = filesize( $screenshot_file );
38
 
39
+ echo '<div style="float:right" class="theme-info"><img style="max-height:180px;" src="' . esc_url( $theme->get_screenshot() ) . '" />';
40
+ echo '<br /><div style="text-align:center">' . intval( $image_size[0] ) . 'x' . intval( $image_size[1] ) . ' ' . round( $image_filesize / 1024 ) . 'k</div></div>';
41
+ }
 
 
 
 
 
42
 
43
+ echo ( ! empty( $theme['Title'] ) ) ? '<p><label>' . esc_html__( 'Title', 'theme-check' ) . '</label><span class="info">' . esc_html( $theme['Title'] ) . '</span></p>' : '';
44
+ echo ( ! empty( $theme['Version'] ) ) ? '<p><label>' . esc_html__( 'Version', 'theme-check' ) . '</label><span class="info">' . esc_html( $theme['Version'] ) . '</span></p>' : '';
45
+ echo ( ! empty( $theme->get( 'Author' ) ) ) ? '<p><label>' . esc_html__( 'Author', 'theme-check' ) . '</label><span class="info">' . esc_html( $theme->get( 'Author' ) ) . '</span></p>' : '';
46
+ echo ( ! empty( $theme->get( 'AuthorURI' ) ) ) ? '<p><label>' . esc_html__( 'Author URI', 'theme-check' ) . '</label><span class="info"><a href="' . esc_url( $theme->get( 'AuthorURI' ) ) . '">' . esc_html( $theme->get( 'AuthorURI' ) ) . '</a></span></p>' : '';
47
+ echo ( ! empty( $theme->get( 'ThemeURI' ) ) ) ? '<p><label>' . esc_html__( 'Theme URI', 'theme-check' ) . '</label><span class="info"><a href="' . esc_url( $theme->get( 'ThemeURI' ) ) . '">' . esc_html( $theme->get( 'ThemeURI' ) ) . '</a></span></p>' : '';
48
+ echo ( ! empty( $theme->get( 'License' ) ) ) ? '<p><label>' . esc_html__( 'License', 'theme-check' ) . '</label><span class="info">' . esc_html( $theme->get( 'License' ) ) . '</span></p>' : '';
49
+ echo ( ! empty( $theme->get( 'License URI' ) ) ) ? '<p><label>' . esc_html__( 'License URI', 'theme-check' ) . '</label><span class="info">' . esc_html( $theme->get( 'License URI' ) ) . '</span></p>' : '';
50
+ echo ( ! empty( $theme['Tags'] ) ) ? '<p><label>' . esc_html__( 'Tags', 'theme-check' ) . '</label><span class="info">' . esc_html( implode( ', ', $theme['Tags'] ) ) . '</span></p>' : '';
51
+ echo ( ! empty( $theme['Description'] ) ) ? '<p><label>' . esc_html__( 'Description', 'theme-check' ) . '</label><span class="info">' . esc_html( $theme['Description'] ) . '</span></p>' : '';
52
 
53
+ if ( $theme->parent() ) {
54
+ echo '<p>';
55
+ printf(
56
+ /* translators: %s: Name of the parent theme. */
57
+ esc_html__( 'This is a child theme. The parent theme is: %s. These files have been included automatically!', 'theme-check' ),
58
+ '<strong>' . esc_html( $theme['Template'] ) . '</strong>'
59
+ );
60
+ echo '</p>';
61
+ }
 
 
 
 
 
 
 
 
 
 
 
 
62
 
63
+ if ( $theme['Template Version'] /* Not supported by WordPress */ ) {
64
+ $parent_theme = $theme->parent();
65
+ if ( $theme['Template Version'] > $parent_theme['Version'] ) {
66
+ echo '<p>';
67
+ printf(
68
+ esc_html__( 'This child theme requires at least version %1$s of theme %2$s to be installed. You only have %3$s please update the parent theme.', 'theme-check' ),
69
+ '<strong>' . esc_html( $theme['Template Version'] ) . '</strong>',
70
+ '<strong>' . esc_html( $parent_theme['Title'] ) . '</strong>',
71
+ '<strong>' . esc_html( $parent_theme['Version'] ) . '</strong>'
72
+ );
73
+ echo '</p>';
 
 
 
 
74
  }
75
+
76
+ if ( empty( $theme['Template Version'] ) ) {
77
+ echo '<p>' . __( 'Child theme does not have the <strong>Template Version</strong> tag in style.css.', 'theme-check' ) . '</p>';
78
+ } elseif ( $theme['Template Version'] < $parent_theme['Version'] ) {
79
+ echo '<p>';
 
 
 
80
  printf(
81
+ esc_html__( 'Child theme is only tested up to version %1$s of %2$s breakage may occur! %3$s installed version is %4$s', 'theme-check' ),
82
+ esc_html( $theme['Template Version'] ),
83
+ esc_html( $parent_theme['Title'] ),
84
+ esc_html( $parent_theme['Title'] ),
85
+ esc_html( $parent_theme['Version'] )
86
  );
87
+ echo '</p>';
88
  }
89
+ }
90
+ echo '</div><!-- .theme-info-->';
91
+
92
+ $plugins = get_plugins( '/theme-check' );
93
+ $version = explode( '.', $plugins['theme-check.php']['Version'] );
94
+ echo '<p>' . sprintf(
95
+ esc_html__( 'Running %1$s tests against %2$s using Guidelines Version: %3$s Plugin revision: %4$s', 'theme-check' ),
96
+ '<strong>' . esc_html( $checkcount ) . '</strong>',
97
+ '<strong>' . esc_html( $theme['Title'] ) . '</strong>',
98
+ '<strong>' . esc_html( $version[0] ) . '</strong>',
99
+ '<strong>' . esc_html( $version[1] ) . '</strong>'
100
+ ) . '</p>';
101
+
102
+ $results = display_themechecks();
103
+
104
+ if ( ! $success ) {
105
+ echo '<h2>' . sprintf( __( 'One or more errors were found for %1$s.', 'theme-check' ), esc_html( $theme['Title'] ) ) . '</h2>';
106
+ } else {
107
+ echo '<h2>' . sprintf( __( '%1$s passed the tests', 'theme-check' ), esc_html( $theme['Title'] ) ) . '</h2>';
108
+ tc_success();
109
+ }
110
+
111
+ if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {
112
+ echo '<div class="updated">';
113
+ echo '<span class="tc-fail">';
114
+ echo esc_html__( 'WARNING', 'theme-check' );
115
+ echo '</span> ';
116
+ echo '<strong>';
117
+ echo esc_html__( 'WP_DEBUG is not enabled!', 'theme-check' );
118
+ echo '</strong>';
119
+ printf(
120
+ /* translators: %1$s is an opening anchor tag. %2$s is the closing part of the tag. */
121
+ esc_html__( 'Please test your theme with %1$sdebug enabled%2$s before you upload!', 'theme-check' ),
122
+ '<a href="https://wordpress.org/support/article/editing-wp-config-php/">',
123
+ '</a>'
124
  );
125
+ echo '</div>';
126
  }
 
127
 
128
+ echo '<div class="tc-box">';
129
+ echo '<ul class="tc-result">';
130
+ echo wp_kses(
131
+ $results,
132
+ array(
133
+ 'li' => array(),
134
+ 'span' => array(
135
+ 'class' => array(),
136
+ ),
137
+ 'strong' => array(),
138
+ )
139
  );
140
+ echo '</ul></div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  }
142
 
143
+ /**
144
+ * Present information about the plugin.
145
+ */
146
  function tc_intro() {
147
  ?>
148
  <h2><?php esc_html_e( 'About', 'theme-check' ); ?></h2>
154
  esc_html__( 'Theme Check is maintained by %1$s and %2$s.', 'theme-check' ),
155
  '<a href="https://profiles.wordpress.org/otto42/">Otto42</a>',
156
  '<a href="https://profiles.wordpress.org/pross/">Pross</a>'
157
+ );
158
+ ?>
159
+ </p>
160
+ <p><?php printf( __( 'If you have found a bug or would like to make a suggestion or contribution, please leave a post on the <a href="%1$s">WordPress forums</a>, or talk about it with the Themes Team on <a href="%2$s">Make WordPress Themes</a> site.', 'theme-check' ), 'https://wordpress.org/tags/theme-check?forum_id=10', 'https://make.wordpress.org/themes/' ); ?></p>
161
  <p><?php printf( __( 'The code for Theme Check can be contributed to on <a href="%s">GitHub</a>.', 'theme-check' ), 'https://github.com/WordPress/theme-check' ); ?></p>
162
  <h3><?php esc_html_e( 'Testers', 'theme-check' ); ?></h3>
163
  <p><a href="https://make.wordpress.org/themes/"><?php esc_html_e( 'The WordPress Themes Team', 'theme-check' ); ?></a></p>
164
  <?php
165
  }
166
 
167
+ /**
168
+ * Present information about submitting themes.
169
+ */
170
  function tc_success() {
171
  ?>
172
  <div class="tc-success"><p><?php esc_html_e( 'Now that your theme has passed the basic tests you need to check it properly using the test data before you upload it to the WordPress Themes Directory.', 'theme-check' ); ?></p>
189
  <?php
190
  }
191
 
192
+ /**
193
+ * Print the form for selecting the theme to test.
194
+ */
195
  function tc_form() {
 
196
  echo '<form action="themes.php?page=themecheck" method="post">';
197
  echo '<select name="themename">';
198
+
199
+ $selected_theme = isset( $_POST['themename'] ) ? wp_unslash( $_POST['themename'] ) : get_stylesheet();
200
+ foreach ( wp_get_themes() as $theme ) {
201
+ printf(
202
+ '<option %s value="%s">%s</option>',
203
+ selected( $selected_theme, $theme['Stylesheet'], false ),
204
+ esc_attr( $theme['Stylesheet'] ),
205
+ esc_html( $theme['Name'] )
206
+ );
207
  }
208
+
209
  echo '</select>';
210
+
211
  echo '<input class="button" type="submit" value="' . esc_attr__( 'Check it!', 'theme-check' ) . '" />';
212
  if ( defined( 'TC_PRE' ) || defined( 'TC_POST' ) ) {
213
  echo ' <input name="trac" type="checkbox" /> ' . esc_html__( 'Output in Trac format.', 'theme-check' );
217
  echo '</form>';
218
  }
219
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
  === Theme Check ===
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: 20200922.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
 
@@ -54,4 +54,4 @@ If **either** of these two vars are defined a new trac tickbox will appear next
54
  == Changelog ==
55
 
56
  = 20200504.1 =
57
- * Changes can be found in the changelog.txt file.
1
  === Theme Check ===
2
  Contributors: Otto42, pross, poena, dingo-d, acosmin, joyously
3
  Requires at Least: 3.7
4
+ Tested Up To: 5.8
5
  Tags: template, theme, check, checker, tool, wordpress.org, upload, uploader, test, guideline, review
6
+ Stable tag: 20210617
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
 
54
  == Changelog ==
55
 
56
  = 20200504.1 =
57
+ * Changes can be found in the changelog.txt file.
theme-check.php CHANGED
@@ -4,7 +4,7 @@
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: 20200922.1
8
  * Text Domain: theme-check
9
  * License: GPLv2
10
  * License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -21,7 +21,7 @@ class ThemeCheckMain {
21
  }
22
 
23
  function load_styles() {
24
- wp_enqueue_style( 'style', plugins_url( 'assets/style.css', __FILE__ ), null, null, 'screen' );
25
  }
26
 
27
  function themecheck_add_page() {
@@ -49,19 +49,21 @@ class ThemeCheckMain {
49
  <h1><?php echo esc_html_x( 'Theme Check', 'title of the main page', 'theme-check' ); ?></h1>
50
  <div class="theme-check">
51
  <?php
52
- tc_form();
53
  if ( ! isset( $_POST['themename'] ) ) {
54
  tc_intro();
55
-
56
  }
57
 
58
  if ( isset( $_POST['themename'] ) ) {
59
  check_admin_referer( 'themecheck-nonce' );
 
60
  if ( isset( $_POST['trac'] ) ) {
61
  define( 'TC_TRAC', true );
62
  }
 
63
  wp_raise_memory_limit();
64
- check_main( $_POST['themename'] );
 
65
  }
66
  ?>
67
  </div> <!-- .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: 20210617
8
  * Text Domain: theme-check
9
  * License: GPLv2
10
  * License URI: https://www.gnu.org/licenses/gpl-2.0.html
21
  }
22
 
23
  function load_styles() {
24
+ wp_enqueue_style( 'style', plugins_url( 'assets/style.css', __FILE__ ), array(), '1', 'screen' );
25
  }
26
 
27
  function themecheck_add_page() {
49
  <h1><?php echo esc_html_x( 'Theme Check', 'title of the main page', 'theme-check' ); ?></h1>
50
  <div class="theme-check">
51
  <?php
52
+ tc_form();
53
  if ( ! isset( $_POST['themename'] ) ) {
54
  tc_intro();
 
55
  }
56
 
57
  if ( isset( $_POST['themename'] ) ) {
58
  check_admin_referer( 'themecheck-nonce' );
59
+
60
  if ( isset( $_POST['trac'] ) ) {
61
  define( 'TC_TRAC', true );
62
  }
63
+
64
  wp_raise_memory_limit();
65
+
66
+ check_main( wp_unslash( $_POST['themename'] ) );
67
  }
68
  ?>
69
  </div> <!-- .theme-check-->