Theme Check - Version 20151211.1

Version Description

  • Full sync with Github and all the changes that have happened there.
  • Release for 4.4 deprecated functions.
Download this release

Release Info

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

Version 20151211.1

assets/gray-grad.png ADDED
Binary file
assets/style.css ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .tc-box {
2
+ padding:20px 0;
3
+ border-top:1px solid #dfdfdf;
4
+ }
5
+ .tc-warning, .tc-required, .tc-fail {
6
+ color:red;
7
+ }
8
+ .tc-recommended, .tc-pass {
9
+ color: green;
10
+ }
11
+ .tc-info {
12
+ color: blue;
13
+ }
14
+ .tc-grep span {
15
+ background: yellow;
16
+ }
17
+ pre {
18
+ white-space: pre-wrap;
19
+ }
20
+ .tc-success {
21
+ margin:0 20px 20px 20px;
22
+ background:#e6ffe2;
23
+ border:1px solid #d1eecc;
24
+ }
25
+ form {
26
+ margin:20px auto;
27
+ }
28
+ .theme-check {
29
+ margin:20px auto;
30
+ border:1px solid #dfdfdf;
31
+ -moz-border-radius:5px;
32
+ -khtml-border-radius:5px;
33
+ -webkit-border-radius:5px;
34
+ border-radius:5px;
35
+ }
36
+ .theme-check h2 {
37
+ margin:0 0 20px 0;
38
+ padding:0 20px;
39
+ background:#dfdfdf url("gray-grad.png") repeat-x left top;
40
+ font-size:20px;
41
+ border-bottom:1px solid #ccc;
42
+ }
43
+ .theme-check p {
44
+ padding:5px 20px;
45
+ }
46
+ .theme-check form {
47
+ margin-left:20px;
48
+ }
49
+ .theme-check ul {
50
+ margin-left:20px;
51
+ }
52
+ .theme-check h3 {
53
+ margin:0 0 10px 20px;
54
+ padding:0;
55
+ }
56
+ .theme-check ul {
57
+ margin-bottom:10px;
58
+ }
59
+ .theme-info {
60
+ padding:10px;
61
+ border:1px solid #dfdfdf;
62
+ margin:10px 20px 0 20px;
63
+ }
64
+ .theme-info p {
65
+ padding:0;
66
+ margin-bottom:10px;
67
+ }
68
+ .theme-info label {
69
+ float:left;
70
+ width:100px;
71
+ font-weight:bold;
72
+ display:block;
73
+ }
74
+ .theme-info span.info {
75
+ margin-left:100px;
76
+ display:block;
77
+ }
changelog.txt ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ = 20140929.1 =
2
+ * Added new checks and updates from Frank Klein at Automattic. Thanks Frank!
3
+ * Updated deprecated function listings
4
+ * Customizer check: All add_settings must use sanitization callbacks, for security
5
+ * Plugin territory checks: Themes must not register post types or taxonomies or add shortcodes for post content
6
+ * Widgets: Calls to register_sidebar must be called from the widgets_init action hook
7
+ * Title: <title> tags must exist and not have anything in them other than a call to wp_title()
8
+ * CDN: Checks for use of common CDNs (recommended only)
9
+ * Note: Changed plugin and author URIs due to old URIs being invalid. These may change again in the future, the URIs to my own site are temporarily only.
10
+
11
+ = 20131213.1 =
12
+ * Corrected errors not being displayed by the plugin and it incorrectly giving a "pass" result to everything.
13
+
14
+ = 20131212.1 =
15
+ * Updated for 3.8
16
+ * Most files have changed for better I18N support, so the language files were removed temporarily until translation can be redone.
17
+
18
+ = 20121211.1 =
19
+ * Updated for 3.5
20
+ * Remove Paypal button.
21
+
22
+ = 20110805.1 =
23
+ * TimThumb checks removed.
24
+ * Proper i18n loading. Fixes http://bit.ly/ouD5Ke.
25
+ * Screenshot now previewed in results, with filesize and dimensions.
26
+
27
+ = 20110602.2 =
28
+ * New file list functions hidden folders now detectable.
29
+ * Better fopen checks.
30
+ * TimThumb version bump
31
+
32
+ = 20110602.1 =
33
+ * DOS/UNIX line ending style checks are now a requirement for proper theme uploading.
34
+ * Timthumb version bump
35
+ * Several fixes reported by GaryJ
36
+ * 3.2 deprecated functions added
37
+
38
+ = 20110412.1 =
39
+ * Fix regex's
40
+ * Added check for latest footer injection hack.
41
+ * Fix tags check to use new content function correctly
42
+ * Sync of all changes made for wporg uploader theme-check.
43
+ * Updated checks post 3.1. added screenshot check to svn.
44
+ * Fix links check to not return a false failure in some cases
45
+ * rm one of the checks that causes problems on wporg uploader (and which is also unnecessary)
46
+ * Move unneeded functions out of checkbase into main.php.
47
+ * Minor formatting changes only (spacing and such)
48
+ * Add check for wp_link_pages() + fix eval() check
49
+
50
+ = 20110219.2 =
51
+ * Merged new UI props Gua Bob [1](http://guabob.com/)
52
+ * Last tested theme is always pre-selected in the themes list.
53
+ * Fixed php error in admin_menu.php
54
+
55
+ = 20110219.1 =
56
+ * See [commit log](https://github.com/Pross/theme-check/commits/) for changes.
57
+
58
+ = 20110201.2 =
59
+ * UI bug fixes [forum post](http://bit.ly/ff7amN) props Mamaduka.
60
+ * Textdomain checks for twentyten and no domain.
61
+ * Fix div not closing props Mamaduka.
62
+
63
+ = 20110201.1 =
64
+ * i18n working
65
+ * sr_RS de_DE ro_RO langs props Daniel Tara and Emil Uzelac.
66
+ * Child theme support added, checks made against parent AND child at runtime.
67
+ * Trac formatting button added for reviewers.
68
+
69
+ = 20101228.3 =
70
+ * Last revision for 3.1 (hopefully)
71
+ * Chips suggestion of checking for inclusion of searchform.php ( not
72
+ perfect yet, need more examples to look for ).
73
+ * add_theme_page is required, all others flagged and displayed with line
74
+ numbers.
75
+ * <?= detected properly, short tags outputted with line umbers.
76
+ * Mostly internationalized, needs translations now.
77
+ * Bug fixes.
78
+
79
+ = 20101228.2 =
80
+ * Added menu checking.
81
+ * ThemeURI AuthourURI added to results.
82
+ * Lots of small fixes.
83
+ * Started translation.
84
+
85
+ = 20101228.1 =
86
+ * Fix embed_defaults filter check and stylesheet file data check.
87
+
88
+ = 20101226.1 =
89
+ * Whole system redesign to allow easier synching with WordPress.org uploader. Many other additions/subtractions/changes as well.
90
+ * WordPress 3.1 guidelines added, to help theme authors ensure compatibility for upcoming release.
91
+
92
+ = 20101110.7 =
93
+ * Re-added malware.php checks for fopen and file_get_contents (INFO)
94
+ * fixed a couple of undefined index errors.
95
+
96
+ = 20101110.4_r2 =
97
+ * Fixed Warning: Wrong parameter count for stristr()
98
+
99
+ = 20101110.4_r1 =
100
+ * Added `echo` to suggested.php
101
+
102
+ = 20101110.4 =
103
+ * Fixed deprecated function call to get_plugins()
104
+
105
+ = 20101110.3 =
106
+ * Fixed undefined index.
107
+
108
+ = 20101110.2 =
109
+ * Missing `<` in main.php
110
+ * Added conditional checks for licence.txt OR Licence tags in style.css
111
+ * UI improvements.
112
+
113
+ = 20101110.1 =
114
+ * Date fix!
115
+
116
+ = 10112010_r1 =
117
+ * Fixed hardcoded links check. Added FAQ
118
+
119
+ = 10112010 =
120
+ * First release.
checkbase.php ADDED
@@ -0,0 +1,320 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
10
+ // interface that all checks should implement
11
+ interface themecheck
12
+ {
13
+ // should return true for good/okay/acceptable, false for bad/not-okay/unacceptable
14
+ public function check( $php_files, $css_files, $other_files );
15
+
16
+ // should return an array of strings explaining any problems found
17
+ public function getError();
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
+
39
+ function display_themechecks() {
40
+ $results = '';
41
+ global $themechecks;
42
+ $errors = array();
43
+ foreach ($themechecks as $check) {
44
+ if ($check instanceof themecheck) {
45
+ $error = $check->getError();
46
+ $error = (array) $error;
47
+ if (!empty($error)) {
48
+ $errors = array_unique( array_merge( $error, $errors ) );
49
+ }
50
+ }
51
+ }
52
+ if (!empty($errors)) {
53
+ rsort($errors);
54
+ foreach ($errors as $e) {
55
+
56
+ if ( defined( 'TC_TRAC' ) ) {
57
+ $results .= ( isset( $_POST['s_info'] ) && preg_match( '/INFO/', $e ) ) ? '' : '* ' . tc_trac( $e ) . "\r\n";
58
+ } else {
59
+ $results .= ( isset( $_POST['s_info'] ) && preg_match( '/INFO/', $e ) ) ? '' : '<li>' . tc_trac( $e ) . '</li>';
60
+ }
61
+ }
62
+ }
63
+
64
+ if ( defined( 'TC_TRAC' ) ) {
65
+
66
+ if ( defined( 'TC_PRE' ) ) $results = TC_PRE . $results;
67
+ $results = '<textarea cols=140 rows=20>' . strip_tags( $results );
68
+ if ( defined( 'TC_POST' ) ) $results = $results . TC_POST;
69
+ $results .= '</textarea>';
70
+ }
71
+ return $results;
72
+ }
73
+
74
+ function checkcount() {
75
+ global $checkcount;
76
+ $checkcount++;
77
+ }
78
+
79
+ // some functions theme checks use
80
+ function tc_grep( $error, $file ) {
81
+ if ( ! file_exists( $file ) ) {
82
+ return '';
83
+ }
84
+ $lines = file( $file, FILE_IGNORE_NEW_LINES ); // Read the theme file into an array
85
+ $line_index = 0;
86
+ $bad_lines = '';
87
+ foreach( $lines as $this_line ) {
88
+ if ( stristr ( $this_line, $error ) ) {
89
+ $error = str_replace( '"', "'", $error );
90
+ $this_line = str_replace( '"', "'", $this_line );
91
+ $error = ltrim( $error );
92
+ $pre = ( FALSE !== ( $pos = strpos( $this_line, $error ) ) ? substr( $this_line, 0, $pos ) : FALSE );
93
+ $pre = ltrim( htmlspecialchars( $pre ) );
94
+ $bad_lines .= "<pre class='tc-grep'>". __("Line ", "theme-check") . ( $line_index+1 ) . ": " . $pre . htmlspecialchars( substr( stristr( $this_line, $error ), 0, 75 ) ) . "</pre>";
95
+ }
96
+ $line_index++;
97
+ }
98
+ return str_replace( $error, '<span class="tc-grep">' . $error . '</span>', $bad_lines );
99
+ }
100
+
101
+ function tc_preg( $preg, $file ) {
102
+ if ( ! file_exists( $file ) ) {
103
+ return '';
104
+ }
105
+ $lines = file( $file, FILE_IGNORE_NEW_LINES ); // Read the theme file into an array
106
+ $line_index = 0;
107
+ $bad_lines = '';
108
+ $error = '';
109
+ foreach( $lines as $this_line ) {
110
+ if ( preg_match( $preg, $this_line, $matches ) ) {
111
+ $error = $matches[0];
112
+ $this_line = str_replace( '"', "'", $this_line );
113
+ $error = ltrim( $error );
114
+ $pre = '';
115
+ if ( !empty( $error ) ) {
116
+ $pre = ( FALSE !== ( $pos = strpos( $this_line, $error ) ) ? substr( $this_line, 0, $pos ) : FALSE );
117
+ }
118
+ $pre = ltrim( htmlspecialchars( $pre ) );
119
+ $bad_lines .= "<pre class='tc-grep'>" . __("Line ", "theme-check") . ( $line_index+1 ) . ": " . $pre . htmlspecialchars( substr( stristr( $this_line, $error ), 0, 75 ) ) . "</pre>";
120
+ }
121
+ $line_index++;
122
+
123
+ }
124
+ return str_replace( $error, '<span class="tc-grep">' . $error . '</span>', $bad_lines );
125
+ }
126
+
127
+ function tc_strxchr($haystack, $needle, $l_inclusive = 0, $r_inclusive = 0){
128
+ if(strrpos($haystack, $needle)){
129
+ //Everything before last $needle in $haystack.
130
+ $left = substr($haystack, 0, strrpos($haystack, $needle) + $l_inclusive);
131
+ //Switch value of $r_inclusive from 0 to 1 and viceversa.
132
+ $r_inclusive = ($r_inclusive == 0) ? 1 : 0;
133
+ //Everything after last $needle in $haystack.
134
+ $right = substr(strrchr($haystack, $needle), $r_inclusive);
135
+ //Return $left and $right into an array.
136
+ return array($left, $right);
137
+ } else {
138
+ if(strrchr($haystack, $needle)) return array('', substr(strrchr($haystack, $needle), $r_inclusive));
139
+ else return false;
140
+ }
141
+ }
142
+
143
+ function tc_filename( $file ) {
144
+ $filename = ( preg_match( '/themes\/[a-z0-9]*\/(.*)/', $file, $out ) ) ? $out[1] : basename( $file );
145
+ return $filename;
146
+ }
147
+
148
+ function tc_trac( $e ) {
149
+ $trac_left = array( '<strong>', '</strong>' );
150
+ $trac_right= array( "'''", "'''" );
151
+ $html_link = '/<a\s?href\s?=\s?[\'|"]([^"|\']*)[\'|"]>([^<]*)<\/a>/i';
152
+ $html_new = '[$1 $2]';
153
+ if ( defined( 'TC_TRAC' ) ) {
154
+ $e = preg_replace( $html_link, $html_new, $e );
155
+ $e = str_replace( $trac_left, $trac_right, $e );
156
+ $e = preg_replace( '/<pre.*?>/', "\r\n{{{\r\n", $e );
157
+ $e = str_replace( '</pre>', "\r\n}}}\r\n", $e );
158
+ }
159
+ return $e;
160
+ }
161
+
162
+ function listdir( $dir ) {
163
+ $files = array();
164
+ $dir_iterator = new RecursiveDirectoryIterator( $dir );
165
+ $iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST);
166
+
167
+ foreach ($iterator as $file) {
168
+ array_push( $files, $file->getPathname() );
169
+ }
170
+ return $files;
171
+ }
172
+
173
+ function old_listdir( $start_dir='.' ) {
174
+ $files = array();
175
+ if ( is_dir( $start_dir ) ) {
176
+ $fh = opendir( $start_dir );
177
+ while ( ( $file = readdir( $fh ) ) !== false ) {
178
+ # loop through the files, skipping . and .., and recursing if necessary
179
+ if ( strcmp( $file, '.' )==0 || strcmp( $file, '..' )==0 ) continue;
180
+ $filepath = $start_dir . '/' . $file;
181
+ if ( is_dir( $filepath ) )
182
+ $files = array_merge( $files, listdir( $filepath ) );
183
+ else
184
+ array_push( $files, $filepath );
185
+ }
186
+ closedir( $fh );
187
+
188
+ } else {
189
+
190
+ # false if the function was called with an invalid non-directory argument
191
+ $files = false;
192
+ }
193
+ return $files;
194
+ }
195
+
196
+ function tc_print_r( $data ) {
197
+ $out = "\n<pre class='html-print-r'";
198
+ $out .= " style='border: 1px solid #ccc; padding: 7px;'>\n";
199
+ $out .= esc_html( print_r( $data, TRUE ) );
200
+ $out .= "\n</pre>\n";
201
+ echo $out;
202
+ }
203
+
204
+ function get_theme_data_from_contents( $theme_data ) {
205
+ $themes_allowed_tags = array(
206
+ 'a' => array(
207
+ 'href' => array(),'title' => array()
208
+ ),
209
+ 'abbr' => array(
210
+ 'title' => array()
211
+ ),
212
+ 'acronym' => array(
213
+ 'title' => array()
214
+ ),
215
+ 'code' => array(),
216
+ 'em' => array(),
217
+ 'strong' => array()
218
+ );
219
+
220
+ $theme_data = str_replace ( '\r', '\n', $theme_data );
221
+ preg_match( '|^[ \t\/*#@]*Theme Name:(.*)$|mi', $theme_data, $theme_name );
222
+ preg_match( '|^[ \t\/*#@]*Theme URI:(.*)$|mi', $theme_data, $theme_uri );
223
+ preg_match( '|^[ \t\/*#@]*Description:(.*)$|mi', $theme_data, $description );
224
+
225
+ if ( preg_match( '|^[ \t\/*#@]*Author URI:(.*)$|mi', $theme_data, $author_uri ) )
226
+ $author_uri = esc_url( trim( $author_uri[1]) );
227
+ else
228
+ $author_uri = '';
229
+
230
+ if ( preg_match( '|^[ \t\/*#@]*Template:(.*)$|mi', $theme_data, $template ) )
231
+ $template = wp_kses( trim( $template[1] ), $themes_allowed_tags );
232
+ else
233
+ $template = '';
234
+
235
+ if ( preg_match( '|^[ \t\/*#@]*Version:(.*)|mi', $theme_data, $version ) )
236
+ $version = wp_kses( trim( $version[1] ), $themes_allowed_tags );
237
+ else
238
+ $version = '';
239
+
240
+ if ( preg_match('|^[ \t\/*#@]*Status:(.*)|mi', $theme_data, $status) )
241
+ $status = wp_kses( trim( $status[1] ), $themes_allowed_tags );
242
+ else
243
+ $status = 'publish';
244
+
245
+ if ( preg_match('|^[ \t\/*#@]*Tags:(.*)|mi', $theme_data, $tags) )
246
+ $tags = array_map( 'trim', explode( ',', wp_kses( trim( $tags[1] ), array() ) ) );
247
+ else
248
+ $tags = array();
249
+
250
+ $theme = ( isset( $theme_name[1] ) ) ? wp_kses( trim( $theme_name[1] ), $themes_allowed_tags ) : '';
251
+
252
+ $theme_uri = ( isset( $theme_uri[1] ) ) ? esc_url( trim( $theme_uri[1] ) ) : '';
253
+
254
+ $description = ( isset( $description[1] ) ) ? wp_kses( trim( $description[1] ), $themes_allowed_tags ) : '';
255
+
256
+ if ( preg_match( '|^[ \t\/*#@]*Author:(.*)$|mi', $theme_data, $author_name ) ) {
257
+ if ( empty( $author_uri ) ) {
258
+ $author = wp_kses( trim( $author_name[1] ), $themes_allowed_tags );
259
+ } else {
260
+ $author = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $author_uri, __( 'Visit author homepage' ), wp_kses( trim( $author_name[1] ), $themes_allowed_tags ) );
261
+ }
262
+ } else {
263
+ $author = __('Anonymous');
264
+ }
265
+
266
+ return array( 'Name' => $theme, 'Title' => $theme, 'URI' => $theme_uri, 'Description' => $description, 'Author' => $author, 'Author_URI' => $author_uri, 'Version' => $version, 'Template' => $template, 'Status' => $status, 'Tags' => $tags );
267
+ }
268
+
269
+ /*
270
+ * 3.3/3.4 compat
271
+ *
272
+ */
273
+ function tc_get_themes() {
274
+
275
+ if ( ! class_exists( 'WP_Theme' ) )
276
+ return get_themes();
277
+
278
+ global $wp_themes;
279
+ if ( isset( $wp_themes ) )
280
+ return $wp_themes;
281
+
282
+ $themes = wp_get_themes();
283
+ $wp_themes = array();
284
+
285
+ foreach ( $themes as $theme ) {
286
+ $name = $theme->get('Name');
287
+ if ( isset( $wp_themes[ $name ] ) )
288
+ $wp_themes[ $name . '/' . $theme->get_stylesheet() ] = $theme;
289
+ else
290
+ $wp_themes[ $name ] = $theme;
291
+ }
292
+
293
+ return $wp_themes;
294
+ }
295
+
296
+ function tc_get_theme_data( $theme_file ) {
297
+
298
+ if ( ! class_exists( 'WP_Theme' ) )
299
+ return get_theme_data( $theme_file );
300
+
301
+ $theme = new WP_Theme( basename( dirname( $theme_file ) ), dirname( dirname( $theme_file ) ) );
302
+
303
+ $theme_data = array(
304
+ 'Name' => $theme->get('Name'),
305
+ 'URI' => $theme->display('ThemeURI', true, false),
306
+ 'Description' => $theme->display('Description', true, false),
307
+ 'Author' => $theme->display('Author', true, false),
308
+ 'AuthorURI' => $theme->display('AuthorURI', true, false),
309
+ 'Version' => $theme->get('Version'),
310
+ 'Template' => $theme->get('Template'),
311
+ 'Status' => $theme->get('Status'),
312
+ 'Tags' => $theme->get('Tags'),
313
+ 'Title' => $theme->get('Name'),
314
+ 'AuthorName' => $theme->display('Author', false, false),
315
+ 'License' => $theme->display( 'License', false, false),
316
+ 'License URI' => $theme->display( 'License URI', false, false),
317
+ 'Template Version' => $theme->display( 'Template Version', false, false)
318
+ );
319
+ return $theme_data;
320
+ }
checks/admin_menu.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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://codex.wordpress.org/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://codex.wordpress.org/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)/' => __( 'Themes should use <strong>add_theme_page()</strong> for adding admin pages.', 'theme-check' )
35
+ );
36
+
37
+
38
+ foreach ( $php_files as $php_key => $phpfile ) {
39
+ foreach ( $checks as $key => $check ) {
40
+ checkcount();
41
+ if ( preg_match_all( $key, $phpfile, $matches ) ) {
42
+ foreach ($matches[1] as $match) {
43
+ if ($match == 'add_theme_page') {
44
+ continue;
45
+ }
46
+ $filename = tc_filename( $php_key );
47
+ $error = ltrim( rtrim( $match, '(' ) );
48
+ $grep = tc_grep( $error, $php_key );
49
+ $this->error[] = sprintf('<span class="tc-lead tc-required">'.__( 'REQUIRED', 'theme-check' ) .'</span>: <strong>%1$s</strong>. %2$s%3$s', $filename, $check, $grep);
50
+ $ret = false;
51
+ }
52
+ }
53
+ }
54
+ }
55
+
56
+ return $ret;
57
+ }
58
+
59
+ function getError() { return $this->error; }
60
+ }
61
+
62
+ $themechecks[] = new AdminMenu;
checks/artisteer.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class ArtisteerCheck 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
+ strpos( $php, 'art_normalize_widget_style_tokens' ) !== false
16
+ || strpos( $php, 'art_include_lib' ) !== false
17
+ || strpos( $php, '_remove_last_slash($url) {' ) !== false
18
+ || strpos( $php, 'adi_normalize_widget_style_tokens' ) !== false
19
+ || strpos( $php, 'm_normalize_widget_style_tokens' ) !== false
20
+ || strpos ( $php, "bw = '<!--- BEGIN Widget --->';" ) !== false
21
+ || strpos ( $php, "ew = '<!-- end_widget -->';" ) !== false
22
+ || strpos ( $php, "end_widget' => '<!-- end_widget -->'") !== false
23
+ ) {
24
+ $this->error[] = "<span class='tc-lead tc-warning'>" . __('WARNING', 'theme-check' ). "</span>: " . __( 'This theme appears to have been auto-generated. Generated themes are not allowed in the themes directory.', 'theme-check' );
25
+ $ret = false;
26
+ }
27
+
28
+ return $ret;
29
+ }
30
+
31
+ function getError() { return $this->error; }
32
+ }
33
+ $themechecks[] = new ArtisteerCheck;
checks/badthings.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ );
19
+
20
+ $grep = '';
21
+
22
+ foreach ( $php_files as $php_key => $phpfile ) {
23
+ foreach ( $checks as $key => $check ) {
24
+ checkcount();
25
+ if ( preg_match( $key, $phpfile, $matches ) ) {
26
+ $filename = tc_filename( $php_key );
27
+ $error = ltrim( trim( $matches[0], '(' ) );
28
+ $grep = tc_grep( $error, $php_key );
29
+ $this->error[] = sprintf('<span class="tc-lead tc-warning">'. __( 'WARNING', 'theme-check' ) . '</span>: ' . __( 'Found %1$s in the file %2$s. %3$s. %4$s', 'theme-check' ), '<strong>' . $error . '</strong>', '<strong>' . $filename . '</strong>', $check, $grep );
30
+ $ret = false;
31
+ }
32
+ }
33
+ }
34
+
35
+
36
+ $checks = array(
37
+ '/cx=[0-9]{21}:[a-z0-9]{10}/' => __( 'Google search code detected', 'theme-check' ),
38
+ '/pub-[0-9]{16}/' => __( 'Google advertising code detected', 'theme-check' )
39
+ );
40
+
41
+ foreach ( $other_files as $php_key => $phpfile ) {
42
+ foreach ( $checks as $key => $check ) {
43
+ checkcount();
44
+ if ( preg_match( $key, $phpfile, $matches ) ) {
45
+ $filename = tc_filename( $php_key );
46
+ $error = ltrim( rtrim( $matches[0],'(' ) );
47
+ $grep = tc_grep( $error, $php_key );
48
+ $this->error[] = sprintf(__('<span class="tc-lead tc-warning">WARNING</span>: Found <strong>%1$s</strong> in the file <strong>%2$s</strong>. %3$s.%4$s', 'theme-check'), $error, $filename, $check, $grep);
49
+ $ret = false;
50
+ }
51
+ }
52
+ }
53
+ return $ret;
54
+ }
55
+ function getError() { return $this->error; }
56
+ }
57
+ $themechecks[] = new Bad_Checks;
checks/basic.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_footer\s*\(' => __( 'See: <a href="https://codex.wordpress.org/Function_Reference/wp_footer">wp_footer</a><pre> &lt;?php wp_footer(); ?&gt;</pre>', 'theme-check' ),
16
+ 'wp_head\s*\(' => __( 'See: <a href="https://codex.wordpress.org/Function_Reference/wp_head">wp_head</a><pre> &lt;?php wp_head(); ?&gt;</pre>', 'theme-check' ),
17
+ 'language_attributes' => __( 'See: <a href="https://codex.wordpress.org/Function_Reference/language_attributes">language_attributes</a><pre>&lt;html &lt;?php language_attributes(); ?&gt;</pre>', 'theme-check' ),
18
+ 'charset' => __( 'There must be a charset defined in the Content-Type or the meta charset tag in the head.', 'theme-check' ),
19
+ 'add_theme_support\s*\(\s?("|\')automatic-feed-links("|\')\s?\)' => __( 'See: <a href="https://codex.wordpress.org/Function_Reference/add_theme_support">add_theme_support</a><pre> &lt;?php add_theme_support( $feature ); ?&gt;</pre>', 'theme-check' ),
20
+ 'comments_template\s*\(' => __( 'See: <a href="https://codex.wordpress.org/Template_Tags/comments_template">comments_template</a><pre> &lt;?php comments_template( $file, $separate_comments ); ?&gt;</pre>', 'theme-check' ),
21
+ 'wp_list_comments\s*\(' => __( 'See: <a href="https://codex.wordpress.org/Template_Tags/wp_list_comments">wp_list_comments</a><pre> &lt;?php wp_list_comments( $args ); ?&gt;</pre>', 'theme-check' ),
22
+ 'comment_form\s*\(' => __( 'See: <a href="https://codex.wordpress.org/Template_Tags/comment_form">comment_form</a><pre> &lt;?php comment_form(); ?&gt;</pre>', 'theme-check' ),
23
+ 'body_class\s*\(' => __( 'See: <a href="https://codex.wordpress.org/Template_Tags/body_class">body_class</a><pre> &lt;?php body_class( $class ); ?&gt;</pre>', 'theme-check' ),
24
+ 'wp_link_pages\s*\(' => __( 'See: <a href="https://codex.wordpress.org/Function_Reference/wp_link_pages">wp_link_pages</a><pre> &lt;?php wp_link_pages( $args ); ?&gt;</pre>', 'theme-check' ),
25
+ 'post_class\s*\(' => __( 'See: <a href="https://codex.wordpress.org/Template_Tags/post_class">post_class</a><pre> &lt;div id="post-&lt;?php the_ID(); ?&gt;" &lt;?php post_class(); ?&gt;&gt;</pre>', 'theme-check' )
26
+ );
27
+
28
+ foreach ($checks as $key => $check) {
29
+ checkcount();
30
+ if ( !preg_match( '/' . $key . '/i', $php ) ) {
31
+ if ( $key === 'add_theme_support\s*\(\s?("|\')automatic-feed-links("|\')\s?\)' ) $key = __( 'add_theme_support( \'automatic-feed-links\' )', 'theme-check');
32
+ if ( $key === 'body_class\s*\(' ) $key = __( 'body_class call in body tag', 'theme-check');
33
+ $key = str_replace( '\s*\(', '', $key );
34
+ $this->error[] = sprintf( '<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('Could not find %1$s. %2$s', 'theme-check' ), '<strong>' . $key . '</strong>', $check );
35
+ $ret = false;
36
+ }
37
+ }
38
+
39
+ return $ret;
40
+ }
41
+
42
+ function getError() { return $this->error; }
43
+ }
44
+
45
+ $themechecks[] = new Basic_Checks;
checks/cdn.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Checks for resources being loaded from CDNs.
5
+ */
6
+
7
+ class CDNCheck implements themecheck {
8
+ protected $error = array();
9
+
10
+ function check( $php_files, $css_files, $other_files) {
11
+
12
+ $ret = true;
13
+ $php_code = implode( ' ', $php_files );
14
+
15
+ checkcount();
16
+
17
+ $cdn_list = array(
18
+ 'bootstrap-maxcdn' => 'maxcdn.bootstrapcdn.com/bootstrap',
19
+ 'bootstrap-netdna' => 'netdna.bootstrapcdn.com/bootstrap',
20
+ 'bootswatch-maxcdn' => 'maxcdn.bootstrapcdn.com/bootswatch',
21
+ 'bootswatch-netdna' => 'netdna.bootstrapcdn.com/bootswatch',
22
+ 'font-awesome-maxcdn' => 'maxcdn.bootstrapcdn.com/font-awesome',
23
+ 'font-awesome-netdna' => 'netdna.bootstrapcdn.com/font-awesome',
24
+ 'html5shiv-google' => 'html5shiv.googlecode.com/svn/trunk/html5.js',
25
+ 'html5shiv-maxcdn' => 'oss.maxcdn.com/libs/html5shiv',
26
+ 'jquery' => 'code.jquery.com/jquery-',
27
+ 'respond-js' => 'oss.maxcdn.com/libs/respond.js',
28
+ );
29
+
30
+ foreach( $cdn_list as $cdn_slug => $cdn_url ) {
31
+ if ( false !== strpos( $php_code, $cdn_url ) ) {
32
+ $this->error[] = '<span class="tc-lead tc-recommended">' . __('RECOMMENDED','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>' );
33
+ //$ret = false;
34
+ }
35
+ }
36
+
37
+ return $ret;
38
+ }
39
+
40
+ function getError() { return $this->error; }
41
+ }
42
+ $themechecks[] = new CDNCheck;
checks/comment_reply.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Comment_Reply implements themecheck {
3
+ protected $error = array();
4
+
5
+ function check( $php_files, $css_files, $other_files) {
6
+
7
+ $php = implode( ' ', $php_files );
8
+ $ret = true;
9
+
10
+ checkcount();
11
+
12
+ if ( ! preg_match( '/wp_enqueue_script\(\s?("|\')comment-reply("|\')/i', $php ) ) {
13
+ if ( ! preg_match( '/comment-reply/', $php ) ) {
14
+ $check = __( 'See: <a href="https://codex.wordpress.org/Migrating_Plugins_and_Themes_to_2.7/Enhanced_Comment_Display">Migrating Plugins and Themes to 2.7/Enhanced Comment Display</a><pre> &lt;?php if ( is_singular() ) wp_enqueue_script( "comment-reply" ); ?&gt;</pre>', 'theme-check' );
15
+ $this->error[] = sprintf('<span class="tc-lead tc-required">'.__('REQUIRED','theme-check').'</span>: '.__('Could not find the <strong>comment-reply</strong> script enqueued. %1$s', 'theme-check'), $check);
16
+ $ret = false;
17
+ } else {
18
+ $this->error[] = '<span class="tc-lead tc-info">'.__('INFO','theme-check').'</span>: '.__('Could not find the <strong>comment-reply</strong> script enqueued, however a reference to \'comment-reply\' was found. Make sure that the comment-reply script is being enqueued properly on singular pages.', 'theme-check');
19
+ }
20
+ }
21
+ return $ret;
22
+ }
23
+
24
+ function getError() { return $this->error; }
25
+ }
26
+
27
+ $themechecks[] = new Comment_Reply;
checks/commpage.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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, 'next_comments_link' ) === false && strpos( $php, 'previous_comments_link' ) === false ) ) {
15
+
16
+ $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>next_comments_link()</strong> and <strong>previous_comments_link()</strong> to add comment pagination.', 'theme-check' );
17
+ $ret = false;
18
+ }
19
+
20
+ return $ret;
21
+ }
22
+
23
+ function getError() { return $this->error; }
24
+ }
25
+ $themechecks[] = new CommentPaginationCheck;
checks/constants.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ );
16
+
17
+ foreach ( $php_files as $php_key => $phpfile ) {
18
+ foreach ( $checks as $key => $check ) {
19
+ checkcount();
20
+ if ( preg_match( '/[\s|]' . $key . '/', $phpfile, $matches ) ) {
21
+ $filename = tc_filename( $php_key );
22
+ $error = ltrim( rtrim( $matches[0], '(' ) );
23
+ $grep = tc_grep( $error, $php_key );
24
+ $this->error[] = sprintf('<span class="tc-lead tc-recommended">'.__('RECOMMENDED','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 );
25
+ }
26
+ }
27
+ }
28
+ return $ret;
29
+ }
30
+
31
+ function getError() { return $this->error; }
32
+ }
33
+ $themechecks[] = new Constants;
checks/content-width.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class ContentWidthCheck 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, '$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;
checks/customizer.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Checks for the Customizer.
5
+ */
6
+
7
+ class CustomizerCheck 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
+ /**
17
+ * Check whether every Customizer setting has a sanitization callback set.
18
+ */
19
+ foreach ( $php_files as $file_path => $file_content ) {
20
+ // Get the arguments passed to the add_setting method
21
+ if ( preg_match_all( '/\$wp_customize->add_setting\(([^;]+)/', $file_content, $matches ) ) {
22
+ // The full match is in [0], the match group in [1]
23
+ foreach ( $matches[1] as $match ) {
24
+ // Check if we have sanitize_callback or sanitize_js_callback
25
+ if ( false === strpos( $match, 'sanitize_callback' ) && false === strpos( $match, 'sanitize_js_callback' ) ) {
26
+ $this->error[] = '<span class="tc-lead tc-required">' . __('REQUIRED','theme-check') . '</span>: ' . __( 'Found a Customizer setting that did not have a sanitization callback function. Every call to the <strong>add_setting()</strong> method needs to have a sanitization callback function passed.', 'theme-check' );
27
+ $ret = false;
28
+ } else {
29
+ // There's a callback, check that no empty parameter is passed.
30
+ if ( preg_match( '/[\'"](?:sanitize_callback|sanitize_js_callback)[\'"]\s*=>\s*[\'"]\s*[\'"]/', $match ) ) {
31
+ $this->error[] = '<span class="tc-lead tc-required">' . __('REQUIRED','theme-check') . '</span>: ' . __( 'Found a Customizer setting that had an empty value passed as sanitization callback. You need to pass a function name as sanitization callback.', 'theme-check' );
32
+ $ret = false;
33
+ }
34
+ }
35
+ }
36
+ }
37
+ }
38
+
39
+ return $ret;
40
+ }
41
+
42
+ function getError() { return $this->error; }
43
+ }
44
+ $themechecks[] = new CustomizerCheck;
checks/customs.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 ADDED
@@ -0,0 +1,297 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ );
258
+ foreach ( $php_files as $php_key => $phpfile ) {
259
+ foreach ( $checks as $alt => $check ) {
260
+ checkcount();
261
+ $key = key( $check );
262
+ $alt = $check[ $key ];
263
+ if ( preg_match( '/(?<!function)[\s?]' . $key . '\s?\(/', $phpfile, $matches ) ) {
264
+ $filename = tc_filename( $php_key );
265
+ $error = ltrim( rtrim( $matches[0], '(' ) );
266
+ $version = $check[0];
267
+ $grep = tc_grep( $error, $php_key );
268
+
269
+ // Point out the deprecated function.
270
+ $error_msg = sprintf(
271
+ __( '%1$s found in the file %2$s. Deprecated since version %3$s.', 'theme-check' ),
272
+ '<strong>' . $error . '()</strong>',
273
+ '<strong>' . $filename . '</strong>',
274
+ '<strong>' . $version . '</strong>'
275
+ );
276
+
277
+ // Add alternative function when available.
278
+ if ( $alt ) {
279
+ $error_msg .= ' ' . sprintf( __( 'Use %s instead.', 'theme-check' ), '<strong>' . $alt . '</strong>' );
280
+ }
281
+
282
+ // Add the precise code match that was found.
283
+ $error_msg .= $grep;
284
+
285
+ // Add the finalized error message.
286
+ $this->error[] = '<span class="tc-lead tc-required">' . __('REQUIRED','theme-check') . '</span>: ' . $error_msg;
287
+
288
+ $ret = false;
289
+ }
290
+ }
291
+ }
292
+ return $ret;
293
+ }
294
+
295
+ function getError() { return $this->error; }
296
+ }
297
+ $themechecks[] = new Deprecated;
checks/directories.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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/filenames.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
9
+ $filenames = array();
10
+
11
+ foreach ( $php_files as $php_key => $phpfile ) {
12
+ array_push( $filenames, strtolower( basename( $php_key ) ) );
13
+ }
14
+ foreach ( $other_files as $php_key => $phpfile ) {
15
+ array_push( $filenames, strtolower( basename( $php_key ) ) );
16
+ }
17
+ foreach ( $css_files as $php_key => $phpfile ) {
18
+ array_push( $filenames, strtolower( basename( $php_key ) ) );
19
+ }
20
+ $blacklist = array(
21
+ 'thumbs.db' => __( 'Windows thumbnail store', 'theme-check' ),
22
+ 'desktop.ini' => __( 'windows system file', 'theme-check' ),
23
+ 'project.properties' => __( 'NetBeans Project File', 'theme-check' ),
24
+ 'project.xml' => __( 'NetBeans Project File', 'theme-check' ),
25
+ '\.kpf' => __( 'Komodo Project File', 'theme-check' ),
26
+ '^\.+[a-zA-Z0-9]' => __( 'Hidden Files or Folders', 'theme-check' ),
27
+ 'php.ini' => __( 'PHP server settings file', 'theme-check' ),
28
+ 'dwsync.xml' => __( 'Dreamweaver project file', 'theme-check' ),
29
+ 'error_log' => __( 'PHP error log', 'theme-check' ),
30
+ 'web.config' => __( 'Server settings file', 'theme-check' ),
31
+ '\.sql' => __( 'SQL dump file', 'theme-check' ),
32
+ '__MACOSX' => __( 'OSX system file', 'theme-check' )
33
+ );
34
+
35
+ $musthave = array( 'index.php', 'style.css' );
36
+ $rechave = array( 'readme.txt' => __( 'Please see <a href="https://codex.wordpress.org/Theme_Review#Theme_Documentation">Theme_Documentation</a> for more information.', 'theme-check' ) );
37
+
38
+ checkcount();
39
+
40
+ foreach( $blacklist as $file => $reason ) {
41
+ if ( $filename = preg_grep( '/' . $file . '/', $filenames ) ) {
42
+ $error = implode( array_unique( $filename ), ' ' );
43
+ $this->error[] = sprintf('<span class="tc-lead tc-warning">'.__('WARNING','theme-check').'</span>: '.__('%1$s %2$s found.', 'theme-check'), '<strong>' . $error . '</strong>', $reason) ;
44
+ $ret = false;
45
+ }
46
+ }
47
+
48
+ foreach( $musthave as $file ) {
49
+ if ( !in_array( $file, $filenames ) ) {
50
+ $this->error[] = sprintf('<span class="tc-lead tc-warning">'.__('WARNING','theme-check').'</span>: '.__('Could not find the file %s in the theme.', 'theme-check'), '<strong>' . $file . '</strong>' );
51
+ $ret = false;
52
+ }
53
+ }
54
+
55
+ foreach( $rechave as $file => $reason ) {
56
+ if ( !in_array( $file, $filenames ) ) {
57
+ $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 );
58
+ }
59
+ }
60
+
61
+ return $ret;
62
+ }
63
+
64
+ function getError() { return $this->error; }
65
+ }
66
+ $themechecks[] = new File_Checks;
checks/gravatar.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // check for various I18N errors
4
+
5
+ class I18NCheck implements themecheck {
6
+ protected $error = array();
7
+
8
+ function check( $php_files, $css_files, $other_files ) {
9
+ $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 ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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/lineendings.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-warning">'.__('WARNING','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-warning">'.__('WARNING','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-warning">'.__('WARNING','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 ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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/more_deprecated.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
14
+ $checks = array(
15
+ 'get_bloginfo' => array(
16
+ 'home' => 'home_url()',
17
+ 'url' => 'home_url()',
18
+ 'wpurl' => 'site_url()',
19
+ 'stylesheet_directory' => 'get_stylesheet_directory_uri()',
20
+ 'template_directory' => 'get_template_directory_uri()',
21
+ 'template_url' => 'get_template_directory_uri()',
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() )',
29
+ 'stylesheet_directory' => 'echo esc_url( get_stylesheet_directory_uri() )',
30
+ 'template_directory' => 'echo esc_url( get_template_directory_uri() )',
31
+ 'template_url' => 'echo esc_url( get_template_directory_uri() )',
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 ) {
42
+ // Loop through all functions.
43
+ foreach ( $checks as $function => $data ) {
44
+ checkcount();
45
+
46
+ // Loop through the parameters and look for all function/parameter combinations.
47
+ foreach ( $data as $parameter => $replacement ) {
48
+ if ( preg_match( '/' . $function . '\(\s*("|\')' . $parameter . '("|\')\s*\)/', $php_file, $matches ) ) {
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
+ }
56
+ }
57
+ }
58
+
59
+ return $ret;
60
+ }
61
+
62
+ function getError() { return $this->error; }
63
+ }
64
+ $themechecks[] = new More_Deprecated;
checks/navmenu.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
10
+ // combine all the php files into one string to make it easier to search
11
+ $php = implode( ' ', $php_files );
12
+ checkcount();
13
+ if ( strpos( $php, 'nav_menu' ) === false ) {
14
+ $this->error[] = '<span class="tc-lead tc-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__("No reference to nav_menu's was found in the theme. Note that if your theme has a menu bar, it is required to use the WordPress nav_menu functionality for it.", 'theme-check' );
15
+ }
16
+
17
+ return $ret;
18
+ }
19
+
20
+ function getError() { return $this->error; }
21
+ }
22
+
23
+ $themechecks[] = new NavMenuCheck;
checks/nonprintable.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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\x80-\xFF]/', $content, $matches ) ) {
14
+ $filename = tc_filename( $name );
15
+ $non_print = tc_preg( '/[\x00-\x08\x0B-\x0C\x0E-\x1F\x80-\xFF]/', $name );
16
+ $this->error[] = sprintf('<span class="tc-lead tc-info">'.__('INFO','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 ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ $ret = false;
16
+ }
17
+ }
18
+
19
+ return $ret;
20
+ }
21
+
22
+ function getError() { return $this->error; }
23
+ }
24
+
25
+ $themechecks[] = new PHPShortTagsCheck;
checks/plugin-territory.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Checks for Plugin Territory Guidelines.
4
+ *
5
+ * See http://make.wordpress.org/themes/guidelines/guidelines-plugin-territory/
6
+ */
7
+
8
+ class Plugin_Territory implements themecheck {
9
+ protected $error = array();
10
+
11
+ function check( $php_files, $css_files, $other_files ) {
12
+ $ret = true;
13
+ $php = implode( ' ', $php_files );
14
+
15
+ // Functions that are required to be removed from the theme.
16
+ $forbidden_functions = array(
17
+ 'register_post_type',
18
+ 'register_taxonomy',
19
+ );
20
+
21
+ foreach ( $forbidden_functions as $function ) {
22
+ checkcount();
23
+ if ( preg_match( '/[\s?]' . $function . '\(/', $php ) ) {
24
+ $this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check').'</span>: ' . sprintf( __( 'The theme uses the %s function, which is plugin-territory functionality.', 'theme-check' ), '<strong>' . esc_html( $function ) . '()</strong>' ) ;
25
+ $ret = false;
26
+ }
27
+ }
28
+
29
+ // Shortcodes can't be used in the post content, so warn about them.
30
+ if ( false !== strpos( $php, 'add_shortcode' ) ) {
31
+ checkcount();
32
+ $this->error[] = '<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check').'</span>: ' . sprintf( __( 'The theme uses the %s function. Custom post-content shortcodes are plugin-territory functionality.', 'theme-check' ), '<strong>add_shortcode()</strong>' ) ;
33
+ $ret = false;
34
+ }
35
+
36
+ return $ret;
37
+ }
38
+
39
+ function getError() { return $this->error; }
40
+ }
41
+ $themechecks[] = new Plugin_Territory;
checks/post-formats.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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/required.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Required implements themecheck {
4
+ protected $error = array();
5
+
6
+ function check( $php_files, $css_files, $other_files ) {
7
+
8
+ $ret = true;
9
+ $checks = array(
10
+ '/\s?get_option\(\s?("|\')home("|\')\s?\)/' => 'home_url()',
11
+ '/\s?get_option\(\s?("|\')site_url("|\')\s?\)/' => 'site_url()',
12
+ );
13
+
14
+ foreach ( $php_files as $php_key => $phpfile ) {
15
+ foreach ( $checks as $key => $check ) {
16
+ checkcount();
17
+ if ( preg_match( $key, $phpfile, $matches ) ) {
18
+ $filename = tc_filename( $php_key );
19
+ $matches[0] = str_replace(array('"',"'"),'', $matches[0]);
20
+ $error = esc_html( rtrim($matches[0], '(' ) );
21
+ $grep = tc_grep( rtrim($matches[0], '(' ), $php_key );
22
+ $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);
23
+ $ret = false;
24
+ }
25
+ }
26
+ }
27
+ return $ret;
28
+ }
29
+ function getError() { return $this->error; }
30
+ }
31
+ $themechecks[] = new Required;
checks/screenshot.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 or screenshot!
22
+ $image = getimagesize( $other_key );
23
+ if ( $image[0] > 1200 || $image[1] > 900 ) {
24
+ $this->error[] = sprintf('<span class="tc-lead tc-recommended">'. __( 'RECOMMENDED','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
+ }
26
+ if ( $image[1] / $image[0] != 0.75 ) {
27
+ $this->error[] = '<span class="tc-lead tc-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__('Screenshot dimensions are wrong! Ratio of width to height should be 4:3.', 'theme-check');
28
+ }
29
+ if ( $image[0] != 1200 || $image[1] != 900 ) {
30
+ $this->error[] = '<span class="tc-lead tc-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__('Screenshot size should be 1200x900, to account for HiDPI displays. Any 4:3 image size is acceptable, but 1200x900 is preferred.', 'theme-check');
31
+ }
32
+ }
33
+ }
34
+ } else {
35
+ $this->error[] = '<span class="tc-lead tc-warning">'.__('WARNING','theme-check').'</span>: '.__('No screenshot detected! Please include a screenshot.png or screenshot.jpg.', 'theme-check' );
36
+ $ret = false;
37
+ }
38
+ return $ret;
39
+ }
40
+
41
+ function getError() { return $this->error; }
42
+ }
43
+ $themechecks[] = new Screenshot_Checks;
checks/searchform.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ '\.sticky' => __( '<strong>.sticky</strong> css class is needed in your theme css.', 'theme-check' ),
18
+ '\.bypostauthor' => __( '<strong>.bypostauthor</strong> css class is needed in your theme css.', 'theme-check' ),
19
+ '\.alignleft' => __( '<strong>.alignleft</strong> css class is needed in your theme css.', 'theme-check' ),
20
+ '\.alignright' => __( '<strong>.alignright</strong> css class is needed in your theme css.', 'theme-check' ),
21
+ '\.aligncenter' => __( '<strong>.aligncenter</strong> css class is needed in your theme css.', 'theme-check' ),
22
+ '\.wp-caption' => __( '<strong>.wp-caption</strong> css class is needed in your theme css.', 'theme-check' ),
23
+ '\.wp-caption-text' => __( '<strong>.wp-caption-text</strong> css class is needed in your theme css.', 'theme-check' ),
24
+ '\.gallery-caption' => __( '<strong>.gallery-caption</strong> css class is needed in your theme css.', 'theme-check' ),
25
+ '\.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' )
26
+ );
27
+
28
+ foreach ($checks as $key => $check) {
29
+ checkcount();
30
+ if ( !preg_match( '/' . $key . '/i', $css, $matches ) ) {
31
+ $this->error[] = "<span class='tc-lead tc-required'>" . __('REQUIRED', 'theme-check' ) . "</span>:" . $check;
32
+ $ret = false;
33
+ }
34
+ }
35
+
36
+ return $ret;
37
+ }
38
+ function getError() { return $this->error; }
39
+ }
40
+ $themechecks[] = new Style_Needed;
checks/style_suggested.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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' ) $data = get_theme_data_from_contents( $content );
13
+ }
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
+ return $ret;
18
+ }
19
+
20
+ $allowed_tags = array("black","blue","brown","gray","green","orange","pink","purple","red","silver","tan","white","yellow","dark","light","one-column","two-columns","three-columns","four-columns","left-sidebar","right-sidebar","fixed-layout","fluid-layout","responsive-layout","flexible-header","accessibility-ready","blavatar","buddypress","custom-background","custom-colors","custom-header","custom-menu","editor-style","featured-image-header","featured-images","front-page-post-form","full-width-template","microformats","post-formats","rtl-language-support","sticky-post","theme-options","threaded-comments","translation-ready","holiday","photoblogging","seasonal");
21
+
22
+ foreach( $data[ 'Tags' ] as $tag ) {
23
+ if ( !in_array( strtolower( $tag ), $allowed_tags ) ) {
24
+ if ( in_array( strtolower( $tag ), array("flexible-width","fixed-width") ) ) {
25
+ $this->error[] = '<span class="tc-lead tc-warning">'. __('WARNING','theme-check'). '</span>: ' . __( 'The flexible-width and fixed-width tags changed to fluid-layout and fixed-layout tags in WordPress 3.8. Additionally, the responsive-layout tag was added. Please change to using one of the new tags.', 'theme-check' );
26
+ } else {
27
+ $this->error[] = '<span class="tc-lead tc-warning">'. __('WARNING','theme-check'). '</span>: ' . sprintf( __('Found wrong tag, remove %s from your style.css header.', 'theme-check'), '<strong>' . $tag . '</strong>' );
28
+ $ret = false;
29
+ }
30
+ }
31
+ }
32
+
33
+ return $ret;
34
+ }
35
+
36
+ function getError() { return $this->error; }
37
+ }
38
+ $themechecks[] = new Style_Tags;
checks/suggested.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Suggested 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
+ '/[\s|]get_bloginfo\(\s?("|\')url("|\')\s?\)/' => 'home_url()',
11
+ '/[\s|]get_bloginfo\(\s?("|\')wpurl("|\')\s?\)/' => 'site_url()',
12
+ '/[\s|]get_bloginfo\(\s?("|\')stylesheet_directory("|\')\s?\)/' => 'get_stylesheet_directory_uri()',
13
+ '/[\s|]get_bloginfo\(\s?("|\')template_directory("|\')\s?\)/' => 'get_template_directory_uri()',
14
+ '/[\s|]get_bloginfo\(\s?("|\')template_url("|\')\s?\)/' => 'get_template_directory_uri()',
15
+ '/[\s|]get_bloginfo\(\s?("|\')text_direction("|\')\s?\)/' => 'is_rtl()',
16
+ '/[\s|]get_bloginfo\(\s?("|\')feed_url("|\')\s?\)/' => 'get_feed_link( \'feed\' ) (feed = rss, rss2, atom)',
17
+ '/[\s|]bloginfo\(\s?("|\')url("|\')\s?\)/' => 'echo home_url()',
18
+ '/[\s|]bloginfo\(\s?("|\')wpurl("|\')\s?\)/' => 'echo site_url()',
19
+ '/[\s|]bloginfo\(\s?("|\')stylesheet_directory("|\')\s?\)/' => 'get_stylesheet_directory_uri()',
20
+ '/[\s|]bloginfo\(\s?("|\')template_directory("|\')\s?\)/' => 'get_template_directory_uri()',
21
+ '/[\s|]bloginfo\(\s?("|\')template_url("|\')\s?\)/' => 'get_template_directory_uri()',
22
+ '/[\s|]bloginfo\(\s?("|\')text_direction("|\')\s?\)/' => 'is_rtl()',
23
+ '/[\s|]bloginfo\(\s?("|\')feed_url("|\')\s?\)/' => 'get_feed_link( \'feed\' ) (feed = rss, rss2, atom)',
24
+ );
25
+
26
+ foreach ( $php_files as $php_key => $phpfile ) {
27
+ foreach ( $checks as $key => $check ) {
28
+ checkcount();
29
+ if ( preg_match( $key, $phpfile, $matches ) ) {
30
+ $filename = tc_filename( $php_key );
31
+ $matches[0] = str_replace(array('"',"'"),'', $matches[0]);
32
+ $error = trim( esc_html( rtrim($matches[0], '(' ) ) );
33
+ $grep = tc_grep( rtrim( $matches[0], '(' ), $php_key );
34
+ $this->error[] = sprintf('<span class="tc-lead tc-recommended">' . __( 'RECOMMENDED', '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);
35
+ }
36
+ }
37
+ }
38
+ return $ret;
39
+ }
40
+
41
+ function getError() { return $this->error; }
42
+ }
43
+ $themechecks[] = new Suggested;
checks/tags.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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, '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 ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
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
+ // ignore core themes and uploads on w.org for this one check
37
+ if ( !in_array($themename, $this->exceptions) && !defined( 'WPORGPATH' ) ) {
38
+ $correct_domain = sanitize_title_with_dashes($data['Name']);
39
+ if ( $themename != $correct_domain ) {
40
+ $this->error[] = '<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check' ) . '</span>: '
41
+ . 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>' ).
42
+ '<br>'. __( '(If this is a child theme, you can ignore this error.)' , 'theme-check' );
43
+ }
44
+ }
45
+
46
+ $ret = true;
47
+ $error = '';
48
+ checkcount();
49
+
50
+ // make sure the tokenizer is available
51
+ if ( !function_exists( 'token_get_all' ) ) {
52
+ return true;
53
+ }
54
+
55
+ $funcs = array_keys($this->rules);
56
+
57
+ $domains = array();
58
+
59
+ foreach ( $php_files as $php_key => $phpfile ) {
60
+ $error='';
61
+
62
+ // tokenize the file
63
+ $tokens = token_get_all($phpfile);
64
+
65
+ $in_func = false;
66
+ $args_started = false;
67
+ $parens_balance = 0;
68
+ $found_domain = false;
69
+
70
+ foreach($tokens as $token) {
71
+ $string_success = false;
72
+
73
+ if (is_array($token)) {
74
+ list($id, $text) = $token;
75
+ if (T_STRING == $id && in_array($text, $funcs)) {
76
+ $in_func = true;
77
+ $func = $text;
78
+ $parens_balance = 0;
79
+ $args_started = false;
80
+ $found_domain = false;
81
+ } elseif (T_CONSTANT_ENCAPSED_STRING == $id) {
82
+ if ($in_func && $args_started) {
83
+ if (! isset( $this->rules[$func][$args_count] ) ) {
84
+ // avoid a warning when too many arguments are in a function, cause a fail case
85
+ $new_args = $args;
86
+ $new_args[] = $text;
87
+ $this->error[] = '<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check' ) . '</span>: '
88
+ . sprintf (
89
+ __( 'Found a translation function that has an incorrect number of arguments. Function %1$s, with the arguments %2$s', 'theme-check' ),
90
+ '<strong>' . $func . '</strong>',
91
+ '<strong>' . implode(', ',$new_args) . '</strong>'
92
+ );
93
+ } else if ($this->rules[$func][$args_count] == 'domain') {
94
+ // strip quotes from the domain, avoids 'domain' and "domain" not being recognized as the same
95
+ $text = str_replace(array('"', "'"), '', $text);
96
+ $domains[] = $text;
97
+ $found_domain=true;
98
+ }
99
+ if ($parens_balance == 1) {
100
+ $args_count++;
101
+ $args[] = $text;
102
+ }
103
+ }
104
+ }
105
+ $token = $text;
106
+ } elseif ('(' == $token){
107
+ if ($parens_balance == 0) {
108
+ $args=array();
109
+ $args_started = true;
110
+ $args_count = 0;
111
+ }
112
+ ++$parens_balance;
113
+ } elseif (')' == $token) {
114
+ --$parens_balance;
115
+ if ($in_func && 0 == $parens_balance) {
116
+ if (!$found_domain) {
117
+ $this->error[] = '<span class="tc-lead tc-warning">' . __( 'WARNING', 'theme-check' ) . '</span>: '
118
+ . sprintf (
119
+ __( 'Found a translation function that is missing a text-domain. Function %1$s, with the arguments %2$s', 'theme-check' ),
120
+ '<strong>' . $func . '</strong>',
121
+ '<strong>' . implode(', ',$args) . '</strong>'
122
+ );
123
+ }
124
+ $in_func = false;
125
+ $func='';
126
+ $args_started = false;
127
+ $found_domain = false;
128
+ }
129
+ }
130
+ }
131
+ }
132
+
133
+ $domains = array_unique($domains);
134
+ $domainlist = implode( ', ', $domains );
135
+ $domainscount = count($domains);
136
+
137
+ if ( $domainscount > 1 ) {
138
+ $this->error[] = '<span class="tc-lead tc-info">' . __( 'INFO', 'theme-check' ) . '</span>: '
139
+ . __( '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' )
140
+ . '<br>'
141
+ . sprintf( __( 'The domains found are %s', 'theme-check'), '<strong>' . $domainlist . '</strong>' );
142
+ } else {
143
+ $this->error[] = '<span class="tc-lead tc-info">' . __( 'INFO', 'theme-check' ) . '</span>: '
144
+ . __( "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' )
145
+ . '<br>'
146
+ . sprintf( __( 'The domain found is %s', 'theme-check'), '<strong>' . $domainlist . '</strong>' );
147
+
148
+ }
149
+
150
+ return $ret;
151
+ }
152
+
153
+ function getError() { return $this->error; }
154
+ }
155
+ $themechecks[] = new TextDomainCheck;
checks/time_date.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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: http://make.wordpress.org/themes/guidelines/guidelines-theme-check/
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-recommended">'.__('RECOMMENDED','theme-check').'</span>: '.__('No reference to <strong>add_theme_support( "title-tag" )</strong> was found in the theme. It is recommended that the theme implement this functionality for WordPress 4.1 and above.', 'theme-check' );
21
+ $titletag = false;
22
+ }
23
+
24
+ // Look for <title> and </title> tags.
25
+ checkcount();
26
+ if ( ( false === strpos( $php, '<title>' ) || false === strpos( $php, '</title>' ) ) && !$titletag ) {
27
+ $this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check').'</span>: ' . __( 'The theme needs to have <strong>&lt;title&gt;</strong> tags, ideally in the <strong>header.php</strong> file.', 'theme-check' );
28
+ $ret = false;
29
+ }
30
+
31
+ // Check whether there is a call to wp_title()
32
+ checkcount();
33
+ if ( false === strpos( $php, 'wp_title(' ) && !$titletag ) {
34
+ $this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check').'</span>: ' . __( 'The theme needs to have a call to <strong>wp_title()</strong>, ideally in the <strong>header.php</strong> file.', 'theme-check' );
35
+ $ret = false;
36
+ }
37
+
38
+ //Check whether the the <title> tag contains something besides a call to wp_title()
39
+ checkcount();
40
+
41
+ foreach ( $php_files as $file_path => $file_content ) {
42
+ // Look for anything that looks like <svg>...</svg> and exclude it (inline svg's have titles too)
43
+ $file_content = preg_replace('/<svg>.*<\/svg>/s', '', $file_content);
44
+
45
+ // First looks ahead to see of there's <title>...</title>
46
+ // Then performs a negative look ahead for <title> wp_title(...); </title>
47
+ if ( preg_match( '/(?=<title>(.*)<\/title>)(?!<title>\s*<\?php\s*wp_title\([^\)]*\);\s*\?>\s*<\/title>)/s', $file_content ) ) {
48
+ $this->error[] = '<span class="tc-lead tc-required">' . __( 'REQUIRED', 'theme-check').'</span>: ' . __( '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' );
49
+ $ret = false;
50
+ }
51
+ }
52
+
53
+ return $ret;
54
+ }
55
+
56
+ function getError() { return $this->error; }
57
+ }
58
+
59
+ $themechecks[] = new Title_Checks;
checks/widgets.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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://codex.wordpress.org/Function_Reference/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://codex.wordpress.org/Function_Reference/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://codex.wordpress.org/Function_Reference/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 ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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-warning">'. __( 'WARNING', '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 ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>' . sprintf(__('Parent theme %1$s not found! You have to have parent AND child-theme installed!', 'theme-check'), '<strong>' . $data[ 'Template' ] . '</strong>' ) . '</h2>';
13
+ return;
14
+ }
15
+ $parent_data = tc_get_theme_data( $parent . '/style.css' );
16
+ $themename = basename( $parent );
17
+ $files = array_merge( listdir( $parent ), $files );
18
+ }
19
+
20
+ if ( $files ) {
21
+ foreach( $files as $key => $filename ) {
22
+ if ( substr( $filename, -4 ) == '.php' && ! is_dir( $filename ) ) {
23
+ $php[$filename] = php_strip_whitespace( $filename );
24
+ }
25
+ else if ( substr( $filename, -4 ) == '.css' && ! is_dir( $filename ) ) {
26
+ $css[$filename] = file_get_contents( $filename );
27
+ }
28
+ else {
29
+ $other[$filename] = ( ! is_dir($filename) ) ? file_get_contents( $filename ) : '';
30
+ }
31
+ }
32
+
33
+ // run the checks
34
+ $success = run_themechecks($php, $css, $other);
35
+
36
+ global $checkcount;
37
+
38
+ // second loop, to display the errors
39
+ echo '<h2>' . __( 'Theme Info', 'theme-check' ) . ': </h2>';
40
+ echo '<div class="theme-info">';
41
+ if (file_exists( trailingslashit( WP_CONTENT_DIR . '/themes' ) . trailingslashit( basename( $theme ) ) . 'screenshot.png' ) ) {
42
+ $image = getimagesize( $theme . '/screenshot.png' );
43
+ echo '<div style="float:right" class="theme-info"><img style="max-height:180px;" src="' . trailingslashit( WP_CONTENT_URL . '/themes' ) . trailingslashit( basename( $theme ) ) . 'screenshot.png" />';
44
+ echo '<br /><div style="text-align:center">' . $image[0] . 'x' . $image[1] . ' ' . round( filesize( $theme . '/screenshot.png' )/1024 ) . 'k</div></div>';
45
+ }
46
+
47
+ echo ( !empty( $data[ 'Title' ] ) ) ? '<p><label>' . __( 'Title', 'theme-check' ) . '</label><span class="info">' . $data[ 'Title' ] . '</span></p>' : '';
48
+ echo ( !empty( $data[ 'Version' ] ) ) ? '<p><label>' . __( 'Version', 'theme-check' ) . '</label><span class="info">' . $data[ 'Version' ] . '</span></p>' : '';
49
+ echo ( !empty( $data[ 'AuthorName' ] ) ) ? '<p><label>' . __( 'Author', 'theme-check' ) . '</label><span class="info">' . $data[ 'AuthorName' ] . '</span></p>' : '';
50
+ echo ( !empty( $data[ 'AuthorURI' ] ) ) ? '<p><label>' . __( 'Author URI', 'theme-check' ) . '</label><span class="info"><a href="' . $data[ 'AuthorURI' ] . '">' . $data[ 'AuthorURI' ] . '</a>' . '</span></p>' : '';
51
+ echo ( !empty( $data[ 'URI' ] ) ) ? '<p><label>' . __( 'Theme URI', 'theme-check' ) . '</label><span class="info"><a href="' . $data[ 'URI' ] . '">' . $data[ 'URI' ] . '</a>' . '</span></p>' : '';
52
+ echo ( !empty( $data[ 'License' ] ) ) ? '<p><label>' . __( 'License', 'theme-check' ) . '</label><span class="info">' . $data[ 'License' ] . '</span></p>' : '';
53
+ echo ( !empty( $data[ 'License URI' ] ) ) ? '<p><label>' . __( 'License URI', 'theme-check' ) . '</label><span class="info">' . $data[ 'License URI' ] . '</span></p>' : '';
54
+ echo ( !empty( $data[ 'Tags' ] ) ) ? '<p><label>' . __( 'Tags', 'theme-check' ) . '</label><span class="info">' . implode( $data[ 'Tags' ], ', ') . '</span></p>' : '';
55
+ echo ( !empty( $data[ 'Description' ] ) ) ? '<p><label>' . __( 'Description', 'theme-check' ) . '</label><span class="info">' . $data[ 'Description' ] . '</span></p>' : '';
56
+
57
+ if ( $data[ 'Template' ] ) {
58
+ if ( $data['Template Version'] > $parent_data['Version'] ) {
59
+ echo '<p>' . sprintf(
60
+ __('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'),
61
+ '<strong>' . $data['Template Version'] . '</strong>',
62
+ '<strong>' . $parent_data['Title'] . '</strong>',
63
+ '<strong>' . $parent_data['Version'] . '</strong>'
64
+ ) . '</p>';
65
+ }
66
+ echo '<p>' . sprintf(
67
+ __( 'This is a child theme. The parent theme is: %s. These files have been included automatically!', 'theme-check'),
68
+ '<strong>' . $data[ 'Template' ] . '</strong>'
69
+ ) . '</p>';
70
+ if ( empty( $data['Template Version'] ) ) {
71
+ echo '<p>' . __('Child theme does not have the <strong>Template Version</strong> tag in style.css.', 'theme-check') . '</p>';
72
+ } else {
73
+ echo ( $data['Template Version'] < $parent_data['Version'] ) ? '<p>' . sprintf(__('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'), $data['Template Version'], $parent_data['Title'], $parent_data['Title'], $parent_data['Version'] ) . '</p>' : '';
74
+ }
75
+ }
76
+ echo '</div><!-- .theme-info-->';
77
+
78
+ $plugins = get_plugins( '/theme-check' );
79
+ $version = explode( '.', $plugins['theme-check.php']['Version'] );
80
+ echo '<p>' . sprintf(
81
+ __(' Running %1$s tests against %2$s using Guidelines Version: %3$s Plugin revision: %4$s', 'theme-check'),
82
+ '<strong>' . $checkcount . '</strong>',
83
+ '<strong>' . $data[ 'Title' ] . '</strong>',
84
+ '<strong>' . $version[0] . '</strong>',
85
+ '<strong>' . $version[1] . '</strong>'
86
+ ) . '</p>';
87
+ $results = display_themechecks();
88
+ if ( !$success ) {
89
+ echo '<h2>' . sprintf(__('One or more errors were found for %1$s.', 'theme-check'), $data[ 'Title' ] ) . '</h2>';
90
+ } else {
91
+ echo '<h2>' . sprintf(__('%1$s passed the tests', 'theme-check'), $data[ 'Title' ] ) . '</h2>';
92
+ tc_success();
93
+ }
94
+ if ( !defined( 'WP_DEBUG' ) || WP_DEBUG == false ) echo '<div class="updated"><span class="tc-fail">' . __('WARNING','theme-check') . '</span> ' . __( '<strong>WP_DEBUG is not enabled!</strong> Please test your theme with <a href="https://codex.wordpress.org/Editing_wp-config.php">debug enabled</a> before you upload!', 'theme-check' ) . '</div>';
95
+ echo '<div class="tc-box">';
96
+ echo '<ul class="tc-result">';
97
+ echo $results;
98
+ echo '</ul></div>';
99
+ }
100
+ }
101
+
102
+
103
+ function tc_intro() {
104
+ ?>
105
+ <h2><?php _e( 'About', 'theme-check' ); ?></h2>
106
+ <p><?php _e( "The Theme Check plugin is an easy way to test your theme and make sure it's up to date with the latest theme review standards. With it, you can run all the same automated testing tools on your theme that WordPress.org uses for theme submissions.", 'theme-check' ); ?></p>
107
+ <h2><?php _e( 'Contact', 'theme-check' ); ?></h2>
108
+ <p><?php printf( __( 'Theme Check is maintained by %1$s and %2$s.', 'theme-check' ),
109
+ '<a href="https://profiles.wordpress.org/otto42/">Otto42</a>',
110
+ '<a href="https://profiles.wordpress.org/pross/">Pross</a>'
111
+ ); ?></p>
112
+ <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 theme review 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>
113
+ <p><?php printf( __( 'The code for Theme Check can be contributed to on <a href="%s">GitHub</a>.', 'theme-check' ), 'https://github.com/Otto42/theme-check'); ?></p>
114
+ <h3><?php _e( 'Testers', 'theme-check' ); ?></h3>
115
+ <p><a href="https://make.wordpress.org/themes/"><?php _e( 'The WordPress Theme Review Team', 'theme-check' ); ?></a></p>
116
+ <?php
117
+ }
118
+
119
+ function tc_success() {
120
+ ?>
121
+ <div class="tc-success"><p><?php _e( 'Now your theme has passed the basic tests you need to check it properly using the test data before you upload to the WordPress Themes Directory.', 'theme-check' ); ?></p>
122
+ <p><?php _e( 'Make sure to review the guidelines at <a href="https://codex.wordpress.org/Theme_Review">Theme Review</a> before uploading a Theme.', 'theme-check' ); ?></p>
123
+ <h3><?php _e( 'Codex Links', 'theme-check' ); ?></h3>
124
+ <ul>
125
+ <li><a href="https://codex.wordpress.org/Theme_Development"><?php _e('Theme Development', 'theme-check' ); ?></a></li>
126
+ <li><a href="https://wordpress.org/support/forum/5"><?php _e('Themes and Templates forum', 'theme-check' ); ?></a></li>
127
+ <li><a href="https://codex.wordpress.org/Theme_Unit_Test"><?php _e('Theme Unit Tests', 'theme-check' ); ?></a></li>
128
+ </ul></div>
129
+ <?php
130
+ }
131
+
132
+ function tc_form() {
133
+ $themes = tc_get_themes();
134
+ echo '<form action="themes.php?page=themecheck" method="post">';
135
+ echo '<select name="themename">';
136
+ foreach( $themes as $name => $location ) {
137
+ echo '<option ';
138
+ if ( isset( $_POST['themename'] ) ) {
139
+ echo ( $location['Stylesheet'] === $_POST['themename'] ) ? 'selected="selected" ' : '';
140
+ } else {
141
+ echo ( basename( STYLESHEETPATH ) === $location['Stylesheet'] ) ? 'selected="selected" ' : '';
142
+ }
143
+ echo ( basename( STYLESHEETPATH ) === $location['Stylesheet'] ) ? 'value="' . $location['Stylesheet'] . '" style="font-weight:bold;">' . $name . '</option>' : 'value="' . $location['Stylesheet'] . '">' . $name . '</option>';
144
+ }
145
+ echo '</select>';
146
+ echo '<input class="button" type="submit" value="' . __( 'Check it!', 'theme-check' ) . '" />';
147
+ if ( defined( 'TC_PRE' ) || defined( 'TC_POST' ) ) echo ' <input name="trac" type="checkbox" /> ' . __( 'Output in Trac format.', 'theme-check' );
148
+ echo '<input name="s_info" type="checkbox" /> ' . __( 'Suppress INFO.', 'theme-check' );
149
+ echo '</form>';
150
+ }
readme.txt ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Theme Check ===
2
+ Contributors: Otto42, pross
3
+ Author URI: http://ottopress.com/
4
+ Plugin URL: http://ottopress.com/wordpress-plugins/theme-check/
5
+ Requires at Least: 3.7
6
+ Tested Up To: 4.4
7
+ Tags: template, theme, check, checker, tool, wordpress, wordpress.org, upload, uploader, test, guideline, review
8
+ Stable tag: 20151211.1
9
+
10
+ A simple and easy way to test your theme for all the latest WordPress standards and practices. A great theme development tool!
11
+
12
+ == Description ==
13
+
14
+ 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.
15
+
16
+ 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.
17
+
18
+ == Frequently Asked Questions ==
19
+
20
+ = What's with the version numbers? =
21
+
22
+ The version number is the date of the revision of the [guidelines](https://make.wordpress.org/themes/handbook/review/) used to create it.
23
+
24
+ = Why does it flag something as bad? =
25
+
26
+ 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.
27
+
28
+ 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.
29
+
30
+ 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.
31
+
32
+ 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).
33
+
34
+ == Other Notes ==
35
+
36
+ = How to enable trac formatting =
37
+
38
+ 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.
39
+ To enable trac formatting in Theme-Check you need to define a couple of variables in wp-config.php:
40
+ *TC_PRE* and *TC_POST* are used as a ticket header and footer.
41
+ Examples:
42
+ `define( 'TC_PRE', 'Theme Review:[[br]]
43
+ - Themes should be reviewed using "define(\'WP_DEBUG\', true);" in wp-config.php[[br]]
44
+ - Themes should be reviewed using the test data from the Theme Checklists (TC)
45
+ -----
46
+ ' );`
47
+
48
+ `define( 'TC_POST', 'Feel free to make use of the contact details below if you have any questions,
49
+ comments, or feedback:[[br]]
50
+ [[br]]
51
+ * Leave a comment on this ticket[[br]]
52
+ * Send an email to the Theme Review email list[[br]]
53
+ * Use the #wordpress-themes IRC channel on Freenode.' );`
54
+ If **either** of these two vars are defined a new trac tickbox will appear next to the *Check it!* button.
55
+
56
+ == Changelog ==
57
+ = 20151211.1 =
58
+ * Full sync with Github and all the changes that have happened there.
59
+ * Release for 4.4 deprecated functions.
60
+
61
+ = 20140929.1 =
62
+ * Added new checks and updates from Frank Klein at Automattic. Thanks Frank!
63
+ * Updated deprecated function listings
64
+ * Customizer check: All add_settings must use sanitization callbacks, for security
65
+ * Plugin territory checks: Themes must not register post types or taxonomies or add shortcodes for post content
66
+ * Widgets: Calls to register_sidebar must be called from the widgets_init action hook
67
+ * Title: <title> tags must exist and not have anything in them other than a call to wp_title()
68
+ * CDN: Checks for use of common CDNs (recommended only)
69
+ * Note: Changed plugin and author URIs due to old URIs being invalid. These may change again in the future, the URIs to my own site are temporarily only.
70
+
71
+ = 20131213.1 =
72
+ * Corrected errors not being displayed by the plugin and it incorrectly giving a "pass" result to everything.
73
+
74
+ = 20131212.1 =
75
+ * Updated for 3.8
76
+ * Most files have changed for better I18N support, so the language files were removed temporarily until translation can be redone.
77
+
78
+ = 20121211.1 =
79
+ * Updated for 3.5
80
+ * Remove Paypal button.
81
+
82
+ = 20110805.1 =
83
+ * TimThumb checks removed.
84
+ * Proper i18n loading. Fixes http://bit.ly/ouD5Ke.
85
+ * Screenshot now previewed in results, with filesize and dimensions.
86
+
87
+ = 20110602.2 =
88
+ * New file list functions hidden folders now detectable.
89
+ * Better fopen checks.
90
+ * TimThumb version bump
91
+
92
+ = 20110602.1 =
93
+ * DOS/UNIX line ending style checks are now a requirement for proper theme uploading.
94
+ * Timthumb version bump
95
+ * Several fixes reported by GaryJ
96
+ * 3.2 deprecated functions added
97
+
98
+ = 20110412.1 =
99
+ * Fix regex's
100
+ * Added check for latest footer injection hack.
101
+ * Fix tags check to use new content function correctly
102
+ * Sync of all changes made for wporg uploader theme-check.
103
+ * Updated checks post 3.1. added screenshot check to svn.
104
+ * Fix links check to not return a false failure in some cases
105
+ * rm one of the checks that causes problems on wporg uploader (and which is also unnecessary)
106
+ * Move unneeded functions out of checkbase into main.php.
107
+ * Minor formatting changes only (spacing and such)
108
+ * Add check for wp_link_pages() + fix eval() check
109
+
110
+ = 20110219.2 =
111
+ * Merged new UI props Gua Bob [1](http://guabob.com/)
112
+ * Last tested theme is always pre-selected in the themes list.
113
+ * Fixed php error in admin_menu.php
114
+
115
+ = 20110219.1 =
116
+ * See [commit log](https://github.com/Pross/theme-check/commits/) for changes.
117
+
118
+ = 20110201.2 =
119
+ * UI bug fixes [forum post](http://bit.ly/ff7amN) props Mamaduka.
120
+ * Textdomain checks for twentyten and no domain.
121
+ * Fix div not closing props Mamaduka.
122
+
123
+ = 20110201.1 =
124
+ * i18n working
125
+ * sr_RS de_DE ro_RO langs props Daniel Tara and Emil Uzelac.
126
+ * Child theme support added, checks made against parent AND child at runtime.
127
+ * Trac formatting button added for reviewers.
128
+
129
+ = 20101228.3 =
130
+ * Last revision for 3.1 (hopefully)
131
+ * Chips suggestion of checking for inclusion of searchform.php ( not
132
+ perfect yet, need more examples to look for ).
133
+ * add_theme_page is required, all others flagged and displayed with line
134
+ numbers.
135
+ * <?= detected properly, short tags outputted with line umbers.
136
+ * Mostly internationalized, needs translations now.
137
+ * Bug fixes.
138
+
139
+ = 20101228.2 =
140
+ * Added menu checking.
141
+ * ThemeURI AuthourURI added to results.
142
+ * Lots of small fixes.
143
+ * Started translation.
144
+
145
+ = 20101228.1 =
146
+ * Fix embed_defaults filter check and stylesheet file data check.
147
+
148
+ = 20101226.1 =
149
+ * Whole system redesign to allow easier synching with WordPress.org uploader. Many other additions/subtractions/changes as well.
150
+ * WordPress 3.1 guidelines added, to help theme authors ensure compatibility for upcoming release.
151
+
152
+ = 20101110.7 =
153
+ * Re-added malware.php checks for fopen and file_get_contents (INFO)
154
+ * fixed a couple of undefined index errors.
155
+
156
+ = 20101110.4_r2 =
157
+ * Fixed Warning: Wrong parameter count for stristr()
158
+
159
+ = 20101110.4_r1 =
160
+ * Added `echo` to suggested.php
161
+
162
+ = 20101110.4 =
163
+ * Fixed deprecated function call to get_plugins()
164
+
165
+ = 20101110.3 =
166
+ * Fixed undefined index.
167
+
168
+ = 20101110.2 =
169
+ * Missing `<` in main.php
170
+ * Added conditional checks for licence.txt OR Licence tags in style.css
171
+ * UI improvements.
172
+
173
+ = 20101110.1 =
174
+ * Date fix!
175
+
176
+ = 10112010_r1 =
177
+ * Fixed hardcoded links check. Added FAQ
178
+
179
+ = 10112010 =
180
+ * First release.
theme-check.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Plugin Name: Theme Check
4
+ Plugin URI: http://ottopress.com/wordpress-plugins/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: Otto42, pross
7
+ Author URI: http://ottopress.com
8
+ Version: 20151211.1
9
+ Text Domain: theme-check
10
+ License: GPLv2
11
+ License URI: https://www.gnu.org/licenses/gpl-2.0.html
12
+ */
13
+
14
+ class ThemeCheckMain {
15
+ function __construct() {
16
+ add_action( 'admin_init', array( $this, 'tc_i18n' ) );
17
+ add_action( 'admin_menu', array( $this, 'themecheck_add_page' ) );
18
+ }
19
+
20
+ function tc_i18n() {
21
+ load_plugin_textdomain( 'theme-check', false, dirname( plugin_basename( __FILE__ ) ) . '/lang/' );
22
+ }
23
+
24
+ function load_styles() {
25
+ wp_enqueue_style('style', plugins_url( 'assets/style.css', __FILE__ ), null, null, 'screen');
26
+ }
27
+
28
+ function themecheck_add_page() {
29
+ $page = add_theme_page( 'Theme Check', 'Theme Check', 'manage_options', 'themecheck', array( $this, 'themecheck_do_page' ) );
30
+ add_action('admin_print_styles-' . $page, array( $this, 'load_styles' ) );
31
+ }
32
+
33
+ function tc_add_headers( $extra_headers ) {
34
+ $extra_headers = array( 'License', 'License URI', 'Template Version' );
35
+ return $extra_headers;
36
+ }
37
+
38
+ function themecheck_do_page() {
39
+ if ( !current_user_can( 'manage_options' ) ) {
40
+ wp_die( __( 'You do not have sufficient permissions to access this page.', 'theme-check' ) );
41
+ }
42
+
43
+ add_filter( 'extra_theme_headers', array( $this, 'tc_add_headers' ) );
44
+
45
+ include 'checkbase.php';
46
+ include 'main.php';
47
+
48
+ ?>
49
+ <div id="theme-check" class="wrap">
50
+ <h1><?php _ex( 'Theme Check', 'title of the main page', 'theme-check' ); ?></h1>
51
+ <div class="theme-check">
52
+ <?php
53
+ tc_form();
54
+ if ( !isset( $_POST[ 'themename' ] ) ) {
55
+ tc_intro();
56
+
57
+ }
58
+
59
+ if ( isset( $_POST[ 'themename' ] ) ) {
60
+ if ( isset( $_POST[ 'trac' ] ) ) define( 'TC_TRAC', true );
61
+ if ( defined( 'WP_MAX_MEMORY_LIMIT' ) ) {
62
+ @ini_set( 'memory_limit', WP_MAX_MEMORY_LIMIT );
63
+ }
64
+ check_main( $_POST[ 'themename' ] );
65
+ }
66
+ ?>
67
+ </div> <!-- .theme-check-->
68
+ </div>
69
+ <?php
70
+ }
71
+ }
72
+ new ThemeCheckMain;