P3 (Plugin Performance Profiler) - Version 1.3.0

Version Description

Internationalized P3, major refactoring for lower memory usage, compatibility with WordPress 3.4.

Download this release

Release Info

Developer StarfieldTech
Plugin Icon wp plugin P3 (Plugin Performance Profiler)
Version 1.3.0
Comparing to
See all releases

Code changes from version 1.2.0 to 1.3.0

classes/.htaccess ADDED
@@ -0,0 +1 @@
 
1
+ Deny from all
classes/class.p3-profiler-plugin-admin.php ADDED
@@ -0,0 +1,691 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * P3 Plugin Performance Profiler Plugin Controller
5
+ *
6
+ * @author GoDaddy.com
7
+ * @package P3_Profiler
8
+ */
9
+ class P3_Profiler_Plugin_Admin {
10
+
11
+ /**
12
+ * List table of the profile scans
13
+ * @var P3_Profiler_Table
14
+ */
15
+ public static $scan_table = null;
16
+
17
+ /**
18
+ * Name of the current scan being viewed
19
+ * @var string
20
+ */
21
+ public static $scan = '';
22
+
23
+ /**
24
+ * Current action
25
+ * @var string
26
+ */
27
+ public static $action = '';
28
+
29
+ /**
30
+ * Profile reader object
31
+ * @var P3_Profiler_Reader
32
+ */
33
+ public static $profile = '';
34
+
35
+ /**
36
+ * Remove the admin bar from the customer site when profiling is enabled
37
+ * to prevent skewing the numbers, as much as possible. Also prevent ssl
38
+ * warnings by forcing content into ssl mode if the admin is in ssl mode
39
+ */
40
+ public static function remove_admin_bar() {
41
+ if ( !is_admin() && is_user_logged_in() ) {
42
+ remove_action( 'init', '_wp_admin_bar_init' );
43
+ if ( true === force_ssl_admin() ) {
44
+ add_filter( 'site_url', array( __CLASS__, '_fix_url' ) );
45
+ add_filter( 'admin_url', array( __CLASS__, '_fix_url' ) );
46
+ add_filter( 'post_link', array( __CLASS__, '_fix_url' ) );
47
+ add_filter( 'category_link', array( __CLASS__, '_fix_url' ) );
48
+ add_filter( 'get_archives_link', array( __CLASS__, '_fix_url' ) );
49
+ add_filter( 'tag_link', array( __CLASS__, '_fix_url' ) );
50
+ add_filter( 'home_url', array( __CLASS__, '_fix_url' ) );
51
+ }
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Replace http with https to avoid SSL warnings in the preview iframe if the admin is in SSL
57
+ * This will strip off any port numbers and will not replace URLs in off-site links
58
+ * @param string $url
59
+ * @return string
60
+ */
61
+ public static function _fix_url( $url ) {
62
+ static $host = '';
63
+ if ( empty( $host ) ) {
64
+ $host = preg_replace( '/[:\d+$]/', '', $_SERVER['HTTP_HOST'] );
65
+ }
66
+ return str_ireplace( 'http://' . $host, 'https://' . $host, $url );
67
+ }
68
+
69
+ /**
70
+ * Load javascripts
71
+ */
72
+ public static function load_scripts() {
73
+ wp_enqueue_script( 'jquery' );
74
+ wp_enqueue_script( 'jquery-ui-dialog' );
75
+ wp_enqueue_script( 'jquery-ui-tabs' );
76
+ wp_enqueue_script( 'jquery-ui-progressbar' );
77
+ wp_enqueue_script( 'flot', plugins_url() . '/p3-profiler/js/jquery.flot.min.js', array( 'jquery-ui-core' ) );
78
+ wp_enqueue_script( 'flot.pie', plugins_url() . '/p3-profiler/js/jquery.flot.pie.min.js', array( 'flot' ) );
79
+ wp_enqueue_script( 'flot.navigate', plugins_url() . '/p3-profiler/js/jquery.flot.navigate.js', array( 'flot' ) );
80
+ wp_enqueue_script( 'p3_corners', plugins_url() . '/p3-profiler/js/jquery.corner.js', array( 'jquery-ui-core' ) );
81
+ wp_enqueue_script( 'p3_qtip', plugins_url() . '/p3-profiler/js/jquery.qtip.min.js', array( 'jquery-ui-core' ) );
82
+ }
83
+
84
+ /**
85
+ * Load styles
86
+ */
87
+ public static function load_styles() {
88
+ wp_enqueue_style( 'p3_jquery_ui_css', plugins_url() . '/p3-profiler/css/custom-theme/jquery-ui-1.8.16.custom.css' );
89
+ wp_enqueue_style( 'p3_qtip_css', plugins_url() . '/p3-profiler/css/jquery.qtip.min.css' );
90
+ wp_enqueue_style( 'p3_css', plugins_url() . '/p3-profiler/css/p3.css' );
91
+ }
92
+
93
+ /**
94
+ * Initialize, upgrade, etc.
95
+ * Determine the action from the query string that guides the exection path
96
+ * Catch any special actions here (e.g. download a file)
97
+ */
98
+ public static function init() {
99
+
100
+ // Determine the profiles path
101
+ $uploads_dir = wp_upload_dir();
102
+ define( 'P3_PROFILES_PATH', $uploads_dir['basedir'] . DIRECTORY_SEPARATOR . 'profiles' );
103
+
104
+ // Upgrade
105
+ self::upgrade();
106
+
107
+ // Set up the request based on p3_action
108
+ if ( !empty( $_REQUEST['p3_action'] ) ) {
109
+ self::$action = $_REQUEST['p3_action'];
110
+ }
111
+ if ( empty( self::$action ) || 'current-scan' == self::$action ) {
112
+ self::$scan = self::get_latest_profile();
113
+ self::$action = 'current-scan';
114
+ } elseif ( 'view-scan' == self::$action ) {
115
+ self::$scan = '';
116
+ if ( !empty( $_REQUEST['name'] ) ) {
117
+ self::$scan = sanitize_file_name( basename( $_REQUEST['name'] ) );
118
+ } else {
119
+ self::$scan = basename( self::get_latest_profile() );
120
+ }
121
+ if ( empty( self::$scan ) || !file_exists( P3_PROFILES_PATH . DIRECTORY_SEPARATOR . self::$scan ) ) {
122
+ self::add_notice( __( 'Scan does not exist', 'p3-profiler' ), true );
123
+ }
124
+ self::$scan = P3_PROFILES_PATH . DIRECTORY_SEPARATOR . self::$scan;
125
+ }
126
+
127
+ // Download the debug logs before output is sent
128
+ if ( 'download-debug-log' == self::$action ) {
129
+ self::download_debug_log();
130
+ } elseif ( 'clear-debug-log' == self::$action ) {
131
+ self::clear_debug_log();
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Dispatcher function. All requests enter through here
137
+ * and are routed based upon the p3_action request variable
138
+ * @return void
139
+ */
140
+ public static function dispatcher() {
141
+
142
+ // If there's a scan, create a viewer object
143
+ if ( !empty( self::$scan ) ) {
144
+ try {
145
+ self::$profile = new P3_Profiler_Reader( self::$scan );
146
+ } catch ( P3_Profiler_No_Data_Exception $e ) {
147
+ echo '<div class="error"><p>' .
148
+ sprintf( __( 'No visits recorded during this profiling session. Check the <a href="%s">help</a> page for more information', 'p3-profiler' ),
149
+ add_query_arg( array( 'p3_action' => 'help', 'current_scan' => null ) ) . '#q-circumvent-cache"'
150
+ ) .
151
+ '</p></div>';
152
+ self::$scan = null;
153
+ self::$profile = null;
154
+ self::$action = 'list-scans';
155
+ } catch ( Exception $e ) {
156
+ echo '<div class="error"><p>' . __( 'Error reading scan', 'p3-profiler' ) . '</p></div>';
157
+ }
158
+ } else {
159
+ self::$profile = null;
160
+ }
161
+
162
+ // Usability message
163
+ if ( !defined( 'WPP_PROFILING_STARTED' ) ) {
164
+ echo '<div class="updated"><p>' . __( 'Click "Start Scan" to run a performance scan of your website.', 'p3-profiler' ) . '</p></div>';
165
+ }
166
+
167
+ // Load the list table, let it handle any bulk actions
168
+ if ( empty( self::$profile ) && in_array( self::$action, array( 'list-scans', 'current-scan' ) ) ) {
169
+ self::$scan_table = new P3_Profiler_Table();
170
+ self::$scan_table->prepare_items();
171
+ }
172
+
173
+ // Load scripts & styles
174
+ self::load_scripts();
175
+ self::load_styles();
176
+
177
+ // Show the page
178
+ require_once P3_PATH . '/templates/template.php';
179
+ }
180
+
181
+ /**
182
+ * Get a list of pages for the auto-scanner
183
+ * @return array
184
+ */
185
+ public static function list_of_pages() {
186
+
187
+ // Start off the scan with the home page
188
+ $pages = array( get_home_url() ); // Home page
189
+
190
+ // Search for a word from the blog description
191
+ $words = array_merge( explode( ' ', get_bloginfo( 'name' ) ), explode( ' ', get_bloginfo( 'description' ) ) );
192
+ $pages[] = home_url( '?s=' . $words[ mt_rand( 0, count( $words ) - 1 ) ] );
193
+
194
+ // Get 4 random tags
195
+ $func = create_function('', "return 'rand()';");
196
+ add_filter( 'get_terms_orderby', $func );
197
+ $terms = get_terms( 'post_tag', 'number=4' );
198
+ foreach ( (array) $terms as $term ) {
199
+ $pages[] = get_term_link( $term );
200
+ }
201
+
202
+ // Get 4 random categories
203
+ $cats = get_terms( 'category', 'number=4');
204
+ foreach ( (array) $cats as $cat ) {
205
+ $pages[] = get_term_link( $cat );
206
+ }
207
+ remove_filter( 'get_terms_orderby', $func );
208
+
209
+ // Get the latest 4 posts
210
+ $tmp = preg_split( '/\s+/', wp_get_archives( 'type=postbypost&limit=4&echo=0' ) );
211
+ if ( !empty( $tmp ) ) {
212
+ foreach ( $tmp as $page ) {
213
+ if ( preg_match( "/href='([^']+)'/", $page, $matches ) ) {
214
+ $pages[] = $matches[1];
215
+ }
216
+ }
217
+ }
218
+
219
+ // Scan some admin pages, too
220
+ $pages[] = admin_url();
221
+ $pages[] = admin_url('edit.php');
222
+ $pages[] = admin_url('plugins.php');
223
+
224
+ // Fix SSL
225
+ if ( true === force_ssl_admin() ) {
226
+ foreach ( $pages as $k => $v ) {
227
+ $pages[$k] = str_replace( 'http://', 'https://', $v );
228
+ }
229
+ }
230
+
231
+ // Done
232
+ return $pages;
233
+ }
234
+
235
+ /**************************************************************/
236
+ /** AJAX FUNCTIONS **/
237
+ /**************************************************************/
238
+
239
+ /**
240
+ * Ajax die
241
+ * @param string $message
242
+ */
243
+ public static function ajax_die( $message ) {
244
+ global $wp_version;
245
+ if ( version_compare( $wp_version, '3.4-dev' ) >= 0 ) {
246
+ wp_die( $message );
247
+ } else {
248
+ die( $message );
249
+ }
250
+ }
251
+
252
+ /**
253
+ * Start scan
254
+ */
255
+ public static function ajax_start_scan() {
256
+
257
+ // Check nonce
258
+ if ( !check_admin_referer( 'p3_ajax_start_scan', 'p3_nonce' ) ) {
259
+ wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
260
+ }
261
+
262
+ // Sanitize the file name
263
+ $filename = sanitize_file_name( basename( $_POST['p3_scan_name'] ) );
264
+
265
+ // Add the entry ( multisite installs can run more than one concurrent profile )
266
+ delete_transient( 'p3_profiler-error_detection' );
267
+ $opts = get_option( 'p3-profiler_options' );
268
+ $opts['profiling_enabled'] = array(
269
+ 'ip' => stripslashes( $_POST['p3_ip'] ),
270
+ 'disable_opcode_cache' => ( 'true' == $_POST['p3_disable_opcode_cache'] ),
271
+ 'name' => $filename,
272
+ );
273
+ update_option( 'p3-profiler_options', $opts );
274
+
275
+ // Kick start the profile file
276
+ if ( !file_exists( P3_PROFILES_PATH . "/$filename.json" ) ) {
277
+ $flag = file_put_contents( P3_PROFILES_PATH . "/$filename.json", '' );
278
+ } else {
279
+ $flag = true;
280
+ }
281
+
282
+ // Check if either operation failed
283
+ if ( false === $flag ) {
284
+ self::ajax_die( 0 );
285
+ } else {
286
+ self::ajax_die( 1 );
287
+ }
288
+ }
289
+
290
+ /**
291
+ * Stop scan
292
+ */
293
+ public static function ajax_stop_scan() {
294
+
295
+ // Check nonce
296
+ if ( !check_admin_referer( 'p3_ajax_stop_scan', 'p3_nonce' ) ) {
297
+ wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
298
+ }
299
+
300
+ // Get current options
301
+ $opts = get_option( 'p3-profiler_options' );
302
+ $opts = $opts['profiling_enabled'];
303
+
304
+ // Turn off scanning
305
+ p3_profiler_disable();
306
+
307
+ // Tell the user what happened
308
+ self::add_notice( __( 'Turned off performance scanning.', 'p3-profiler' ) );
309
+
310
+ // Return the last filename
311
+ if ( !empty( $opts ) && is_array( $opts ) && array_key_exists( 'name', $opts ) ) {
312
+ echo $opts['name'] . '.json';
313
+ self::ajax_die( '' );
314
+ } else {
315
+ self::ajax_die( 0 );
316
+ }
317
+ }
318
+
319
+ /**
320
+ * Save advanced settings
321
+ */
322
+ public static function ajax_save_settings() {
323
+
324
+ // Check nonce
325
+ if ( !check_admin_referer( 'p3_save_settings', 'p3_nonce' ) ) {
326
+ wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
327
+ }
328
+
329
+ // Save the new options
330
+ $opts = get_option( 'p3-profiler_options' );
331
+ $opts['disable_opcode_cache'] = ( 'true' == $_POST['p3_disable_opcode_cache'] );
332
+ $opts['cache_buster'] = ( 'true' == $_POST['p3_cache_buster'] );
333
+ $opts['use_current_ip'] = ( 'true' == $_POST['p3_use_current_ip'] );
334
+ $opts['ip_address'] = ( $_POST['p3_ip_address'] );
335
+ $opts['debug'] = ('true' == $_POST['p3_debug'] );
336
+ update_option( 'p3-profiler_options', $opts );
337
+
338
+ // Clear the debug log if it's full
339
+ if ( 'true' === $_POST['p3_debug'] ) {
340
+ $log = get_option( 'p3-profiler_debug_log' );
341
+ if ( is_array( $log ) && count( $log ) >= 100 ) {
342
+ update_option( 'p3-profiler_debug_log', array() );
343
+ }
344
+ }
345
+
346
+ self::ajax_die( 1 );
347
+ }
348
+
349
+
350
+ /**************************************************************/
351
+ /** EMAIL RESULTS **/
352
+ /**************************************************************/
353
+
354
+ /**
355
+ * Send results ( presumably to admin or support )
356
+ */
357
+ public static function ajax_send_results() {
358
+
359
+ // Check nonce
360
+ if ( !check_admin_referer( 'p3_ajax_send_results', 'p3_nonce' ) ) {
361
+ wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
362
+ }
363
+
364
+ // Check fields
365
+ $to = sanitize_email( $_POST['p3_to'] );
366
+ $from = sanitize_email( $_POST['p3_from'] );
367
+ $subject = trim( $_POST['p3_subject'] );
368
+ $message = strip_tags( $_POST['p3_message'] );
369
+ $results = strip_tags( $_POST['p3_results'] );
370
+
371
+ // Append the results to the message ( if a messge was specified )
372
+ if ( empty( $message ) ) {
373
+ $message = stripslashes( $results );
374
+ } else {
375
+ $message = stripslashes( $message . "\n\n" .$results );
376
+ }
377
+
378
+ // Check for errors and send message
379
+ if ( !is_email( $to ) || !is_email( $from ) ) {
380
+ echo '0|';
381
+ _e( 'Invalid subject', 'p3-profiler' );
382
+ } elseif ( empty( $subject ) ) {
383
+ echo '0|';
384
+ _e( 'Invalid subject', 'p3-profiler' );
385
+ } elseif ( false === wp_mail( $to, $subject, $message, "From: $from" ) ) {
386
+ echo '0|';
387
+ printf(
388
+ __( '<a href="%s" target="_blank">wp_mail()</a> function returned false', 'p3-profiler' ),
389
+ 'http://codex.wordpress.org/Function_Reference/wp_mail'
390
+ );
391
+ } else {
392
+ echo '1';
393
+ }
394
+ self::ajax_die( '' );
395
+ }
396
+
397
+ /**************************************************************/
398
+ /** DEBUG LOG FUNCTIONS **/
399
+ /**************************************************************/
400
+
401
+ /**
402
+ * Clear the debug log
403
+ */
404
+ public static function clear_debug_log() {
405
+ if ( !check_admin_referer( 'p3-clear-debug-log' ) ) {
406
+ wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
407
+ }
408
+ update_option( 'p3-profiler_debug_log', array() );
409
+ wp_redirect( add_query_arg( array( 'p3_action' => 'help' ) ) );
410
+ }
411
+
412
+ /**
413
+ * Download the debug log
414
+ */
415
+ public static function download_debug_log() {
416
+ if ( !check_admin_referer( 'p3-download-debug-log' ) ) {
417
+ wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
418
+ }
419
+ $log = get_option( 'p3-profiler_debug_log' );
420
+ if ( empty( $log ) ) {
421
+ $log = array();
422
+ }
423
+ header('Pragma: public');
424
+ header('Expires: 0');
425
+ header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
426
+ header('Content-Type: application/force-download');
427
+ header('Content-Type: application/octet-stream');
428
+ header('Content-Type: application/download');
429
+ header('Content-Disposition: attachment; filename="p3debug.csv";');
430
+ header('Content-Transfer-Encoding: binary');
431
+
432
+ // File header
433
+ printf('"%s","%s","%s","%s","%s","%s","%s","%s","%s"' . "\n",
434
+ __( 'Profiling Enabled', 'p3-profiler' ),
435
+ __( 'Recording IP', 'p3-profiler' ),
436
+ __( 'Scan Name', 'p3-profiler' ),
437
+ __( 'Recording', 'p3-profiler' ),
438
+ __( 'Disable Optimizers', 'p3-profiler' ),
439
+ __( 'URL', 'p3-profiler' ),
440
+ __( 'Visitor IP', 'p3-profiler' ),
441
+ __( 'Time', 'p3-profiler' ),
442
+ _x( 'PID', 'Abbreviation for process id', 'p3-profiler' )
443
+ );
444
+
445
+ foreach ( (array) $log as $entry ) {
446
+ printf('"%s","%s","%s","%s","%s","%s","%s","%s","%d"' . "\n",
447
+ $entry['profiling_enabled'] ? 'true' : 'false',
448
+ $entry['recording_ip'],
449
+ $entry['scan_name'],
450
+ $entry['recording'] ? 'true' : 'false',
451
+ $entry['disable_optimizers'] ? 'true' : 'false',
452
+ $entry['url'],
453
+ $entry['visitor_ip'],
454
+ date( 'Y-m-d H:i:s', $entry['time'] ),
455
+ $entry['pid']
456
+ );
457
+ }
458
+
459
+ // Done
460
+ die();
461
+ }
462
+
463
+
464
+ /**************************************************************/
465
+ /** HISTORY PAGE **/
466
+ /**************************************************************/
467
+
468
+ /**
469
+ * Get the latest performance scan
470
+ * @return string|false
471
+ */
472
+ public static function get_latest_profile() {
473
+
474
+ // Open the directory
475
+ $dir = opendir( P3_PROFILES_PATH );
476
+ if ( false === $dir ) {
477
+ wp_die( __( 'Cannot read profiles directory', 'p3-profiler' ) );
478
+ }
479
+
480
+ // Loop through the files, get the path and the last modified time
481
+ $files = array();
482
+ while ( false !== ( $file = readdir( $dir ) ) ) {
483
+ if ( '.json' == substr( $file, -5 ) && filesize( P3_PROFILES_PATH . '/' . $file ) > 0 ) {
484
+ $files[filemtime( P3_PROFILES_PATH . "/$file" )] = P3_PROFILES_PATH . "/$file";
485
+ }
486
+ }
487
+ closedir( $dir );
488
+
489
+ // If there are no files, return false
490
+ if ( empty( $files ) ) {
491
+ return false;
492
+ }
493
+
494
+ // Sort the files by the last modified time, return the latest
495
+ ksort( $files );
496
+ return array_pop( $files );
497
+ }
498
+
499
+ /**
500
+ * Add a notices
501
+ * @uses transients
502
+ * @param string $notice
503
+ * @param bool $error Default false. If true, this is a red error. If false, this is a yellow notice.
504
+ * @return void
505
+ */
506
+ public static function add_notice( $notice, $error = false ) {
507
+
508
+ // Get any notices on the stack
509
+ $notices = get_transient( 'p3_notices' );
510
+ if ( empty( $notices ) ) {
511
+ $notices = array();
512
+ }
513
+
514
+ // Add the notice to the stack
515
+ $notices[] = array(
516
+ 'msg' => $notice,
517
+ 'error' => $error,
518
+ );
519
+
520
+ // Save the stack
521
+ set_transient( 'p3_notices', $notices );
522
+ }
523
+
524
+ /**
525
+ * Display notices
526
+ * @uses transients
527
+ * @return voide
528
+ */
529
+ public static function show_notices() {
530
+ $notices = get_transient( 'p3_notices' );
531
+ if ( !empty( $notices ) ) {
532
+ $notices = array_unique( $notices );
533
+ foreach ( $notices as $notice ) {
534
+ echo '<div class="' . ( ( $notice['error'] ) ? 'error' : 'updated' ) . '"><p>' . htmlentities( $notice['msg'] ) . '</p></div>';
535
+ }
536
+ }
537
+ set_transient( 'p3_notices', array() );
538
+ if ( false !== self::scan_enabled() ) {
539
+ echo '<div class="updated"><p>' . __( 'Performance scanning is enabled.', 'p3-profiler' ) . '</p></div>';
540
+ }
541
+ }
542
+
543
+ /**
544
+ * Make the profiles folder
545
+ * @param string $path
546
+ */
547
+ public static function make_profiles_folder( $path ) {
548
+ wp_mkdir_p( $path );
549
+ if ( !file_exists( "$path/.htaccess" ) ) {
550
+ file_put_contents( $path . DIRECTORY_SEPARATOR . '.htaccess', "Deny from all\n" );
551
+ }
552
+ if ( !file_exists( "$path/index.php" ) ) {
553
+ file_put_contents( $path. DIRECTORY_SEPARATOR . 'index.php', '<' . "?php header( 'Status: 404 Not found' ); ?" . ">\nNot found" );
554
+ }
555
+ }
556
+
557
+ /**
558
+ * Delete the profiles folder
559
+ * @param string $path
560
+ */
561
+ public static function delete_profiles_folder( $path ) {
562
+ if ( !file_exists( $path ) )
563
+ return;
564
+ $dir = opendir( $path );
565
+ while ( ( $file = readdir( $dir ) ) !== false ) {
566
+ if ( $file != '.' && $file != '..' ) {
567
+ unlink( $path . DIRECTORY_SEPARATOR . $file );
568
+ }
569
+ }
570
+ closedir( $dir );
571
+ rmdir( $path );
572
+ }
573
+
574
+ /**
575
+ * Check to see if a scan is enabled
576
+ * @return array|false
577
+ */
578
+ public static function scan_enabled() {
579
+ $opts = get_option( 'p3-profiler_options' );
580
+ if ( !empty( $opts['profiling_enabled'] ) ) {
581
+ return $opts['profiling_enabled'];
582
+ }
583
+ return false;
584
+ }
585
+
586
+ /**
587
+ * Convert a filesize ( in bytes ) to a human readable filesize
588
+ * @param int $size
589
+ * @return string
590
+ */
591
+ public static function readable_size( $size ) {
592
+ $units = array(
593
+ _x( 'B', 'Abbreviation for bytes', 'p3-profiler' ),
594
+ _x( 'KB', 'Abbreviation for kilobytes', 'p3-profiler' ),
595
+ _x( 'MB', 'Abbreviation for megabytes', 'p3-profiler' ),
596
+ _x( 'GB', 'Abbreviation for gigabytes', 'p3-profiler' ),
597
+ _x( 'TB', 'Abbreviation for terabytes', 'p3-profiler' )
598
+ );
599
+ $size = max( $size, 0 );
600
+ $pow = floor( ( $size ? log( $size ) : 0 ) / log( 1024 ) );
601
+ $pow = min( $pow, count( $units ) - 1 );
602
+ $size /= pow( 1024, $pow );
603
+ return round( $size, 0 ) . ' ' . $units[$pow];
604
+ }
605
+
606
+ /**
607
+ * Actions to take when a multisite blog is removed
608
+ */
609
+ public static function delete_blog() {
610
+ $uploads_dir = wp_upload_dir();
611
+ $folder = $uploads_dir['basedir'] . DIRECTORY_SEPARATOR . 'profiles' . DIRECTORY_SEPARATOR;
612
+ self::delete_profiles_folder( $folder );
613
+ delete_option( 'p3-profiler_version' );
614
+ delete_option( 'p3-profiler_options' );
615
+ delete_option( 'p3-profiler_debug_log' );
616
+ }
617
+
618
+ /**
619
+ * Upgrade
620
+ * Check options, perform any necessary data conversions
621
+ */
622
+ public static function upgrade() {
623
+
624
+ // Get the current version
625
+ $version = get_option( 'p3-profiler_version' );
626
+
627
+ // Upgrading from < 1.1.0
628
+ if ( empty( $version ) || version_compare( $version, '1.1.0' ) < 0 ) {
629
+ update_option( 'p3-profiler_disable_opcode_cache', true );
630
+ update_option( 'p3-profiler_use_current_ip', true );
631
+ update_option( 'p3-profiler_ip_address', '' );
632
+ update_option( 'p3-profiler_version', '1.1.0' );
633
+ }
634
+
635
+ // Upgrading from < 1.1.2
636
+ if ( empty( $version) || version_compare( $version, '1.1.2' ) < 0 ) {
637
+ update_option( 'p3-profiler_cache_buster', true );
638
+ update_option( 'p3-profiler_version', '1.1.2' );
639
+ }
640
+
641
+ // Upgrading from < 1.2.0
642
+ if ( empty( $version) || version_compare( $version, '1.2.0' ) < 0 ) {
643
+
644
+ // Set profiling option
645
+ update_option( 'p3-profiler_profiling_enabled', false );
646
+ update_option( 'p3-profiler_version', '1.2.0' );
647
+ update_option( 'p3-profiler_debug', false );
648
+ update_option( 'p3-profiler_debug_log', array() );
649
+
650
+ // Remove any .htaccess modifications
651
+ $file = ABSPATH . '/.htaccess';
652
+ if ( file_exists( $file ) && array() !== extract_from_markers( $file, 'p3-profiler' ) ) {
653
+ insert_with_markers( $file, 'p3-profiler', array( '# removed during 1.2.0 upgrade' ) );
654
+ }
655
+
656
+ // Remove .profiling_enabled if it's still present
657
+ if ( file_exists( P3_PATH . '/.profiling_enabled' ) ) {
658
+ @unlink( P3_PATH . '/.profiling_enabled' );
659
+ }
660
+ }
661
+
662
+ // Upgrading from < 1.3.0
663
+ if ( empty( $version) || version_compare( $version, '1.3.0' ) < 0 ) {
664
+ update_option( 'p3-profiler_version', '1.3.0' );
665
+
666
+ // Move to a serialized single option
667
+ $opts = array(
668
+ 'profiling_enabled' => get_option( 'p3-profiler_profiling_enabled' ),
669
+ 'disable_opcode_cache' => get_option( 'p3-profiler_disable_opcode_cache' ),
670
+ 'use_current_ip' => get_option( 'p3-profiler_use_current_ip' ),
671
+ 'ip_address' => get_option( 'p3-profiler_ip_address' ),
672
+ 'cache_buster' => get_option( 'p3-profiler_cache_buster' ),
673
+ 'debug' => get_option( 'p3-profiler_debug' )
674
+ );
675
+ update_option( 'p3-profiler_options', $opts );
676
+
677
+ // Delete the extra options
678
+ delete_option( 'p3-profiler_disable_opcode_cache' );
679
+ delete_option( 'p3-profiler_use_current_ip' );
680
+ delete_option( 'p3-profiler_ip_address' );
681
+ delete_option( 'p3-profiler_cache_buster' );
682
+ delete_option( 'p3-profiler_debug' );
683
+ delete_option( 'p3-profiler_profiling_enabled' );
684
+ }
685
+
686
+ // Ensure the profiles folder is there
687
+ $uploads_dir = wp_upload_dir();
688
+ $folder = $uploads_dir['basedir'] . DIRECTORY_SEPARATOR . 'profiles';
689
+ self::make_profiles_folder( $folder );
690
+ }
691
+ }
classes/class.p3-profiler-plugin.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * P3 Plugin Performance Profiler Plugin
5
+ *
6
+ * @author GoDaddy.com
7
+ * @package P3_Profiler
8
+ */
9
+ class P3_Profiler_Plugin {
10
+
11
+ /**
12
+ * Add the 'P3 Profiler' option under the 'Tools' menu
13
+ */
14
+ public static function tools_menu() {
15
+ $page = add_management_page(
16
+ __( 'P3 Plugin Profiler', 'p3-profiler' ),
17
+ __( 'P3 Plugin Profiler', 'p3-profiler' ),
18
+ 'manage_options',
19
+ P3_PLUGIN_SLUG,
20
+ array( 'P3_Profiler_Plugin_Admin', 'dispatcher' )
21
+ );
22
+ }
23
+
24
+
25
+ /**
26
+ * Show the "Profile now" option on the plugins table
27
+ * @param array $links
28
+ * @param string $file
29
+ * @return array New links
30
+ */
31
+ public static function add_settings_link( $links, $file ) {
32
+ $settings_link = '<a href="tools.php?page=p3-profiler">' . __( 'Scan Now', 'p3-profiler' ) . '</a>';
33
+ // p3-profiler === p3-profiler
34
+ if ( dirname( plugin_basename( $file ) ) === basename( P3_PATH ) )
35
+ array_unshift( $links, $settings_link );
36
+ return $links;
37
+ }
38
+
39
+ /**
40
+ * Load the language file
41
+ */
42
+ public static function load_language() {
43
+ load_plugin_textdomain( 'p3-profiler', false, plugin_basename( P3_PATH ) . '/languages/' );
44
+ }
45
+
46
+ /**
47
+ * Activation hook
48
+ * Install the profiler loader as a mu-plugin
49
+ */
50
+ public static function activate() {
51
+ global $wp_version;
52
+
53
+ // Version check, only 3.3+
54
+ if ( ! version_compare( $wp_version, '3.3', '>=' ) ) {
55
+ if ( function_exists( 'deactivate_plugins' ) )
56
+ deactivate_plugins( __FILE__ );
57
+ die( '<strong>P3</strong> requires WordPress 3.3 or later' );
58
+ }
59
+
60
+ // mu-plugins doesn't exist
61
+ if ( !file_exists( WPMU_PLUGIN_DIR ) && is_writable( dirname( WPMU_PLUGIN_DIR ) ) ) {
62
+ wp_mkdir_p( WPMU_PLUGIN_DIR );
63
+ }
64
+ if ( file_exists( WPMU_PLUGIN_DIR ) && is_writable( WPMU_PLUGIN_DIR ) ) {
65
+ file_put_contents(
66
+ WPMU_PLUGIN_DIR . '/p3-profiler.php',
67
+ '<' . "?php // Start profiling\n@include_once( WP_PLUGIN_DIR . '/p3-profiler/start-profile.php' ); ?" . '>'
68
+ );
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Deactivation hook
74
+ * Remove the profiler loader
75
+ * @return void
76
+ */
77
+ public static function deactivate() {
78
+ global $p3_profiler;
79
+
80
+ // Unhook the profiler
81
+ $opts = get_option( 'p3-profiler_options' );
82
+ $opts['debug'] = false;
83
+ update_option( 'p3-profiler_options', $opts );
84
+ update_option( 'p3-profiler_debug_log', array() );
85
+ if ( !empty( $p3_profiler ) ) {
86
+ remove_action( 'shutdown', array( $p3_profiler, 'shutdown_handler' ) );
87
+ }
88
+
89
+ // Remove mu-plugin
90
+ if ( file_exists( WPMU_PLUGIN_DIR . '/p3-profiler.php' ) ) {
91
+ if ( is_writable( WPMU_PLUGIN_DIR . '/p3-profiler.php' ) ) {
92
+ // Some servers give write permission, but not delete permission. Empty the file out, first, then try to delete it.
93
+ file_put_contents( WPMU_PLUGIN_DIR . '/p3-profiler.php', '' );
94
+ unlink( WPMU_PLUGIN_DIR . '/p3-profiler.php' );
95
+ }
96
+ }
97
+ }
98
+ }
class.p3-profile-reader.php → classes/class.p3-profiler-reader.php RENAMED
@@ -9,7 +9,7 @@ if ( !defined('P3_PATH') )
9
  * @version 1.0
10
  * @package P3_Profiler
11
  */
12
- class P3_Profile_Reader {
13
 
14
  /**
15
  * Total site load time (profile + theme + core + plugins)
@@ -145,14 +145,14 @@ if ( !defined('P3_PATH') )
145
  /**
146
  * Constructor
147
  * @param string $file Full path to the profile json file
148
- * @return P3_Profile_Reader
149
  */
150
  public function __construct( $file ) {
151
 
152
  // Open the file
153
  $fp = fopen( $file, 'r' );
154
  if ( FALSE === $fp ) {
155
- throw new Exception( 'Cannot open ' . $file );
156
  }
157
 
158
  // Decode each line. Each line is a separate json object. Whenever a
@@ -164,7 +164,7 @@ if ( !defined('P3_PATH') )
164
  }
165
  $tmp = json_decode( $line );
166
  if ( null === $tmp ) {
167
- throw new Exception( 'Cannot parse ' . $file );
168
  fclose( $fp );
169
  }
170
  $this->_data[] = $tmp;
@@ -188,7 +188,7 @@ if ( !defined('P3_PATH') )
188
 
189
  // Check for empty data
190
  if ( empty( $this->_data ) ) {
191
- throw new P3_Profile_No_Data_Exception('No visits recorded during this profiling session.');
192
  }
193
 
194
  foreach ( $this->_data as $o ) {
@@ -335,7 +335,10 @@ if ( !defined('P3_PATH') )
335
  * @return string
336
  */
337
  private function _get_theme_name( $theme ) {
338
- if ( function_exists( 'get_theme_data' ) && file_exists( WP_CONTENT_DIR . '/themes/' . $theme . '/style.css' ) ) {
 
 
 
339
  $theme_info = get_theme_data( WP_CONTENT_DIR . '/themes/' . $theme . '/style.css' );
340
  if ( !empty( $theme_info ) && !empty( $theme_info['Name'] ) ) {
341
  return $theme_info['Name'];
9
  * @version 1.0
10
  * @package P3_Profiler
11
  */
12
+ class P3_Profiler_Reader {
13
 
14
  /**
15
  * Total site load time (profile + theme + core + plugins)
145
  /**
146
  * Constructor
147
  * @param string $file Full path to the profile json file
148
+ * @return P3_Profiler_Reader
149
  */
150
  public function __construct( $file ) {
151
 
152
  // Open the file
153
  $fp = fopen( $file, 'r' );
154
  if ( FALSE === $fp ) {
155
+ throw new Exception( __( 'Cannot open file: ', 'p3-profiler' ) . $file );
156
  }
157
 
158
  // Decode each line. Each line is a separate json object. Whenever a
164
  }
165
  $tmp = json_decode( $line );
166
  if ( null === $tmp ) {
167
+ throw new Exception( __( 'Cannot parse file: ', 'p3-profiler' ) . $file );
168
  fclose( $fp );
169
  }
170
  $this->_data[] = $tmp;
188
 
189
  // Check for empty data
190
  if ( empty( $this->_data ) ) {
191
+ throw new P3_Profiler_No_Data_Exception( __( 'No visits recorded during this profiling session.', 'p3-profiler' ) );
192
  }
193
 
194
  foreach ( $this->_data as $o ) {
335
  * @return string
336
  */
337
  private function _get_theme_name( $theme ) {
338
+ if ( function_exists( 'wp_get_theme') ) {
339
+ $theme_info = wp_get_theme( $theme );
340
+ return $theme_info->get('Name');
341
+ } elseif ( function_exists( 'get_theme_data' ) && file_exists( WP_CONTENT_DIR . '/themes/' . $theme . '/style.css' ) ) {
342
  $theme_info = get_theme_data( WP_CONTENT_DIR . '/themes/' . $theme . '/style.css' );
343
  if ( !empty( $theme_info ) && !empty( $theme_info['Name'] ) ) {
344
  return $theme_info['Name'];
class.p3-profile-table-sorter.php → classes/class.p3-profiler-table-sorter.php RENAMED
@@ -9,7 +9,7 @@ if ( !defined('P3_PATH') )
9
  * @version 1.0
10
  * @package P3_Profiler
11
  */
12
- class P3_Profile_Table_Sorter {
13
 
14
  /**
15
  * The field name to sort by
9
  * @version 1.0
10
  * @package P3_Profiler
11
  */
12
+ class P3_Profiler_Table_Sorter {
13
 
14
  /**
15
  * The field name to sort by
class.p3-profile-table.php → classes/class.p3-profiler-table.php RENAMED
@@ -9,7 +9,7 @@ if ( !defined('P3_PATH') )
9
  * @version 1.0
10
  * @package P3_Profiler
11
  */
12
- class P3_Profile_Table extends WP_List_Table {
13
 
14
  /**************************************************************************/
15
  /** SETUP **/
@@ -17,13 +17,13 @@ class P3_Profile_Table extends WP_List_Table {
17
 
18
  /**
19
  * Constructor
20
- * @return P3_Profile_Table
21
  */
22
  public function __construct() {
23
  parent::__construct(
24
  array(
25
- 'singular' => 'scan',
26
- 'plural' => 'scans',
27
  )
28
  );
29
  }
@@ -103,7 +103,7 @@ class P3_Profile_Table extends WP_List_Table {
103
  */
104
  public function column_title( $item ) {
105
  $actions = array(
106
- 'delete' => sprintf( '<a href="?page=%s&action=%s&name=%s">Delete</a>', sanitize_text_field( $_REQUEST['name'] ), 'delete', $item['name'] ),
107
  );
108
 
109
  //Return the title contents
@@ -135,10 +135,10 @@ class P3_Profile_Table extends WP_List_Table {
135
  public function get_columns() {
136
  $columns = array(
137
  'cb' => '<input type="checkbox" />',
138
- 'name' => 'Name',
139
- 'date' => 'Date',
140
- 'count' => 'Visits',
141
- 'filesize' => 'Size',
142
  );
143
  return $columns;
144
  }
@@ -171,20 +171,19 @@ class P3_Profile_Table extends WP_List_Table {
171
  'current_scan' => null,
172
  )
173
  );
174
- return <<<EOD
175
- <a href="$url" title="View the results of this scan"><strong>$display</strong></a>
176
- <div class="row-actions-visible">
177
- <span class="view">
178
- <a href="$url" data-name="$key" title="View the results of this scan" class="view-results">View</a> |
179
- </span>
180
- <span>
181
- <a href="javascript:;" data-name="$key" title="Continue this scan" class="p3-continue-scan">Continue</a> |
182
- </span>
183
- <span class="delete">
184
- <a href="javascript:;" data-name="$key" title="Delete this scan" class="delete-scan delete">Delete</a>
185
- </span>
186
- </div>
187
- EOD;
188
  }
189
 
190
  /**************************************************************************/
@@ -196,7 +195,7 @@ EOD;
196
  * @return string
197
  */
198
  public function get_bulk_actions() {
199
- $actions = array( 'delete' => 'Delete' );
200
  return $actions;
201
  }
202
 
@@ -208,16 +207,18 @@ EOD;
208
  global $p3_profiler_plugin;
209
  if ( 'delete' === $this->current_action() && !empty( $_REQUEST['scan'] ) ) {
210
  if ( !wp_verify_nonce( $_REQUEST['p3_nonce'], 'delete_scans' ) ) {
211
- wp_die( 'Invalid nonce' );
212
  }
213
  foreach ( $_REQUEST['scan'] as $scan ) {
214
  $file = P3_PROFILES_PATH . DIRECTORY_SEPARATOR . basename( $scan );
215
  if ( !file_exists( $file ) || !is_writable( $file ) || !unlink( $file ) ) {
216
- wp_die( 'Error removing file ' . $file );
217
  }
218
  }
219
  $count = count( $_REQUEST['scan'] );
220
- printf('<div id="updated"><p>Deleted %d %s.</p></div>', $count, ($count == 1) ? 'scan' : 'scans' );
 
 
221
  }
222
  }
223
 
@@ -247,7 +248,7 @@ EOD;
247
  $field = '_filesize';
248
  break;
249
  }
250
- $sorter = new P3_Profile_Table_Sorter( $data, $field );
251
  return $sorter->sort( $direction );
252
  }
253
 
@@ -273,7 +274,7 @@ EOD;
273
  'name' => $this->_action_links( $key, $name ),
274
  'date' => date( 'D, M jS', $time ) . ' at ' . date( 'g:i a', $time ),
275
  'count' => number_format( $count ),
276
- 'filesize' => $GLOBALS['p3_profiler_plugin']->readable_size( filesize( $file ) ),
277
  '_filesize' => filesize( $file ),
278
  '_date' => $time,
279
  '_count' => $count,
9
  * @version 1.0
10
  * @package P3_Profiler
11
  */
12
+ class P3_Profiler_Table extends WP_List_Table {
13
 
14
  /**************************************************************************/
15
  /** SETUP **/
17
 
18
  /**
19
  * Constructor
20
+ * @return P3_Profiler_Table
21
  */
22
  public function __construct() {
23
  parent::__construct(
24
  array(
25
+ 'singular' => _n( 'scan', 'scans', 1, 'p3-profiler' ),
26
+ 'plural' => _n( 'scan', 'scans', 2, 'p3-profiler' ),
27
  )
28
  );
29
  }
103
  */
104
  public function column_title( $item ) {
105
  $actions = array(
106
+ 'delete' => sprintf( '<a href="?page=%s&action=%s&name=%s">' . __( 'Delete', 'p3-profiler' ) . '</a>', sanitize_text_field( $_REQUEST['name'] ), 'delete', $item['name'] ),
107
  );
108
 
109
  //Return the title contents
135
  public function get_columns() {
136
  $columns = array(
137
  'cb' => '<input type="checkbox" />',
138
+ 'name' => __( 'Name', 'p3-profiler' ),
139
+ 'date' => __( 'Date', 'p3-profiler' ),
140
+ 'count' => __( 'Visits', 'p3-profiler' ),
141
+ 'filesize' => __( 'Size', 'p3-profiler' ),
142
  );
143
  return $columns;
144
  }
171
  'current_scan' => null,
172
  )
173
  );
174
+ $ret = '<a href="' . esc_attr( $url ). '" title="' . esc_attr__( 'View the results of this scan', 'p3-profiler' ) . '"><strong>' . $display . '</strong></a>';
175
+ $ret .= '<div class="row-actions-visible">';
176
+ $ret .= ' <span class="view">';
177
+ $ret .= ' <a href="' . esc_attr( $url ) . '" data-name="' . esc_attr( $key ) . '" title="' . esc_attr__( 'View the results of this scan', 'p3-profiler' ) . '" class="view-results">' . __( 'View', 'p3-profiler' ) . '</a> |';
178
+ $ret .= ' </span>';
179
+ $ret .= ' <span>';
180
+ $ret .= ' <a href="javascript:;" data-name="' . esc_attr( $key ) . '" title="' . esc_attr__( 'Continue this scan', 'p3-profiler' ) . '" class="p3-continue-scan">' . __( 'Continue', 'p3-profiler' ) . '</a> |';
181
+ $ret .= ' </span>';
182
+ $ret .= ' <span class="delete">';
183
+ $ret .= ' <a href="javascript:;" data-name="' . esc_attr( $key ) . '" title="' . esc_attr__( 'Delete this scan', 'p3-profiler' ) . '" class="delete-scan delete">' . __( 'Delete', 'p3-profiler' ) . '</a>';
184
+ $ret .= ' </span>';
185
+ $ret .= '</div>';
186
+ return $ret;
 
187
  }
188
 
189
  /**************************************************************************/
195
  * @return string
196
  */
197
  public function get_bulk_actions() {
198
+ $actions = array( 'delete' => __( 'Delete', 'p3-profiler' ) );
199
  return $actions;
200
  }
201
 
207
  global $p3_profiler_plugin;
208
  if ( 'delete' === $this->current_action() && !empty( $_REQUEST['scan'] ) ) {
209
  if ( !wp_verify_nonce( $_REQUEST['p3_nonce'], 'delete_scans' ) ) {
210
+ wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
211
  }
212
  foreach ( $_REQUEST['scan'] as $scan ) {
213
  $file = P3_PROFILES_PATH . DIRECTORY_SEPARATOR . basename( $scan );
214
  if ( !file_exists( $file ) || !is_writable( $file ) || !unlink( $file ) ) {
215
+ wp_die( __( 'Error removing file: ', 'p3-profiler' ) . $file );
216
  }
217
  }
218
  $count = count( $_REQUEST['scan'] );
219
+ echo '<div class="updated"><p>'
220
+ . sprintf( _n( 'Deleted %d scan. ', 'Deleted %d scans.' , $count, 'p3-profiler' ), $count )
221
+ . '</p></div>';
222
  }
223
  }
224
 
248
  $field = '_filesize';
249
  break;
250
  }
251
+ $sorter = new P3_Profiler_Table_Sorter( $data, $field );
252
  return $sorter->sort( $direction );
253
  }
254
 
274
  'name' => $this->_action_links( $key, $name ),
275
  'date' => date( 'D, M jS', $time ) . ' at ' . date( 'g:i a', $time ),
276
  'count' => number_format( $count ),
277
+ 'filesize' => P3_Profiler_Plugin_Admin::readable_size( filesize( $file ) ),
278
  '_filesize' => filesize( $file ),
279
  '_date' => $time,
280
  '_count' => $count,
class.p3-profiler.php → classes/class.p3-profiler.php RENAMED
@@ -121,7 +121,7 @@ class P3_Profiler {
121
 
122
  // Set up paths
123
  $this->_P3_PATH = realpath( dirname( __FILE__ ) );
124
-
125
  // Debug mode
126
  $this->_debug_entry = array(
127
  'profiling_enabled' => false,
@@ -130,7 +130,7 @@ class P3_Profiler {
130
  'recording' => false,
131
  'disable_optimizers' => false,
132
  'url' => $this->_get_url(),
133
- 'visitor_ip' => $this->get_ip(),
134
  'time' => time(),
135
  'pid' => getmypid()
136
  );
@@ -138,19 +138,19 @@ class P3_Profiler {
138
  // Check to see if we should profile
139
  $opts = array();
140
  if ( function_exists( 'get_option') ) {
141
- $opts = get_option('p3-profiler_profiling_enabled');
142
- if ( !empty( $opts ) ) {
143
  if ( isset( $this->_debug_entry ) ) {
144
  $this->_debug_entry['profiling_enabled'] = true;
145
- $this->_debug_entry['scan_name'] = $opts['name'];
146
- $this->_debug_entry['recording_ip'] = $opts['ip'];
147
- $this->_debug_entry['disable_optimizers'] = $opts['disable_opcode_cache'];
148
  }
149
  }
150
  }
151
 
152
  // Add a global flag to let everyone know we're profiling
153
- if ( !empty( $opts ) && preg_match( '/' . $opts['ip'] . '/', $this->get_ip() ) ) {
154
  define( 'WPP_PROFILING_STARTED', true );
155
  }
156
 
@@ -162,12 +162,31 @@ class P3_Profiler {
162
  return $this;
163
  }
164
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  // Kludge memory limit / time limit
166
- @ini_set( 'memory_limit', '128M' );
 
 
167
  @set_time_limit( 90 );
168
 
 
 
 
169
  // Set the profile file
170
- $this->_profile_filename = $opts['name'] . '.json';
171
 
172
  // Start timing
173
  $this->_start_time = microtime( true );
@@ -185,7 +204,7 @@ class P3_Profiler {
185
  // Add some startup information
186
  $this->_profile = array(
187
  'url' => $this->_get_url(),
188
- 'ip' => $this->get_ip(),
189
  'pid' => getmypid(),
190
  'date' => @date( 'c' ),
191
  'stack' => array()
@@ -193,7 +212,7 @@ class P3_Profiler {
193
 
194
  // Disable opcode optimizers. These "optimize" calls out of the stack
195
  // and hide calls from the tick handler and backtraces
196
- if ( $opts['disable_opcode_cache'] ) {
197
  if ( extension_loaded( 'xcache' ) ) {
198
  @ini_set( 'xcache.optimizer', false ); // Will be implemented in 2.0, here for future proofing
199
  // XCache seems to do some optimizing, anyway. The recorded stack size is smaller with xcache.cacher enabled than without.
@@ -485,8 +504,21 @@ class P3_Profiler {
485
  */
486
  public function shutdown_handler() {
487
 
 
 
 
 
 
 
 
 
 
 
 
 
488
  // Write debug log
489
- if ( get_option( 'p3-profiler_debug' ) ) {
 
490
  $this->_write_debug_log();
491
  }
492
 
@@ -585,11 +617,10 @@ class P3_Profiler {
585
  // Throw away unneeded information to make the profiles smaller
586
  unset( $this->_profile['stack'] );
587
 
588
- // Open the file and acquire an exclusive lock ( prevent multiple hits from stomping on our
589
- // previous profiles
590
  $uploads_dir = wp_upload_dir();
591
  $path = $uploads_dir['basedir'] . DIRECTORY_SEPARATOR . 'profiles' . DIRECTORY_SEPARATOR . $this->_profile_filename;
592
- file_put_contents( $path, json_encode( $this->_profile ) . PHP_EOL, FILE_APPEND );
593
  }
594
 
595
  /**
@@ -601,55 +632,10 @@ class P3_Profiler {
601
  if ( !empty( $url ) ) {
602
  return $url;
603
  }
604
- $protocol = 'http://';
605
- if ( ( !empty( $_SERVER['HTTPS'] ) && 'on' == strtolower( $_SERVER['HTTPS'] ) ) || 443 == $_SERVER['SERVER_PORT'] ) {
606
- $protocol = 'https://';
607
- }
608
- $domain = $_SERVER['HTTP_HOST'];
609
- if ( !empty( $_SERVER['REQUEST_URI'] ) ) {
610
- $file = '';
611
- $query_string = '';
612
- $path = preg_replace( '/[?&]P3_NOCACHE=[a-zA-Z0-9]+/', '', $_SERVER['REQUEST_URI'] );
613
- } else {
614
- $file = '';
615
- if ( !empty( $_SERVER['SCRIPT_NAME'] ) ) {
616
- $file = $_SERVER['SCRIPT_NAME'];
617
- }
618
- $path = '';
619
- if ( !empty( $_SERVER['PATH_INFO'] ) ) {
620
- $path = $_SERVER['PATH_INFO'];
621
- } elseif ( !empty( $_SERVER['REDIRECT_URL'] ) ) {
622
- $path = $_SERVER['REDIRECT_URL'];
623
- }
624
- $query_string = '';
625
- if ( !empty( $_SERVER['QUERY_STRING'] ) ) {
626
- $query_string = '?' . preg_replace( '/[?&]P3_NOCACHE=[a-zA-Z0-9]+/', '', $_SERVER['QUERY_STRING'] );
627
- }
628
- }
629
- $url = $protocol.$domain.$file.$path.$query_string;
630
  return $url;
631
  }
632
-
633
- /**
634
- * Get the user's IP
635
- * @return string
636
- */
637
- public function get_ip() {
638
- static $ip = '';
639
- if ( !empty( $ip ) ) {
640
- return $ip;
641
- } else {
642
- if ( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
643
- $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
644
- } elseif ( !empty ( $_SERVER['HTTP_X_REAL_IP'] ) ) {
645
- $ip = $_SERVER['HTTP_X_REAL_IP'];
646
- } else {
647
- $ip = $_SERVER['REMOTE_ADDR'];
648
- }
649
- return $ip;
650
- }
651
- }
652
-
653
  /**
654
  * Disable debug mode
655
  */
@@ -665,7 +651,9 @@ class P3_Profiler {
665
  array_unshift( $debug_log, $this->_debug_entry );
666
  if ( count( $debug_log ) >= 100 ) {
667
  $debug_log = array_slice( $debug_log, 0, 100 );
668
- update_option( 'p3-profiler_debug', false );
 
 
669
  }
670
 
671
  // Write the log
121
 
122
  // Set up paths
123
  $this->_P3_PATH = realpath( dirname( __FILE__ ) );
124
+
125
  // Debug mode
126
  $this->_debug_entry = array(
127
  'profiling_enabled' => false,
130
  'recording' => false,
131
  'disable_optimizers' => false,
132
  'url' => $this->_get_url(),
133
+ 'visitor_ip' => p3_profiler_get_ip(),
134
  'time' => time(),
135
  'pid' => getmypid()
136
  );
138
  // Check to see if we should profile
139
  $opts = array();
140
  if ( function_exists( 'get_option') ) {
141
+ $opts = get_option('p3-profiler_options' );
142
+ if ( !empty( $opts['profiling_enabled'] ) ) {
143
  if ( isset( $this->_debug_entry ) ) {
144
  $this->_debug_entry['profiling_enabled'] = true;
145
+ $this->_debug_entry['scan_name'] = $opts['profiling_enabled']['name'];
146
+ $this->_debug_entry['recording_ip'] = $opts['profiling_enabled']['ip'];
147
+ $this->_debug_entry['disable_optimizers'] = $opts['profiling_enabled']['disable_opcode_cache'];
148
  }
149
  }
150
  }
151
 
152
  // Add a global flag to let everyone know we're profiling
153
+ if ( !empty( $opts ) && preg_match( '/' . $opts['profiling_enabled']['ip'] . '/', p3_profiler_get_ip() ) ) {
154
  define( 'WPP_PROFILING_STARTED', true );
155
  }
156
 
162
  return $this;
163
  }
164
 
165
+ // Emergency shut off switch
166
+ if ( isset( $_REQUEST['P3_SHUTOFF'] ) && !empty( $_REQUEST['P3_SHUTOFF'] ) ) {
167
+ p3_profiler_disable();
168
+ return $this;
169
+ }
170
+
171
+ // Error detection
172
+ $flag = get_transient( 'p3_profiler-error_detection' );
173
+ if ( !empty( $flag ) ) {
174
+ p3_profiler_disable();
175
+ delete_transient( 'p3_profiler-error_detection' );
176
+ return $this;
177
+ }
178
+
179
  // Kludge memory limit / time limit
180
+ if ( (int) @ini_get( 'memory_limit' ) < 256 ) {
181
+ @ini_set( 'memory_limit', '256M' );
182
+ }
183
  @set_time_limit( 90 );
184
 
185
+ // Set the error detection flag
186
+ set_transient( 'p3_profiler-error_detection', time() );
187
+
188
  // Set the profile file
189
+ $this->_profile_filename = $opts['profiling_enabled']['name'] . '.json';
190
 
191
  // Start timing
192
  $this->_start_time = microtime( true );
204
  // Add some startup information
205
  $this->_profile = array(
206
  'url' => $this->_get_url(),
207
+ 'ip' => p3_profiler_get_ip(),
208
  'pid' => getmypid(),
209
  'date' => @date( 'c' ),
210
  'stack' => array()
212
 
213
  // Disable opcode optimizers. These "optimize" calls out of the stack
214
  // and hide calls from the tick handler and backtraces
215
+ if ( $opts['profiling_enabled']['disable_opcode_cache'] ) {
216
  if ( extension_loaded( 'xcache' ) ) {
217
  @ini_set( 'xcache.optimizer', false ); // Will be implemented in 2.0, here for future proofing
218
  // XCache seems to do some optimizing, anyway. The recorded stack size is smaller with xcache.cacher enabled than without.
504
  */
505
  public function shutdown_handler() {
506
 
507
+ // Detect fatal errors (e.g. out of memory errors)
508
+ $error = error_get_last();
509
+ if ( empty( $error ) || E_ERROR !== $error['type'] ) {
510
+ delete_transient( 'p3_profiler-error_detection' );
511
+ } else {
512
+ set_transient( 'p3_notices', array( array(
513
+ 'msg' => sprintf( __( 'A fatal error occurred during profiling: %s in file %s on line %d ', 'p3-profiler' ), $error['message'], $error['file'], $error['line'] ),
514
+ 'error' => true,
515
+ ) ) );
516
+ }
517
+ unset( $error );
518
+
519
  // Write debug log
520
+ $opts = get_option('p3-profiler_options' );
521
+ if ( !empty( $opts['debug'] ) ) {
522
  $this->_write_debug_log();
523
  }
524
 
617
  // Throw away unneeded information to make the profiles smaller
618
  unset( $this->_profile['stack'] );
619
 
620
+ // Write the profile file
 
621
  $uploads_dir = wp_upload_dir();
622
  $path = $uploads_dir['basedir'] . DIRECTORY_SEPARATOR . 'profiles' . DIRECTORY_SEPARATOR . $this->_profile_filename;
623
+ file_put_contents( $path, json_encode( $this->_profile ) . PHP_EOL, FILE_APPEND );
624
  }
625
 
626
  /**
632
  if ( !empty( $url ) ) {
633
  return $url;
634
  }
635
+ $url = remove_query_arg( 'P3_NOCACHE', $_SERVER['REQUEST_URI'] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
636
  return $url;
637
  }
638
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
639
  /**
640
  * Disable debug mode
641
  */
651
  array_unshift( $debug_log, $this->_debug_entry );
652
  if ( count( $debug_log ) >= 100 ) {
653
  $debug_log = array_slice( $debug_log, 0, 100 );
654
+ $opts = get_option( 'p3-profiler_options' );
655
+ $opts['debug'] = false;
656
+ update_option( 'p3-profiler_options', $opts );
657
  }
658
 
659
  // Write the log
classes/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php header( 'Status: 404 Not found' ); ?>
2
+ Not found
logo.gif → css/logo.gif RENAMED
File without changes
css/p3.css CHANGED
@@ -4,6 +4,11 @@
4
  margin-top: 10px;
5
  padding: 4px;
6
  cursor: default;
 
 
 
 
 
7
  }
8
 
9
 
@@ -11,8 +16,8 @@
11
  #p3-scan-label {
12
  float: right;
13
  font-weight: bold;
14
- margin-top: 7px;
15
- margin-right: 12px;
16
  }
17
 
18
 
@@ -279,9 +284,9 @@ p3-glossary-container {
279
  text-align: center;
280
  position: absolute;
281
  float: left;
282
- margin-top: 45px;
283
- margin-left: -158px;
284
- width: 315px;
285
  left: 50%;
286
  }
287
  #p3-copyright img {
4
  margin-top: 10px;
5
  padding: 4px;
6
  cursor: default;
7
+ height: 30px;
8
+ }
9
+ #p3-navbar div:first-child {
10
+ float: left;
11
+ width: 400px;
12
  }
13
 
14
 
16
  #p3-scan-label {
17
  float: right;
18
  font-weight: bold;
19
+ margin-top: 8px;
20
+ margin-right: 14px;
21
  }
22
 
23
 
284
  text-align: center;
285
  position: absolute;
286
  float: left;
287
+ margin-top: 35px;
288
+ margin-left: -200px;
289
+ width: 400px;
290
  left: 50%;
291
  }
292
  #p3-copyright img {
exceptions/class.p3-profiler-no-data-exception.php CHANGED
@@ -10,4 +10,4 @@ if ( !defined('P3_PATH') )
10
  * @version 1.0
11
  * @package P3_Profiler
12
  */
13
- class P3_Profile_No_Data_Exception extends Exception {}
10
  * @version 1.0
11
  * @package P3_Profiler
12
  */
13
+ class P3_Profiler_No_Data_Exception extends Exception {}
languages/.htaccess ADDED
@@ -0,0 +1 @@
 
1
+ Deny from all
languages/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php header( 'Status: 404 Not found' ); ?>
2
+ Not found
p3-profiler.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: P3 (Plugin Performance Profiler)
4
  Plugin URI: http://support.godaddy.com/godaddy/wordpress-p3-plugin/
5
  Description: See which plugins are slowing down your site. Create a profile of your WordPress site's plugins' performance by measuring their impact on your site's load time.
6
  Author: GoDaddy.com
7
- Version: 1.2.0
8
  Author URI: http://www.godaddy.com/
9
  */
10
 
@@ -19,10 +19,24 @@ if ( !defined( 'ABSPATH') )
19
  // Shortcut for knowing our path
20
  define( 'P3_PATH', realpath( dirname( __FILE__ ) ) );
21
 
22
- // Directory for profiles
23
- $uploads_dir = wp_upload_dir();
24
- define( 'P3_PROFILES_PATH', $uploads_dir['basedir'] . DIRECTORY_SEPARATOR . 'profiles' );
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
  /**************************************************************************/
28
  /** START PROFILING **/
@@ -31,906 +45,75 @@ define( 'P3_PROFILES_PATH', $uploads_dir['basedir'] . DIRECTORY_SEPARATOR . 'pro
31
  // Start profiling. If it's already been started, this line won't do anything
32
  require_once P3_PATH . '/start-profile.php';
33
 
34
-
35
  /**************************************************************************/
36
  /** PLUGIN HOOKS **/
37
  /**************************************************************************/
38
 
39
- // Global plugin object
40
- $p3_profiler_plugin = new P3_Profiler_Plugin();
 
 
 
 
 
41
 
42
  // Admin hooks
43
- if ( is_admin() ) {
 
44
  // Show the 'Profiler' option under the 'Plugins' menu
45
- add_action( 'admin_menu', array( $p3_profiler_plugin, 'settings_menu' ) );
46
 
47
- // Upgrade routine
48
- add_action( 'admin_init', array( $p3_profiler_plugin, 'upgrade' ) );
49
 
50
- // Figure out the action
51
- add_action( 'admin_init', array( $p3_profiler_plugin, 'action_init' ) );
52
 
53
- // Ajax actions
54
- add_action( 'wp_ajax_p3_start_scan', array( $p3_profiler_plugin, 'ajax_start_scan' ) );
55
- add_action( 'wp_ajax_p3_stop_scan', array( $p3_profiler_plugin, 'ajax_stop_scan' ) );
56
- add_action( 'wp_ajax_p3_send_results', array( $p3_profiler_plugin, 'ajax_send_results' ) );
57
- add_action( 'wp_ajax_p3_save_settings', array( $p3_profiler_plugin, 'ajax_save_settings' ) );
58
 
59
- // Show any notices
60
- add_action( 'admin_notices', array( $p3_profiler_plugin, 'show_notices' ) );
61
 
62
- // Early init actions ( processing bulk table actions, loading libraries, etc.)
63
- add_action( 'admin_head', array( $p3_profiler_plugin, 'early_init' ) );
64
- }
65
 
66
  // Remove the admin bar when in profiling mode
67
- if ( defined( 'WPP_PROFILING_STARTED' ) || isset( $_GET['P3_HIDE_ADMIN_BAR'] ) ) {
68
- add_action( 'plugins_loaded', array( $p3_profiler_plugin, 'remove_admin_bar' ) );
69
  }
70
 
71
  // Install / uninstall hooks
72
- register_activation_hook( P3_PATH . DIRECTORY_SEPARATOR . 'p3-profiler.php', array( $p3_profiler_plugin, 'activate' ) );
73
- register_deactivation_hook( P3_PATH . DIRECTORY_SEPARATOR . 'p3-profiler.php', array( $p3_profiler_plugin, 'deactivate' ) );
74
- register_uninstall_hook( P3_PATH . DIRECTORY_SEPARATOR . 'p3-profiler.php', array( 'P3_Profiler_Plugin', 'uninstall' ) );
75
  if ( function_exists( 'is_multisite' ) && is_multisite() ) {
76
- add_action( 'wpmu_delete_blog', array( $p3_profiler_plugin, 'delete_blog' ) );
77
  }
78
 
79
  /**
80
- * P3 Plugin Performance Profiler Plugin Controller
81
- *
82
- * @author GoDaddy.com
83
- * @version 1.0
84
- * @package P3_Profiler
85
  */
86
- class P3_Profiler_Plugin {
87
-
88
- /**
89
- * List table of the profile scans
90
- * @var P3_Profile_Table
91
- */
92
- public $scan_table = null;
93
-
94
- /**
95
- * Name of the current scan being viewed
96
- * @var string
97
- */
98
- public $scan = '';
99
-
100
- /**
101
- * Current action
102
- * @var string
103
- */
104
- public $action = '';
105
-
106
- /**
107
- * Profile reader object
108
- * @var P3_Profile_Reader
109
- */
110
- public $profile = '';
111
-
112
- /**
113
- * Remove the admin bar from the customer site when profiling is enabled
114
- * to prevent skewing the numbers, as much as possible. Also prevent ssl
115
- * warnings by forcing content into ssl mode if the admin is in ssl mode
116
- * @return void
117
- */
118
- public function remove_admin_bar() {
119
- if ( !is_admin() && is_user_logged_in() ) {
120
- remove_action( 'init', '_wp_admin_bar_init' );
121
- if ( true === force_ssl_admin() ) {
122
- add_filter( 'site_url', array( $this, '_fix_url' ) );
123
- add_filter( 'admin_url', array( $this, '_fix_url' ) );
124
- add_filter( 'post_link', array( $this, '_fix_url' ) );
125
- add_filter( 'category_link', array( $this, '_fix_url' ) );
126
- add_filter( 'get_archives_link', array( $this, '_fix_url' ) );
127
- add_filter( 'tag_link', array( $this, '_fix_url' ) );
128
- add_filter( 'home_url', array( $this, '_fix_url' ) );
129
- }
130
- }
131
- }
132
-
133
- /**
134
- * Replace http with https to avoid SSL warnings in the preview iframe if the admin is in SSL
135
- * This will strip off any port numbers and will not replace URLs in off-site links
136
- * @param string $url
137
- * @return string
138
- */
139
- public function _fix_url( $url ) {
140
- static $host = '';
141
- if ( empty( $host ) ) {
142
- $host = preg_replace( '/[:\d+$]/', '', $_SERVER['HTTP_HOST'] );
143
- }
144
- return str_ireplace( 'http://' . $host, 'https://' . $host, $url );
145
- }
146
-
147
- /**
148
- * Add the 'Profiler' option under the 'Plugins' menu
149
- * @return void
150
- */
151
- public function settings_menu() {
152
- if ( function_exists( 'add_submenu_page' ) ) {
153
- $page = add_submenu_page(
154
- 'tools.php',
155
- 'P3 Plugin Profiler',
156
- 'P3 Plugin Profiler',
157
- 'manage_options',
158
- basename( __FILE__ ),
159
- array( $this, 'dispatcher' )
160
- );
161
- add_action( 'load-' . $page, array( $this, 'load_libraries' ) );
162
- add_action( 'admin_print_scripts-' . $page, array( $this, 'load_scripts' ) );
163
- add_action( 'admin_print_styles-' . $page, array( $this, 'load_styles' ) );
164
- }
165
- }
166
-
167
- /**
168
- * Load the necessary resources
169
- * @uses wp_enqueue_script
170
- * @uses jquery, jquery-ui, jquery.corners
171
- * @uses flot, flot.pie
172
- * @return void
173
- */
174
- public function load_libraries() {
175
-
176
- // Load php libraries libraries
177
- include_once P3_PATH . '/class.p3-profile-table-sorter.php';
178
- include_once P3_PATH . '/class.p3-profile-table.php';
179
- include_once P3_PATH . '/class.p3-profile-reader.php';
180
-
181
- // Load exceptions
182
- include_once P3_PATH . '/exceptions/class.p3-profiler-no-data-exception.php';
183
- }
184
-
185
- /**
186
- * Load javascripts
187
- * @uses wp_enqueue_script
188
- * @uses jquery, jquery-ui, jquery.corners
189
- * @uses flot, flot.pie
190
- * @return void
191
- */
192
- public function load_scripts() {
193
- wp_enqueue_script( 'jquery' );
194
- wp_enqueue_script( 'jquery-ui-dialog' );
195
- wp_enqueue_script( 'jquery-ui-tabs' );
196
- wp_enqueue_script( 'jquery-ui-progressbar' );
197
- wp_enqueue_script( 'flot', plugins_url() . '/p3-profiler/js/jquery.flot.min.js', array( 'jquery-ui-core' ) );
198
- wp_enqueue_script( 'flot.pie', plugins_url() . '/p3-profiler/js/jquery.flot.pie.min.js', array( 'flot' ) );
199
- wp_enqueue_script( 'flot.navigate', plugins_url() . '/p3-profiler/js/jquery.flot.navigate.js', array( 'flot' ) );
200
- wp_enqueue_script( 'p3_corners', plugins_url() . '/p3-profiler/js/jquery.corner.js', array( 'jquery-ui-core' ) );
201
- wp_enqueue_script( 'p3_qtip', plugins_url() . '/p3-profiler/js/jquery.qtip.min.js', array( 'jquery-ui-core' ) );
202
- }
203
-
204
- /**
205
- * Load styles
206
- * @uses wp_enqueue_style
207
- * @uses jquery-ui
208
- * @return void
209
- */
210
- public function load_styles() {
211
- wp_enqueue_style( 'p3_jquery_ui_css', plugins_url() . '/p3-profiler/css/custom-theme/jquery-ui-1.8.16.custom.css' );
212
- wp_enqueue_style( 'p3_qtip_css', plugins_url() . '/p3-profiler/css/jquery.qtip.min.css' );
213
- wp_enqueue_style( 'p3_css', plugins_url() . '/p3-profiler/css/p3.css' );
214
- }
215
-
216
- /**
217
- * Determine the action from the query string that guides the exection path
218
- */
219
- public function action_init() {
220
-
221
- // Only for our page
222
- if ( isset( $_REQUEST['page'] ) && basename( __FILE__ ) == $_REQUEST['page'] ) {
223
-
224
- // Set up the request based on p3_action
225
- if ( !empty( $_REQUEST['p3_action'] ) ) {
226
- $this->action = $_REQUEST['p3_action'];
227
- }
228
- if ( empty( $this->action ) || 'current-scan' == $this->action ) {
229
- $this->scan = $this->get_latest_profile();
230
- $this->action = 'current-scan';
231
- } elseif ( 'view-scan' == $this->action ) {
232
- $this->scan = '';
233
- if ( !empty( $_REQUEST['name'] ) ) {
234
- $this->scan = sanitize_file_name( basename( $_REQUEST['name'] ) );
235
- }
236
- if ( empty( $this->scan ) || !file_exists( P3_PROFILES_PATH . "/{$this->scan}" ) ) {
237
- wp_die( '<div id="message" class="error"><p>Scan does not exist</p></div>' );
238
- }
239
- $this->scan = P3_PROFILES_PATH . "/{$this->scan}";
240
- }
241
-
242
- // Download the debug logs before output is sent
243
- if ( 'download-debug-log' == $this->action ) {
244
- $this->download_debug_log();
245
- } elseif ( 'clear-debug-log' == $this->action ) {
246
- $this->clear_debug_log();
247
- }
248
- }
249
- }
250
-
251
- /**
252
- * Load the necessary resources
253
- * @uses wp_enqueue_script
254
- * @uses jquery, jquery-ui, jquery.corners
255
- * @uses flot, flot.pie
256
- * @return void
257
- */
258
- public function early_init() {
259
-
260
- // Only for our page
261
- if ( isset( $_REQUEST['page'] ) && basename( __FILE__ ) == $_REQUEST['page'] ) {
262
-
263
- // If there's a scan, create a viewer object
264
- if ( !empty( $this->scan ) ) {
265
- try {
266
- $this->profile = new P3_Profile_Reader( $this->scan );
267
- } catch ( P3_Profile_No_Data_Exception $e ) {
268
- echo '<div class="error"><p>No visits recorded during this profiling session. Check the <a href="' .
269
- add_query_arg( array( 'p3_action' => 'help', 'current_scan' => null ) ) . '#q-circumvent-cache"' .
270
- '>help</a> page for more information</p></div>';
271
- $this->scan = null;
272
- $this->profile = null;
273
- $this->action = 'list-scans';
274
- } catch ( Exception $e ) {
275
- wp_die( '<div id="message" class="error"><p>Error reading scan</p></div>' );
276
- }
277
- } else {
278
- $this->profile = null;
279
- }
280
-
281
-
282
- // Load the list table, let it handle any bulk actions
283
- if ( empty( $this->profile ) && in_array( $this->action, array( 'list-scans', 'current-scan' ) ) ) {
284
- $this->scan_table = new P3_Profile_Table();
285
- $this->scan_table->prepare_items();
286
- }
287
-
288
- // Usability message
289
- if ( !defined( 'WPP_PROFILING_STARTED' ) ) {
290
- $this->add_notice( 'Click "Start Scan" to run a performance scan of your website.' );
291
- }
292
- }
293
- }
294
-
295
- /**
296
- * Dispatcher function. All requests enter through here
297
- * and are routed based upon the p3_action request variable
298
- * @return void
299
- */
300
- public function dispatcher() {
301
- switch ( $this->action ) {
302
- case 'list-scans' :
303
- $this->list_scans();
304
- break;
305
- case 'view-scan' :
306
- $this->view_scan();
307
- break;
308
- case 'start-scan' :
309
- $this->start_scan();
310
- break;
311
- case 'help' :
312
- $this->show_help();
313
- break;
314
- default :
315
- $this->scan_settings_page();
316
- }
317
- }
318
-
319
- /**
320
- * Order terms randomly
321
- * @return string
322
- */
323
- public function get_terms_orderby() {
324
- return 'rand()';
325
- }
326
-
327
- /**
328
- * Get a list of pages for the auto-scanner
329
- * @return array
330
- */
331
- public function list_of_pages() {
332
-
333
- // Start off the scan with the home page
334
- $pages = array( get_home_url() ); // Home page
335
-
336
- // Search for a word from the blog description
337
- $words = array_merge( explode( ' ', get_bloginfo( 'name' ) ), explode( ' ', get_bloginfo( 'description' ) ) );
338
- $pages[] = home_url( '?s=' . $words[ mt_rand( 0, count( $words ) - 1 ) ] );
339
-
340
- // Get 4 random tags
341
- add_filter( 'get_terms_orderby', array( $this, 'get_terms_orderby' ) );
342
- $terms = get_terms( 'post_tag', 'number=4' );
343
- foreach ( (array) $terms as $term ) {
344
- $pages[] = get_term_link( $term );
345
- }
346
-
347
- // Get 4 random categories
348
- $cats = get_terms( 'category', 'number=4');
349
- foreach ( (array) $cats as $cat ) {
350
- $pages[] = get_term_link( $cat );
351
- }
352
- remove_filter( 'get_terms_orderby', array( $this, 'get_terms_orderby' ) );
353
-
354
- // Get the latest 4 posts
355
- $tmp = preg_split( '/\s+/', wp_get_archives( 'type=postbypost&limit=4&echo=0' ) );
356
- if ( !empty( $tmp ) ) {
357
- foreach ( $tmp as $page ) {
358
- if ( preg_match( "/href='([^']+)'/", $page, $matches ) ) {
359
- $pages[] = $matches[1];
360
- }
361
- }
362
- }
363
-
364
- // Fix SSL
365
- if ( true === force_ssl_admin() ) {
366
- foreach ( $pages as $k => $v ) {
367
- $pages[$k] = str_replace( 'http://', 'https://', $v );
368
- }
369
- }
370
-
371
- // Done
372
- return $pages;
373
- }
374
-
375
- /**************************************************************/
376
- /** AJAX FUNCTIONS **/
377
- /**************************************************************/
378
-
379
- /**
380
- * Start scan
381
- * @return void
382
- */
383
- public function ajax_start_scan() {
384
-
385
- // Check nonce
386
- if ( !wp_verify_nonce( $_POST ['p3_nonce'], 'p3_ajax_start_scan' ) ) {
387
- wp_die( 'Invalid nonce' );
388
- }
389
-
390
- // Sanitize the file name
391
- $filename = sanitize_file_name( basename( $_POST['p3_scan_name'] ) );
392
-
393
- // Add the entry ( multisite installs can run more than one concurrent profile )
394
- $opts = array(
395
- 'ip' => stripslashes( $_POST['p3_ip'] ),
396
- 'disable_opcode_cache' => ( 'true' == $_POST['p3_disable_opcode_cache'] ),
397
- 'name' => $filename,
398
- );
399
-
400
- update_option( 'p3-profiler_profiling_enabled', $opts );
401
-
402
- // Kick start the profile file
403
- if ( !file_exists( P3_PROFILES_PATH . "/$filename.json" ) ) {
404
- $flag = file_put_contents( P3_PROFILES_PATH . "/$filename.json", '' );
405
- } else {
406
- $flag = true;
407
- }
408
-
409
- // Check if either operation failed
410
- if ( false === $flag ) {
411
- wp_die( 0 );
412
- } else {
413
- echo 1;
414
- die();
415
- }
416
- }
417
-
418
- /**
419
- * Stop scan
420
- * @return void
421
- */
422
- public function ajax_stop_scan() {
423
-
424
- // Check nonce
425
- if ( !wp_verify_nonce( $_POST ['p3_nonce'], 'p3_ajax_stop_scan' ) ) {
426
- wp_die( 'Invalid nonce' );
427
- }
428
-
429
- // Turn off scanning
430
- $opts = get_option( 'p3-profiler_profiling_enabled' );
431
- update_option( 'p3-profiler_profiling_enabled', false );
432
-
433
- // Tell the user what happened
434
- $this->add_notice( 'Turned off performance scanning.' );
435
-
436
- // Return the last filename
437
- if ( !empty( $opts ) && is_array( $opts ) && array_key_exists( 'name', $opts ) ) {
438
- echo $opts['name'] . '.json';
439
- die();
440
- } else {
441
- wp_die( 0 );
442
- }
443
- }
444
-
445
- /**
446
- * Save advanced settings
447
- * @return void
448
- */
449
- public function ajax_save_settings() {
450
-
451
- // Check nonce
452
- if ( !wp_verify_nonce( $_POST ['p3_nonce'], 'p3_save_settings' ) ) {
453
- wp_die( 'Invalid nonce' );
454
- }
455
-
456
- // Save the new options
457
- update_option( 'p3-profiler_disable_opcode_cache', 'true' == $_POST['p3_disable_opcode_cache'] );
458
- update_option( 'p3-profiler_cache_buster', 'true' == $_POST['p3_cache_buster'] );
459
- update_option( 'p3-profiler_use_current_ip', 'true' == $_POST['p3_use_current_ip'] );
460
- update_option( 'p3-profiler_ip_address', $_POST['p3_ip_address'] );
461
- update_option( 'p3-profiler_debug', 'true' == $_POST['p3_debug'] );
462
-
463
- // Clear the debug log if it's full
464
- if ( 'true' === $_POST['p3_debug'] ) {
465
- $log = get_option( 'p3-profiler_debug_log' );
466
- if ( is_array( $log ) && count( $log ) >= 100 ) {
467
- update_option( 'p3-profiler_debug_log', array() );
468
- }
469
- }
470
-
471
- die( '1' );
472
- }
473
-
474
-
475
- /**************************************************************/
476
- /** EMAIL RESULTS **/
477
- /**************************************************************/
478
-
479
- /**
480
- * Send results ( presumably to admin or support )
481
- * @return void
482
- */
483
- public function ajax_send_results() {
484
-
485
- // Check nonce
486
- if ( !wp_verify_nonce( $_POST ['p3_nonce'], 'p3_ajax_send_results' ) ) {
487
- wp_die( 'Invalid nonce' );
488
- }
489
-
490
- // Check fields
491
- $to = sanitize_email( $_POST['p3_to'] );
492
- $from = sanitize_email( $_POST['p3_from'] );
493
- $subject = trim( $_POST['p3_subject'] );
494
- $message = strip_tags( $_POST['p3_message'] );
495
- $results = strip_tags( $_POST['p3_results'] );
496
-
497
- // Append the results to the message ( if a messge was specified )
498
- if ( empty( $message ) ) {
499
- $message = stripslashes( $results );
500
- } else {
501
- $message = stripslashes( $message . "\n\n" .$results );
502
- }
503
-
504
- // Check for errors and send message
505
- if ( !is_email( $to ) || !is_email( $from ) ) {
506
- echo '0|Invalid e-mail';
507
- } elseif ( empty( $subject ) ) {
508
- echo '0|Invalid subject';
509
- } elseif ( false === wp_mail( $to, $subject, $message, "From: $from" ) ) {
510
- echo '0|<a href="http://codex.wordpress.org/Function_Reference/wp_mail" target="_blank">wp_mail()</a> function returned false';
511
- } else {
512
- echo '1';
513
- }
514
- die();
515
- }
516
-
517
-
518
- /**************************************************************/
519
- /** CURRENT PAGE **/
520
- /**************************************************************/
521
-
522
- /**
523
- * Show the settings page.
524
- * This is where the user can start/stop the scan
525
- */
526
- public function scan_settings_page() {
527
- include_once P3_PATH . '/templates/template.php';
528
- }
529
-
530
-
531
- /**************************************************************/
532
- /** HELP PAGE **/
533
- /**************************************************************/
534
-
535
- /**
536
- * Show the help page.
537
- */
538
- public function show_help() {
539
- include_once P3_PATH . '/templates/template.php';
540
- }
541
-
542
-
543
- /**************************************************************/
544
- /** DEBUG LOG FUNCTIONS **/
545
- /**************************************************************/
546
-
547
- /**
548
- * Clear the debug log
549
- */
550
- public function clear_debug_log() {
551
- if ( !check_admin_referer( 'p3-clear-debug-log' ) ) {
552
- wp_die( 'Invalid access' );
553
- }
554
- update_option( 'p3-profiler_debug_log', array() );
555
- wp_redirect( add_query_arg( array( 'p3_action' => 'help' ) ) );
556
- }
557
-
558
- /**
559
- * Download the debug log
560
- */
561
- public function download_debug_log() {
562
- if ( !check_admin_referer( 'p3-download-debug-log' ) ) {
563
- wp_die( 'Invalid access' );
564
- }
565
- $log = get_option( 'p3-profiler_debug_log' );
566
- if ( empty( $log ) ) {
567
- $log = array();
568
- }
569
- header('Pragma: public');
570
- header('Expires: 0');
571
- header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
572
- header('Content-Type: application/force-download');
573
- header('Content-Type: application/octet-stream');
574
- header('Content-Type: application/download');
575
- header('Content-Disposition: attachment; filename="p3debug.csv";');
576
- header('Content-Transfer-Encoding: binary');
577
-
578
- // File header
579
- echo '"Profiling Enabled","Recording IP","Scan Name","Recording","Disable Optimizers","URL","Visitor IP","Time","PID"' . "\n";
580
-
581
- foreach ( (array) $log as $entry ) {
582
- printf('"%s","%s","%s","%s","%s","%s","%s","%s","%d"' . "\n",
583
- $entry['profiling_enabled'] ? 'true' : 'false',
584
- $entry['recording_ip'],
585
- $entry['scan_name'],
586
- $entry['recording'] ? 'true' : 'false',
587
- $entry['disable_optimizers'] ? 'true' : 'false',
588
- $entry['url'],
589
- $entry['visitor_ip'],
590
- date( 'Y-m-d H:i:s', $entry['time'] ),
591
- $entry['pid']
592
- );
593
- }
594
-
595
- // Done
596
- die();
597
- }
598
-
599
-
600
- /**************************************************************/
601
- /** HISTORY PAGE **/
602
- /**************************************************************/
603
-
604
- /**
605
- * View the results of a scan
606
- * @uses $_REQUEST['name']
607
- * @return void
608
- */
609
- public function view_scan() {
610
- include_once P3_PATH . '/templates/template.php';
611
- }
612
-
613
- /**
614
- * Show a list of available scans.
615
- * Uses WP List table to handle UI and sorting.
616
- * Uses P3_Profile_Table to handle deleting
617
- * @uses WP_List_Table
618
- * @uses jquery
619
- * @uses P3_Profile_Table
620
- * @return void
621
- */
622
- public function list_scans() {
623
- include_once P3_PATH . '/templates/template.php';
624
- }
625
-
626
- /**
627
- * Get the latest performance scan
628
- * @return string|false
629
- */
630
- public function get_latest_profile() {
631
-
632
- // Open the directory
633
- $dir = opendir( P3_PROFILES_PATH );
634
- if ( false === $dir ) {
635
- wp_die( 'Cannot read profiles directory' );
636
- }
637
-
638
- // Loop through the files, get the path and the last modified time
639
- $files = array();
640
- while ( false !== ( $file = readdir( $dir ) ) ) {
641
- if ( '.json' == substr( $file, -5 ) && filesize( P3_PROFILES_PATH . '/' . $file ) > 0 ) {
642
- $files[filemtime( P3_PROFILES_PATH . "/$file" )] = P3_PROFILES_PATH . "/$file";
643
- }
644
- }
645
- closedir( $dir );
646
-
647
- // If there are no files, return false
648
- if ( empty( $files ) ) {
649
- return false;
650
- }
651
-
652
- // Sort the files by the last modified time, return the latest
653
- ksort( $files );
654
- return array_pop( $files );
655
- }
656
-
657
- /**
658
- * Add a notices
659
- * @uses transients
660
- * @param string $notice
661
- * @param bool $error Default false. If true, this is a red error. If false, this is a yellow notice.
662
- * @return void
663
- */
664
- public function add_notice( $notice, $error = false ) {
665
-
666
- // Get any notices on the stack
667
- $notices = get_transient( 'p3_notices' );
668
- if ( empty( $notices ) ) {
669
- $notices = array();
670
- }
671
-
672
- // Add the notice to the stack
673
- $notices[] = array(
674
- 'msg' => $notice,
675
- 'error' => $error,
676
- );
677
-
678
- // Save the stack
679
- set_transient( 'p3_notices', $notices );
680
- }
681
-
682
- /**
683
- * Display notices
684
- * @uses transients
685
- * @return voide
686
- */
687
- public function show_notices() {
688
- $notices = get_transient( 'p3_notices' );
689
- if ( !empty( $notices ) ) {
690
- $notices = array_unique( $notices );
691
- foreach ( $notices as $notice ) {
692
- echo '<div class="' . ( ( $notice['error'] ) ? 'error' : 'updated' ) . '"><p>' . htmlentities( $notice['msg'] ) . '</p></div>';
693
- }
694
- }
695
- set_transient( 'p3_notices', array() );
696
- if ( false !== $this->scan_enabled() ) {
697
- echo '<div class="updated"><p>Performance scanning is enabled.</p></div>';
698
- }
699
- }
700
-
701
- /**
702
- * Activation hook
703
- * Install the profiler loader in the most optimal place
704
- * @return void
705
- */
706
- public function activate() {
707
- global $wp_version;
708
-
709
- // Version check, only 3.3+
710
- if ( ! version_compare( $wp_version, '3.3', '>=') ) {
711
- if ( function_exists('deactivate_plugins') )
712
- deactivate_plugins(__FILE__);
713
- die( '<strong>P3</strong> requires WordPress 3.3 or later' );
714
- }
715
-
716
- // mu-plugins doesn't exist
717
- if ( !file_exists( WPMU_PLUGIN_DIR ) && is_writable( dirname( WPMU_PLUGIN_DIR ) ) ) {
718
- wp_mkdir_p( WPMU_PLUGIN_DIR );
719
- }
720
- if ( file_exists( WPMU_PLUGIN_DIR ) && is_writable( WPMU_PLUGIN_DIR ) ) {
721
- file_put_contents(
722
- WPMU_PLUGIN_DIR . '/p3-profiler.php',
723
- '<' . "?php // Start profiling\nrequire_once( realpath( dirname( __FILE__ ) ) . '/../plugins/p3-profiler/start-profile.php' ); ?" . '>'
724
- );
725
- }
726
- }
727
-
728
- /**
729
- * Make the profiles folder
730
- * @param string $path
731
- * @return void
732
- */
733
- private function _make_profiles_folder( $path ) {
734
- wp_mkdir_p( $path );
735
- if ( !file_exists( "$path/.htaccess" ) ) {
736
- file_put_contents( $path . DIRECTORY_SEPARATOR . '.htaccess', "Deny from all\n" );
737
- }
738
- if ( !file_exists( "$path/index.php" ) ) {
739
- file_put_contents( $path. DIRECTORY_SEPARATOR . 'index.php', '<' . "?php header( 'Status: 404 Not found' ); ?" . ">\nNot found" );
740
- }
741
- }
742
-
743
- /**
744
- * Delete the profiles folder
745
- * @param string $path
746
- * @return void
747
- */
748
- private function _delete_profiles_folder( $path ) {
749
- if ( !file_exists( $path ) )
750
- return;
751
- $dir = opendir( $path );
752
- while ( ( $file = readdir( $dir ) ) !== false ) {
753
- if ( $file != '.' && $file != '..' ) {
754
- unlink( $path . DIRECTORY_SEPARATOR . $file );
755
- }
756
- }
757
- closedir( $dir );
758
- rmdir( $path );
759
- }
760
-
761
- /**
762
- * Deactivation hook
763
- * Remove the profiler loader
764
- * @return void
765
- */
766
- public function deactivate() {
767
- global $p3_profiler;
768
-
769
- // Unhook the profiler
770
- update_option( 'p3-profiler_debug', false );
771
- update_option( 'p3-profiler_debug_log', array() );
772
- remove_action( 'shutdown', array( $p3_profiler, 'shutdown_handler' ) );
773
-
774
- // Remove mu-plugin
775
- if ( file_exists( WPMU_PLUGIN_DIR . '/p3-profiler.php' ) ) {
776
- if ( is_writable( WPMU_PLUGIN_DIR . '/p3-profiler.php' ) ) {
777
- // Some servers give write permission, but not delete permission. Empty the file out, first, then try to delete it.
778
- file_put_contents( WPMU_PLUGIN_DIR . '/p3-profiler.php', '' );
779
- unlink( WPMU_PLUGIN_DIR . '/p3-profiler.php' );
780
- }
781
- }
782
- }
783
-
784
- /**
785
- * Uninstall hook
786
- * Remove profile data
787
- * @return void
788
- */
789
- public static function uninstall() {
790
- global $p3_profiler;
791
-
792
- // Unhook the profiler
793
- update_option( 'p3-profiler_debug', false );
794
- update_option( 'p3-profiler_debug_log', array() );
795
- remove_action( 'shutdown', array( $p3_profiler, 'shutdown_handler' ) );
796
-
797
- // This is a static function so it needs an instance
798
- // Since I'm myself, I can call my own private methods
799
- $class = __CLASS__;
800
- $me = new $class();
801
-
802
- // Delete the profiles folder
803
- if ( function_exists( 'is_multisite' ) && is_multisite() ) {
804
- $blogs = get_blog_list( 0, 'all' );
805
- foreach ( $blogs as $blog ) {
806
- switch_to_blog( $blog['blog_id'] );
807
- $uploads_dir = wp_upload_dir();
808
- $folder = $uploads_dir['basedir'] . DIRECTORY_SEPARATOR . 'profiles' . DIRECTORY_SEPARATOR;
809
- $me->_delete_profiles_folder( $folder );
810
-
811
- // Remove any options
812
- delete_option( 'p3-profiler_disable_opcode_cache' );
813
- delete_option( 'p3-profiler_use_current_ip' );
814
- delete_option( 'p3-profiler_ip_address' );
815
- delete_option( 'p3-profiler_version' );
816
- delete_option( 'p3-profiler_cache_buster' );
817
- delete_option( 'p3-profiler_profiling_enabled' );
818
- delete_option( 'p3-profiler_debug' );
819
- delete_option( 'p3-profiler_debug_log' );
820
- }
821
- restore_current_blog();
822
- } else {
823
- $me->_delete_profiles_folder( P3_PROFILES_PATH );
824
-
825
- // Remove any options
826
- delete_option( 'p3-profiler_disable_opcode_cache' );
827
- delete_option( 'p3-profiler_use_current_ip' );
828
- delete_option( 'p3-profiler_ip_address' );
829
- delete_option( 'p3-profiler_version' );
830
- delete_option( 'p3-profiler_cache_buster' );
831
- delete_option( 'p3-profiler_profiling_enabled' );
832
- delete_option( 'p3-profiler_debug' );
833
- delete_option( 'p3-profiler_debug_log' );
834
- }
835
- }
836
-
837
- /**
838
- * Check to see if a scan is enabled
839
- * @return array|false
840
- */
841
- public function scan_enabled() {
842
- $opts = get_option( 'p3-profiler_profiling_enabled' );
843
- if ( !empty( $opts ) ) {
844
- return $opts;
845
- }
846
- return false;
847
- }
848
-
849
- /**
850
- * Convert a filesize ( in bytes ) to a human readable filesize
851
- * @param int $size
852
- * @return string
853
- */
854
- public function readable_size( $size ) {
855
- $units = array( 'B', 'KB', 'MB', 'GB', 'TB' );
856
- $size = max( $size, 0 );
857
- $pow = floor( ( $size ? log( $size ) : 0 ) / log( 1024 ) );
858
- $pow = min( $pow, count( $units ) - 1 );
859
- $size /= pow( 1024, $pow );
860
- return round( $size, 0 ) . ' ' . $units[$pow];
861
- }
862
-
863
- /**
864
- * Actions to take when a multisite blog is removed
865
- * @return void
866
- */
867
- public function delete_blog() {
868
- $uploads_dir = wp_upload_dir();
869
- $folder = $uploads_dir['basedir'] . DIRECTORY_SEPARATOR . 'profiles' . DIRECTORY_SEPARATOR;
870
- $this->_delete_profiles_folder( $folder );
871
- delete_option( 'p3-profiler_disable_opcode_cache' );
872
- delete_option( 'p3-profiler_use_current_ip' );
873
- delete_option( 'p3-profiler_ip_address' );
874
- delete_option( 'p3-profiler_version' );
875
- delete_option( 'p3-profiler_cache_buster' );
876
- delete_option( 'p3-profiler_profiling_enabled' );
877
- delete_option( 'p3-profiler_debug' );
878
- delete_option( 'p3-profiler_debug_log' );
879
- }
880
-
881
- /**
882
- * Upgrade
883
- * Check options, perform any necessary data conversions
884
- * @return void
885
- */
886
- public function upgrade() {
887
-
888
- // Only for our page
889
- if ( !isset( $_REQUEST['page'] ) || basename( __FILE__ ) != $_REQUEST['page'] ) {
890
- return;
891
- }
892
-
893
- // Get the current version
894
- $version = get_option( 'p3-profiler_version' );
895
-
896
- // Upgrading from < 1.1.0
897
- if ( empty( $version ) || version_compare( $version, '1.1.0' ) < 0 ) {
898
- update_option( 'p3-profiler_disable_opcode_cache', true );
899
- update_option( 'p3-profiler_use_current_ip', true );
900
- update_option( 'p3-profiler_ip_address', '' );
901
- update_option( 'p3-profiler_version', '1.1.0' );
902
- }
903
-
904
- // Upgrading from < 1.1.2
905
- if ( empty( $version) || version_compare( $version, '1.1.2' ) < 0 ) {
906
- update_option( 'p3-profiler_cache_buster', true );
907
- update_option( 'p3-profiler_version', '1.1.2' );
908
- }
909
-
910
- // Upgrading from < 1.2.0
911
- if ( empty( $version) || version_compare( $version, '1.2.0' ) < 0 ) {
912
-
913
- // Set profiling option
914
- update_option( 'p3-profiler_profiling_enabled', false );
915
- update_option( 'p3-profiler_version', '1.2.0' );
916
- update_option( 'p3-profiler_debug', false );
917
- update_option( 'p3-profiler_debug_log', array() );
918
-
919
- // Remove any .htaccess modifications
920
- $file = ABSPATH . '/.htaccess';
921
- if ( file_exists( $file ) && array() !== extract_from_markers( $file, 'p3-profiler' ) ) {
922
- insert_with_markers( $file, 'p3-profiler', array( '# removed during 1.2.0 upgrade' ) );
923
- }
924
-
925
- // Remove .profiling_enabled if it's still present
926
- if ( file_exists( P3_PATH . '/.profiling_enabled' ) ) {
927
- @unlink( P3_PATH . '/.profiling_enabled' );
928
- }
929
- }
930
-
931
- // Ensure the profiles folder is there
932
- $uploads_dir = wp_upload_dir();
933
- $folder = $uploads_dir['basedir'] . DIRECTORY_SEPARATOR . 'profiles';
934
- $this->_make_profiles_folder( $folder );
935
  }
936
  }
4
  Plugin URI: http://support.godaddy.com/godaddy/wordpress-p3-plugin/
5
  Description: See which plugins are slowing down your site. Create a profile of your WordPress site's plugins' performance by measuring their impact on your site's load time.
6
  Author: GoDaddy.com
7
+ Version: 1.3.0
8
  Author URI: http://www.godaddy.com/
9
  */
10
 
19
  // Shortcut for knowing our path
20
  define( 'P3_PATH', realpath( dirname( __FILE__ ) ) );
21
 
22
+ // Plugin slug
23
+ define( 'P3_PLUGIN_SLUG', 'p3-profiler' );
 
24
 
25
+ /**************************************************************************/
26
+ /** AUTOLOADING **/
27
+ /**************************************************************************/
28
+
29
+ // Autoload classes, if possible
30
+ if ( function_exists( 'spl_autoload_register') ) {
31
+ spl_autoload_register( 'p3_profiler_autoload' );
32
+ } else {
33
+ require_once( P3_PATH . '/classes/class.p3-profiler-reader.php' );
34
+ require_once( P3_PATH . '/classes/class.p3-profiler-table-sorter.php' );
35
+ require_once( P3_PATH . '/classes/class.p3-profiler-table.php' );
36
+ require_once( P3_PATH . '/classes/class.p3-profiler-plugin.php' );
37
+ require_once( P3_PATH . '/classes/class.p3-profiler-plugin-admin.php' );
38
+ require_once( P3_PATH . '/exceptions/class.p3-profiler-no-data-exception.php' );
39
+ }
40
 
41
  /**************************************************************************/
42
  /** START PROFILING **/
45
  // Start profiling. If it's already been started, this line won't do anything
46
  require_once P3_PATH . '/start-profile.php';
47
 
 
48
  /**************************************************************************/
49
  /** PLUGIN HOOKS **/
50
  /**************************************************************************/
51
 
52
+ // Ajax actions
53
+ if ( is_admin() && 'admin-ajax.php' == end( explode( '/', $_SERVER['PHP_SELF'] ) ) ) {
54
+
55
+ add_action( 'wp_ajax_p3_start_scan', array( 'P3_Profiler_Plugin_Admin', 'ajax_start_scan' ) );
56
+ add_action( 'wp_ajax_p3_stop_scan', array( 'P3_Profiler_Plugin_Admin', 'ajax_stop_scan' ) );
57
+ add_action( 'wp_ajax_p3_send_results', array( 'P3_Profiler_Plugin_Admin', 'ajax_send_results' ) );
58
+ add_action( 'wp_ajax_p3_save_settings', array( 'P3_Profiler_Plugin_Admin', 'ajax_save_settings' ) );
59
 
60
  // Admin hooks
61
+ } elseif ( is_admin() ) {
62
+
63
  // Show the 'Profiler' option under the 'Plugins' menu
64
+ add_action( 'admin_menu', array( 'P3_Profiler_Plugin', 'tools_menu' ) );
65
 
66
+ // Show the 'Profile now' link on the plugins table
67
+ add_action( 'plugin_action_links', array( 'P3_Profiler_Plugin', 'add_settings_link'), 10, 2 );
68
 
69
+ if ( isset( $_REQUEST['page'] ) && P3_PLUGIN_SLUG == $_REQUEST['page'] ) {
 
70
 
71
+ // Localization
72
+ add_action( 'admin_init', array( 'P3_Profiler_Plugin', 'load_language' ) );
 
 
 
73
 
74
+ // Pre-processing of actions
75
+ add_action( 'admin_init', array( 'P3_Profiler_Plugin_Admin', 'init' ) );
76
 
77
+ // Show any notices
78
+ add_action( 'admin_notices', array( 'P3_Profiler_Plugin_Admin', 'show_notices' ) );
79
+ }
80
 
81
  // Remove the admin bar when in profiling mode
82
+ } elseif ( defined( 'WPP_PROFILING_STARTED' ) || isset( $_GET['P3_HIDE_ADMIN_BAR'] ) ) {
83
+ add_action( 'plugins_loaded', array( 'P3_Profiler_Plugin_Admin', 'remove_admin_bar' ) );
84
  }
85
 
86
  // Install / uninstall hooks
87
+ register_activation_hook( P3_PATH . DIRECTORY_SEPARATOR . 'p3-profiler.php', array( 'P3_Profiler_Plugin', 'activate' ) );
88
+ register_deactivation_hook( P3_PATH . DIRECTORY_SEPARATOR . 'p3-profiler.php', array( 'P3_Profiler_Plugin', 'deactivate' ) );
 
89
  if ( function_exists( 'is_multisite' ) && is_multisite() ) {
90
+ add_action( 'wpmu_delete_blog', array( 'P3_Profiler_Plugin', 'delete_blog' ) );
91
  }
92
 
93
  /**
94
+ * Autoloader ... very little logic needed
95
+ * @param string $className
96
+ * @return
 
 
97
  */
98
+ function p3_profiler_autoload( $className ) {
99
+ switch ( $className ) {
100
+ case 'P3_Profiler_Reader' :
101
+ require_once( P3_PATH . '/classes/class.p3-profiler-reader.php' );
102
+ break;
103
+ case 'P3_Profiler_Table_Sorter' :
104
+ require_once( P3_PATH . '/classes/class.p3-profiler-table-sorter.php' );
105
+ break;
106
+ case 'P3_Profiler_Table' :
107
+ require_once( P3_PATH . '/classes/class.p3-profiler-table.php' );
108
+ break;
109
+ case 'P3_Profiler_Plugin' :
110
+ require_once( P3_PATH . '/classes/class.p3-profiler-plugin.php' );
111
+ break;
112
+ case 'P3_Profiler_Plugin_Admin' :
113
+ require_once( P3_PATH . '/classes/class.p3-profiler-plugin-admin.php' );
114
+ break;
115
+ case 'P3_Profiler_No_Data_Exception' :
116
+ require_once( P3_PATH . '/exceptions/class.p3-profiler-no-data-exception.php' );
117
+ break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  }
119
  }
p3-profiler.pot ADDED
@@ -0,0 +1,1494 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2012 P3 (Plugin Performance Profiler)
2
+ # This file is distributed under the same license as the P3 (Plugin Performance Profiler) package.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: P3 (Plugin Performance Profiler) 1.3.0\n"
6
+ "Report-Msgid-Bugs-To: http://wordpress.org/tag/p3-profiler\n"
7
+ "POT-Creation-Date: 2012-05-26 00:32:52+00:00\n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "PO-Revision-Date: 2012-MO-DA HO:MI+ZONE\n"
12
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
+ "Language-Team: LANGUAGE <LL@li.org>\n"
14
+
15
+ #: classes/class.p3-profiler-plugin-admin.php:74
16
+ #: classes/class.p3-profiler-plugin-admin.php:75
17
+ #: classes/class.p3-profiler-plugin.php:16
18
+ #: classes/class.p3-profiler-plugin.php:17
19
+ msgid "P3 Plugin Profiler"
20
+ msgstr ""
21
+
22
+ #: classes/class.p3-profiler-plugin-admin.php:135
23
+ msgid "Scan does not exist"
24
+ msgstr ""
25
+
26
+ #: classes/class.p3-profiler-plugin-admin.php:161
27
+ msgid ""
28
+ "No visits recorded during this profiling session. Check the <a href=\"%s"
29
+ "\">help</a> page for more information"
30
+ msgstr ""
31
+
32
+ #: classes/class.p3-profiler-plugin-admin.php:169
33
+ msgid "Error reading scan"
34
+ msgstr ""
35
+
36
+ #: classes/class.p3-profiler-plugin-admin.php:177
37
+ msgid "Click \"Start Scan\" to run a performance scan of your website."
38
+ msgstr ""
39
+
40
+ #: classes/class.p3-profiler-plugin-admin.php:272
41
+ #: classes/class.p3-profiler-plugin-admin.php:310
42
+ #: classes/class.p3-profiler-plugin-admin.php:339
43
+ #: classes/class.p3-profiler-plugin-admin.php:374
44
+ #: classes/class.p3-profiler-plugin-admin.php:419
45
+ #: classes/class.p3-profiler-plugin-admin.php:430
46
+ #: classes/class.p3-profiler-table.php:210
47
+ msgid "You do not have sufficient permissions to access this page."
48
+ msgstr ""
49
+
50
+ #: classes/class.p3-profiler-plugin-admin.php:321
51
+ msgid "Turned off performance scanning."
52
+ msgstr ""
53
+
54
+ #: classes/class.p3-profiler-plugin-admin.php:394
55
+ #: classes/class.p3-profiler-plugin-admin.php:397
56
+ msgid "Invalid subject"
57
+ msgstr ""
58
+
59
+ #: classes/class.p3-profiler-plugin-admin.php:401
60
+ msgid "<a href=\"%s\" target=\"_blank\">wp_mail()</a> function returned false"
61
+ msgstr ""
62
+
63
+ #: classes/class.p3-profiler-plugin-admin.php:447 templates/help.php:366
64
+ #: templates/help.php:406
65
+ msgid "Profiling Enabled"
66
+ msgstr ""
67
+
68
+ #: classes/class.p3-profiler-plugin-admin.php:448 templates/help.php:367
69
+ #: templates/help.php:407
70
+ msgid "Recording IP"
71
+ msgstr ""
72
+
73
+ #: classes/class.p3-profiler-plugin-admin.php:449 templates/callouts.php:257
74
+ #: templates/help.php:368 templates/help.php:408
75
+ msgid "Scan Name"
76
+ msgstr ""
77
+
78
+ #: classes/class.p3-profiler-plugin-admin.php:450 templates/help.php:369
79
+ #: templates/help.php:409
80
+ msgid "Recording"
81
+ msgstr ""
82
+
83
+ #: classes/class.p3-profiler-plugin-admin.php:451 templates/help.php:370
84
+ #: templates/help.php:410
85
+ msgid "Disable Optimizers"
86
+ msgstr ""
87
+
88
+ #: classes/class.p3-profiler-plugin-admin.php:452 templates/help.php:371
89
+ #: templates/help.php:411
90
+ msgid "URL"
91
+ msgstr ""
92
+
93
+ #: classes/class.p3-profiler-plugin-admin.php:453 templates/help.php:372
94
+ #: templates/help.php:412
95
+ msgid "Visitor IP"
96
+ msgstr ""
97
+
98
+ #: classes/class.p3-profiler-plugin-admin.php:454 templates/help.php:373
99
+ #: templates/help.php:413
100
+ msgid "Time"
101
+ msgstr ""
102
+
103
+ #: classes/class.p3-profiler-plugin-admin.php:455 templates/help.php:374
104
+ #: templates/help.php:414
105
+ msgctxt "Abbreviation for process id"
106
+ msgid "PID"
107
+ msgstr ""
108
+
109
+ #: classes/class.p3-profiler-plugin-admin.php:490
110
+ msgid "Cannot read profiles directory"
111
+ msgstr ""
112
+
113
+ #: classes/class.p3-profiler-plugin-admin.php:552
114
+ msgid "Performance scanning is enabled."
115
+ msgstr ""
116
+
117
+ #: classes/class.p3-profiler-plugin-admin.php:606
118
+ msgctxt "Abbreviation for bytes"
119
+ msgid "B"
120
+ msgstr ""
121
+
122
+ #: classes/class.p3-profiler-plugin-admin.php:607
123
+ msgctxt "Abbreviation for kilobytes"
124
+ msgid "KB"
125
+ msgstr ""
126
+
127
+ #: classes/class.p3-profiler-plugin-admin.php:608 templates/view-scan.php:959
128
+ msgctxt "Abbreviation for megabytes"
129
+ msgid "MB"
130
+ msgstr ""
131
+
132
+ #: classes/class.p3-profiler-plugin-admin.php:609
133
+ msgctxt "Abbreviation for gigabytes"
134
+ msgid "GB"
135
+ msgstr ""
136
+
137
+ #: classes/class.p3-profiler-plugin-admin.php:610
138
+ msgctxt "Abbreviation for terabytes"
139
+ msgid "TB"
140
+ msgstr ""
141
+
142
+ #: classes/class.p3-profiler-reader.php:155
143
+ msgid "Cannot open file: "
144
+ msgstr ""
145
+
146
+ #: classes/class.p3-profiler-reader.php:167
147
+ msgid "Cannot parse file: "
148
+ msgstr ""
149
+
150
+ #: classes/class.p3-profiler-reader.php:191
151
+ msgid "No visits recorded during this profiling session."
152
+ msgstr ""
153
+
154
+ #: classes/class.p3-profiler-table.php:25
155
+ #: classes/class.p3-profiler-table.php:26
156
+ msgid "scan"
157
+ msgid_plural "scans"
158
+ msgstr[0] ""
159
+ msgstr[1] ""
160
+
161
+ #: classes/class.p3-profiler-table.php:106
162
+ #: classes/class.p3-profiler-table.php:183
163
+ #: classes/class.p3-profiler-table.php:198
164
+ msgid "Delete"
165
+ msgstr ""
166
+
167
+ #: classes/class.p3-profiler-table.php:138
168
+ msgid "Name"
169
+ msgstr ""
170
+
171
+ #: classes/class.p3-profiler-table.php:139
172
+ msgid "Date"
173
+ msgstr ""
174
+
175
+ #: classes/class.p3-profiler-table.php:140
176
+ msgid "Visits"
177
+ msgstr ""
178
+
179
+ #: classes/class.p3-profiler-table.php:141
180
+ msgid "Size"
181
+ msgstr ""
182
+
183
+ #: classes/class.p3-profiler-table.php:174
184
+ #: classes/class.p3-profiler-table.php:177
185
+ msgid "View the results of this scan"
186
+ msgstr ""
187
+
188
+ #: classes/class.p3-profiler-table.php:177
189
+ msgid "View"
190
+ msgstr ""
191
+
192
+ #: classes/class.p3-profiler-table.php:180
193
+ msgid "Continue this scan"
194
+ msgstr ""
195
+
196
+ #: classes/class.p3-profiler-table.php:180
197
+ msgid "Continue"
198
+ msgstr ""
199
+
200
+ #: classes/class.p3-profiler-table.php:183
201
+ msgid "Delete this scan"
202
+ msgstr ""
203
+
204
+ #: classes/class.p3-profiler-table.php:215
205
+ msgid "Error removing file: "
206
+ msgstr ""
207
+
208
+ #: classes/class.p3-profiler-table.php:220
209
+ msgid "Deleted %d scan. "
210
+ msgid_plural "Deleted %d scans."
211
+ msgstr[0] ""
212
+ msgstr[1] ""
213
+
214
+ #: classes/class.p3-profiler.php:513
215
+ msgid "A fatal error occurred during profiling: %s in file %s on line %d "
216
+ msgstr ""
217
+
218
+ #: templates/callouts.php:93
219
+ msgid "Scanning is paused."
220
+ msgstr ""
221
+
222
+ #: templates/callouts.php:142
223
+ msgid "Scanning is complete."
224
+ msgstr ""
225
+
226
+ #: templates/callouts.php:148
227
+ msgid "Scanning"
228
+ msgstr ""
229
+
230
+ #: templates/callouts.php:202 templates/callouts.php:489
231
+ msgid "Advanced Settings"
232
+ msgstr ""
233
+
234
+ #: templates/callouts.php:206 templates/view-scan.php:55
235
+ msgid "OK"
236
+ msgstr ""
237
+
238
+ #: templates/callouts.php:226 templates/callouts.php:627
239
+ #: templates/view-scan.php:121
240
+ msgid "Cancel"
241
+ msgstr ""
242
+
243
+ #: templates/callouts.php:244
244
+ msgid "Performance Scan"
245
+ msgstr ""
246
+
247
+ #: templates/callouts.php:479 templates/callouts.php:662
248
+ msgid "Stop Scan"
249
+ msgstr ""
250
+
251
+ #: templates/callouts.php:486
252
+ msgid "My IP:"
253
+ msgstr ""
254
+
255
+ #: templates/callouts.php:488
256
+ msgid "Start Scan"
257
+ msgstr ""
258
+
259
+ #: templates/callouts.php:497
260
+ msgid ""
261
+ "Total number of active plugins, including must-use plugins, on your site."
262
+ msgstr ""
263
+
264
+ #: templates/callouts.php:499
265
+ msgid "Total Plugins:"
266
+ msgstr ""
267
+
268
+ #: templates/callouts.php:512
269
+ msgid "currently active"
270
+ msgstr ""
271
+
272
+ #: templates/callouts.php:519
273
+ msgid ""
274
+ "Total number of seconds dedicated to plugin code per visit on your site."
275
+ msgstr ""
276
+
277
+ #: templates/callouts.php:520 templates/callouts.php:538
278
+ #: templates/callouts.php:556
279
+ msgid "From"
280
+ msgstr ""
281
+
282
+ #: templates/callouts.php:522 templates/help.php:483
283
+ msgid "Plugin Load Time"
284
+ msgstr ""
285
+
286
+ #: templates/callouts.php:525 templates/callouts.php:543
287
+ #: templates/callouts.php:561
288
+ msgid "n/a"
289
+ msgstr ""
290
+
291
+ #: templates/callouts.php:530
292
+ msgid "sec. per visit"
293
+ msgstr ""
294
+
295
+ #: templates/callouts.php:537
296
+ msgid "Percent of load time on your site dedicated to plugin code"
297
+ msgstr ""
298
+
299
+ #: templates/callouts.php:540
300
+ msgid "Plugin Impact"
301
+ msgstr ""
302
+
303
+ #: templates/callouts.php:548
304
+ msgid "of page load time"
305
+ msgstr ""
306
+
307
+ #: templates/callouts.php:555
308
+ msgid "Total number of database queries per visit"
309
+ msgstr ""
310
+
311
+ #: templates/callouts.php:558 templates/help.php:545
312
+ msgid "MySQL Queries"
313
+ msgstr ""
314
+
315
+ #: templates/callouts.php:566
316
+ msgid "per visit"
317
+ msgstr ""
318
+
319
+ #: templates/callouts.php:577
320
+ msgid "IP address or pattern:"
321
+ msgstr ""
322
+
323
+ #: templates/callouts.php:579
324
+ msgid "Use my IP address"
325
+ msgstr ""
326
+
327
+ #: templates/callouts.php:581
328
+ msgid "Enter IP address or regular expression pattern"
329
+ msgstr ""
330
+
331
+ #: templates/callouts.php:583
332
+ msgid "Example: 1.2.3.4 or ( 1.2.3.4|4.5.6.7 )"
333
+ msgstr ""
334
+
335
+ #: templates/callouts.php:588
336
+ msgid "Attempt to disable opcode optimizers"
337
+ msgstr ""
338
+
339
+ #: templates/callouts.php:588
340
+ msgid "recommended"
341
+ msgstr ""
342
+
343
+ #: templates/callouts.php:590
344
+ msgid ""
345
+ "This can increase accuracy in plugin detection, but decrease accuracy in "
346
+ "timing"
347
+ msgstr ""
348
+
349
+ #: templates/callouts.php:595
350
+ msgid "Attempt to circumvent browser cache"
351
+ msgstr ""
352
+
353
+ #: templates/callouts.php:597
354
+ msgid ""
355
+ "This may help fix a \"No visits recorded\" error message. See the <a href="
356
+ "\"%s\">help</a> page for details."
357
+ msgstr ""
358
+
359
+ #: templates/callouts.php:604
360
+ msgid "Debug mode"
361
+ msgstr ""
362
+
363
+ #: templates/callouts.php:606
364
+ msgid ""
365
+ "This will log the last 100 visits. Check the <a href=\"%s\">help</a> page "
366
+ "to view log messages."
367
+ msgstr ""
368
+
369
+ #: templates/callouts.php:618
370
+ msgid ""
371
+ "The scanner will analyze the speed and resource usage of all active plugins "
372
+ "on your website. It may take several minutes, and this window must remain "
373
+ "open for the scan to finish successfully."
374
+ msgstr ""
375
+
376
+ #: templates/callouts.php:624
377
+ msgid ""
378
+ "Click the links and pages of your site, and the scanner will analyze the "
379
+ "speed and resource usage of all of your active plugins."
380
+ msgstr ""
381
+
382
+ #: templates/callouts.php:631
383
+ msgid "I'm Done"
384
+ msgstr ""
385
+
386
+ #: templates/callouts.php:641 templates/template.php:76
387
+ msgid "Scan name:"
388
+ msgstr ""
389
+
390
+ #: templates/callouts.php:642
391
+ msgid "Enter scan name here"
392
+ msgstr ""
393
+
394
+ #: templates/callouts.php:645
395
+ msgid "Enter the name of a previous scan to continue scanning"
396
+ msgstr ""
397
+
398
+ #: templates/callouts.php:648
399
+ msgid "Auto Scan"
400
+ msgstr ""
401
+
402
+ #: templates/callouts.php:649
403
+ msgid "Manual Scan"
404
+ msgstr ""
405
+
406
+ #: templates/callouts.php:656
407
+ msgid "Scanning ..."
408
+ msgstr ""
409
+
410
+ #: templates/callouts.php:667
411
+ msgid "Resume"
412
+ msgstr ""
413
+
414
+ #: templates/callouts.php:669 templates/callouts.php:675
415
+ msgid "View Results"
416
+ msgstr ""
417
+
418
+ #: templates/help.php:10 templates/help.php:13
419
+ msgid "Hide Glossary"
420
+ msgstr ""
421
+
422
+ #: templates/help.php:11
423
+ msgid "Show Glossary"
424
+ msgstr ""
425
+
426
+ #: templates/help.php:24 templates/help.php:31 templates/help.php:38
427
+ #: templates/help.php:47 templates/help.php:358 templates/help.php:450
428
+ msgid "Hide"
429
+ msgstr ""
430
+
431
+ #: templates/help.php:27 templates/help.php:42
432
+ msgid "Show"
433
+ msgstr ""
434
+
435
+ #: templates/help.php:67
436
+ msgid "Back to top"
437
+ msgstr ""
438
+
439
+ #: templates/help.php:77
440
+ msgid "Contents"
441
+ msgstr ""
442
+
443
+ #: templates/help.php:85
444
+ msgid "What does the P3 plugin do?"
445
+ msgstr ""
446
+
447
+ #: templates/help.php:87
448
+ msgid ""
449
+ "This plugin does just what its name says, it creates a profile of your "
450
+ "WordPress site's plugins' performance by measuring their impact on your "
451
+ "site's load time.\n"
452
+ "<br /><br />\n"
453
+ "Often times, WordPress sites load slowly because of poorly-configured "
454
+ "plugins or because there are so many of them. This plugin can help you "
455
+ "narrow down the cause of your site's slowness."
456
+ msgstr ""
457
+
458
+ #: templates/help.php:94
459
+ msgid "How do I use this?"
460
+ msgstr ""
461
+
462
+ #: templates/help.php:96
463
+ msgid ""
464
+ "Simply click \"Start Scan\" to run an automated scan of your site. The "
465
+ "scanner generates some traffic on your site and monitors your site's "
466
+ "performance on the server, then shows you the results. With this "
467
+ "information, you can decide what action to take."
468
+ msgstr ""
469
+
470
+ #: templates/help.php:101
471
+ msgid "What do I do with these results?"
472
+ msgstr ""
473
+
474
+ #: templates/help.php:103
475
+ msgid ""
476
+ "If your site loads in an acceptable time (usually &lt; 0.5 seconds), you "
477
+ "might consider other explanation for sluggish loading. For example, loading "
478
+ "large images, large videos, or a lot of content can cause slowness. Tools "
479
+ "like <a href=\"%1$s\" target=\"_blank\">%2$s</a>, <a href=\"%3$s\" target="
480
+ "\"_blank\">%4$s</a>, <a href=\"%5$s\" target=\"_blank\">%6$s</a>, or <a href="
481
+ "\"%7$s\" target=\"_blank\">%8$s</a> or <a href=\"%9$s\" target=\"_blank\">"
482
+ "%10$s</a> can show you a connection breakdown of your site's content."
483
+ msgstr ""
484
+
485
+ #: templates/help.php:104
486
+ msgid "webpagetest.org"
487
+ msgstr ""
488
+
489
+ #: templates/help.php:105 templates/help.php:339
490
+ msgid "Firebug"
491
+ msgstr ""
492
+
493
+ #: templates/help.php:106
494
+ msgid "Pingdom tools"
495
+ msgstr ""
496
+
497
+ #: templates/help.php:107 templates/help.php:341
498
+ msgid "Safari Developer Tools"
499
+ msgstr ""
500
+
501
+ #: templates/help.php:108 templates/help.php:340
502
+ msgid "Chrome Developer Tools"
503
+ msgstr ""
504
+
505
+ #: templates/help.php:114
506
+ msgid "How do I fix \"No visits recorded...\" ?"
507
+ msgstr ""
508
+
509
+ #: templates/help.php:116
510
+ msgid ""
511
+ "This error message means that after being disabled, the profiler did not "
512
+ "record any traffic on your site. There are several common causes for this:"
513
+ msgstr ""
514
+
515
+ #: templates/help.php:119 templates/help.php:126 templates/help.php:133
516
+ msgid "Cause:"
517
+ msgstr ""
518
+
519
+ #: templates/help.php:120
520
+ msgid ""
521
+ "Your site is using a caching plugin. The pages that are being scanned "
522
+ "aren't actually loading on the server because they're cached in your browser "
523
+ "or on the server before WordPress can generate them. The P3 plugin doesn't "
524
+ "load and doesn't record any traffic."
525
+ msgstr ""
526
+
527
+ #: templates/help.php:122 templates/help.php:129 templates/help.php:136
528
+ msgid "Solution:"
529
+ msgstr ""
530
+
531
+ #: templates/help.php:123
532
+ msgid ""
533
+ "Enable the \"Attempt to circumvent browser cache\" option in the advanced "
534
+ "settings."
535
+ msgstr ""
536
+
537
+ #: templates/help.php:127
538
+ msgid ""
539
+ "The IP address you've entered in the advanced settings dialog doesn't match "
540
+ "the IP address you're scanning from."
541
+ msgstr ""
542
+
543
+ #: templates/help.php:130
544
+ msgid "Check the IP address you've entered and try again."
545
+ msgstr ""
546
+
547
+ #: templates/help.php:134
548
+ msgid "You've selected a manual scan, but haven't generated any traffic."
549
+ msgstr ""
550
+
551
+ #: templates/help.php:137
552
+ msgid "Try the automated scan."
553
+ msgstr ""
554
+
555
+ #: templates/help.php:144
556
+ msgid "Why did P3 only record 2 or 3 visits during the scan?"
557
+ msgstr ""
558
+
559
+ #: templates/help.php:146
560
+ msgid ""
561
+ "If your site is using a caching plugin, some pages might be cached in your "
562
+ "browser or on the server and are loading before before WordPress can "
563
+ "generate them. When this happens, the P3 plugin doesn't load and doesn't "
564
+ "record any traffic. Please enable the \"Attempt to circumvent browser cache"
565
+ "\" option in the advanced settings."
566
+ msgstr ""
567
+
568
+ #: templates/help.php:151
569
+ msgid "How does this work?"
570
+ msgstr ""
571
+
572
+ #: templates/help.php:153
573
+ msgid ""
574
+ "When you activate the plugin by clicking \"Start Scan,\" it detects visits "
575
+ "from your IP address, and actively monitors all <a href=\"%s\" target="
576
+ "\"_blank\">php user defined function calls</a> while the server generates "
577
+ "your WordPress pages. It then records the information in a report file you "
578
+ "can view later. When the scan is complete, or you click \"Stop Scan,\" the "
579
+ "plugin becomes dormant again."
580
+ msgstr ""
581
+
582
+ #: templates/help.php:160
583
+ msgid "How does my site load the plugin?"
584
+ msgstr ""
585
+
586
+ #: templates/help.php:162
587
+ msgid ""
588
+ "This plugin automatically creates a <a href=\"%s\" target=\"_blank\">must-"
589
+ "use</a> plugin to load before other plugins. If that doesn't work, it runs "
590
+ "like a regular plugin."
591
+ msgstr ""
592
+
593
+ #: templates/help.php:166
594
+ msgid "You are currently using:"
595
+ msgstr ""
596
+
597
+ #: templates/help.php:173
598
+ msgid "must-use plugin"
599
+ msgstr ""
600
+
601
+ #: templates/help.php:177
602
+ msgid "plugin"
603
+ msgstr ""
604
+
605
+ #: templates/help.php:184
606
+ msgid "How accurate are these results?"
607
+ msgstr ""
608
+
609
+ #: templates/help.php:186
610
+ msgid ""
611
+ "The results have an inherent margin of error because of the nature of the "
612
+ "tool and its multi-layered design. The plugin changes the environment to "
613
+ "measure it, and that makes it impossible to get completely accurate "
614
+ "results.\n"
615
+ "<br /><br />\n"
616
+ "It gets really close, though! The \"margin of error\" on the Advanced "
617
+ "Metrics page displays the discrepancy between the measured results (the time "
618
+ "for your site's PHP code to completely run) and the expected results (sum of "
619
+ "the plugins, core, theme, profile load times) to show you the plugin's "
620
+ "accuracy.\n"
621
+ "<br /><br />\n"
622
+ "If you want more accurate results, you'll need to resort to a different "
623
+ "profiler like <a href=\"%1$s\" target=\"_blank\">%2$s</a>, but this will not "
624
+ "break down results by plugin."
625
+ msgstr ""
626
+
627
+ #: templates/help.php:191
628
+ msgid "xdebug"
629
+ msgstr ""
630
+
631
+ #: templates/help.php:197
632
+ msgid "Why are some plugins slow?"
633
+ msgstr ""
634
+
635
+ #: templates/help.php:199
636
+ msgid ""
637
+ "WordPress is a complex ecosystem of plugins and themes, and it lives on a "
638
+ "complex ecosystem of software on your web server.\n"
639
+ "<br /><br />\n"
640
+ "If a plugin runs slowly just once, it's probably an anomaly, a transient "
641
+ "hiccup, and you can safely ignore it.\n"
642
+ "<br /><br />\n"
643
+ "If a plugin shows slowness once on a reguarly basis (e.g. every time you run "
644
+ "a scan, once a day, once an hour), a scheduled task might be causing it. "
645
+ "Plugins that backup your site, monitor your site for changes, contact "
646
+ "outside sources (e.g. RSS feeds), warm up caches, etc. can exhibit this kind "
647
+ "of behavior.\n"
648
+ "<br /><br />\n"
649
+ "If a plugin shows as fast-slow-fast-slow-fast-slow, it could be caused as "
650
+ "the plugin loads its main code, then a follow-up piece of code, like a piece "
651
+ "of generated JavaScript.\n"
652
+ "<br /><br />\n"
653
+ "If a plugin consistently shows slowness, you might want to contact the "
654
+ "plugin author or try deactivating the plugin temporarily to see if it makes "
655
+ "a difference on your site."
656
+ msgstr ""
657
+
658
+ #: templates/help.php:212
659
+ msgid ""
660
+ "How are these results different from YSlow / PageSpeed / Webpagetest.org / "
661
+ "Pingdom Tools?"
662
+ msgstr ""
663
+
664
+ #: templates/help.php:214
665
+ msgid ""
666
+ "This plugin measures how your site was generated on the server. Tools like "
667
+ "<a href=\"%1$s\" target=\"_blank\">%2$s</a>, <a href=\"%3$s\" target=\"_blank"
668
+ "\">%4$s</a>, <a href=\"%5$s\" target=\"_blank\">%6$s</a>, and <a href=\"%7$s"
669
+ "\" target=\"_blank\">%8$s</a> measure how your site looks to the browser."
670
+ msgstr ""
671
+
672
+ #: templates/help.php:215 templates/help.php:337
673
+ msgid "YSlow"
674
+ msgstr ""
675
+
676
+ #: templates/help.php:216
677
+ msgid "PageSpeed"
678
+ msgstr ""
679
+
680
+ #: templates/help.php:217
681
+ msgid "Webpagetest.org"
682
+ msgstr ""
683
+
684
+ #: templates/help.php:218 templates/help.php:335
685
+ msgid "Pingdom Tools"
686
+ msgstr ""
687
+
688
+ #: templates/help.php:224
689
+ msgid "What can interfere with testing?"
690
+ msgstr ""
691
+
692
+ #: templates/help.php:226
693
+ msgid ""
694
+ "Opcode optimizers can interfere with PHP backtraces. Leaving opcode "
695
+ "optimizers turned on will result in timing that more accurately reflects "
696
+ "your site's real performance, but the function calls to plugins may be "
697
+ "\"optimized\" out of the backtraces and some plugins (especially those with "
698
+ "only one hook) might not show up. Disabling opcode caches results in slower "
699
+ "times, but shows all plugins.\n"
700
+ "<br /><br />\n"
701
+ "By default, this plugin attempts to disable any detected opcode optimizers "
702
+ "when it runs. You can change this setting by clicking \"Advanced Settings\" "
703
+ "under \"Start Scan.\"\n"
704
+ "<br /><br />\n"
705
+ "Caching plugins that have an option to disable caches for logged in users "
706
+ "will not give you the same performance profile that an anonymous users "
707
+ "experience. To get around this, you should select a manual scan, then run an "
708
+ "incognito browser window, or run another browser, and browse your site as a "
709
+ "logged out user. When you're finished, click \"I'm done,\" and your scan "
710
+ "should show the performance of an anonymous user."
711
+ msgstr ""
712
+
713
+ #: templates/help.php:235
714
+ msgid "Is my site using an opcode optimizer?"
715
+ msgstr ""
716
+
717
+ #: templates/help.php:238
718
+ msgid ""
719
+ "Your site is using XCache. Although XCache reports that no opcode "
720
+ "optimization won't be implemented until version 2.0, this has been known to "
721
+ "cause problems with P3."
722
+ msgstr ""
723
+
724
+ #: templates/help.php:242
725
+ msgid ""
726
+ "Your site is using APC. This has not been known to cause problems with P3."
727
+ msgstr ""
728
+
729
+ #: templates/help.php:246
730
+ msgid ""
731
+ "Your site is using eaccelerator with optimization enabled. This has been "
732
+ "known to cause problems with P3."
733
+ msgstr ""
734
+
735
+ #: templates/help.php:248
736
+ msgid ""
737
+ "To temporarily disable the optimizer you can add <code>php_flag eaccelerator."
738
+ "optimizer Off</code> to your site's .htaccess file."
739
+ msgstr ""
740
+
741
+ #: templates/help.php:250
742
+ msgid ""
743
+ "To temporarily disable the optimizer you can add <code>eaccelerator."
744
+ "optimizer = 0</code> to your site's <a href=\"%1$s\" target=\"_blank\">%2$s "
745
+ "file</a>."
746
+ msgstr ""
747
+
748
+ #: templates/help.php:255
749
+ msgid "To temporarily disable the optimizer you can ask your hosting provider."
750
+ msgstr ""
751
+
752
+ #: templates/help.php:260
753
+ msgid ""
754
+ "Your site is using Zend Optimizer+. This has not been known to cause "
755
+ "problems with P3."
756
+ msgstr ""
757
+
758
+ #: templates/help.php:264
759
+ msgid ""
760
+ "Your site is using the IonCube loader. This has not been known to cause "
761
+ "problems with P3."
762
+ msgstr ""
763
+
764
+ #: templates/help.php:268
765
+ msgid ""
766
+ "Your site is using wincache. This has not been known to cause problems with "
767
+ "P3."
768
+ msgstr ""
769
+
770
+ #: templates/help.php:272
771
+ msgid ""
772
+ "Your site is using the Zend Guard loader. This has not been known to cause "
773
+ "problems with P3."
774
+ msgstr ""
775
+
776
+ #: templates/help.php:276
777
+ msgid ""
778
+ "Your site is using the Zend Optimizer. This extension has not been tested "
779
+ "with P3. Please report any problems."
780
+ msgstr ""
781
+
782
+ #: templates/help.php:280
783
+ msgid ""
784
+ "P3 has not detected any opcode optimizers on your site. Although none were "
785
+ "detected, an opcode optimizer may still be present. Contact your server "
786
+ "administrator with any questions."
787
+ msgstr ""
788
+
789
+ #: templates/help.php:287
790
+ msgid "How much room do these profiles take up on my server"
791
+ msgstr ""
792
+
793
+ #: templates/help.php:300
794
+ msgid ""
795
+ "The scans are stored in <code>%1$s</code> and take up %2$s of disk space. "
796
+ "Each time you run a scan, this storage requirement goes up, and each time "
797
+ "you delete a scan, it goes down."
798
+ msgstr ""
799
+
800
+ #: templates/help.php:308
801
+ msgid "Is this plugin always running?"
802
+ msgstr ""
803
+
804
+ #: templates/help.php:310
805
+ msgid ""
806
+ "The short answer is no.\n"
807
+ "<br /><br />\n"
808
+ "The more detailed answer is the loader is always running, but checks very "
809
+ "early in the page loading process to see if you've enabled profiling mode "
810
+ "and if the user's IP address matches the IP address the plugin is "
811
+ "monitoring. For multisite installations, it also matches the site URL. If "
812
+ "all these match, the plugin becomes active and profiles. Otherwise, your "
813
+ "site loads as normal with no other code overhead.\n"
814
+ "<br /><br />\n"
815
+ "Deactivating the plugin ensures it's not running at all, and does not delete "
816
+ "your scans. However, uninstalling the plugin does delete your scans."
817
+ msgstr ""
818
+
819
+ #: templates/help.php:319
820
+ msgid "How can I test specific pages on my site?"
821
+ msgstr ""
822
+
823
+ #: templates/help.php:321
824
+ msgid ""
825
+ "When you start a scan, choose \"Manual Scan\" and then you can visit "
826
+ "specific links on your site that you want to profile. If you want to profile "
827
+ "the admin section, just click the \"X\" in the top right of the scan window "
828
+ "and you'll be returned to your admin section. You can browse as normal, then "
829
+ "come back to the profile page and click \"Stop Scan\" when you're ready to "
830
+ "view the results.\n"
831
+ "<br /><br />\n"
832
+ "To scan your site as an anonymous user, select \"Manual Mode\" as above, but "
833
+ "instead of clicking your site in the scan window, open a different browser "
834
+ "(or an incognito window) and browse your site as a logged out user. When "
835
+ "you're done, close that browser and return to your admin. Click \"I'm done\" "
836
+ "and view your scan results."
837
+ msgstr ""
838
+
839
+ #: templates/help.php:328
840
+ msgid ""
841
+ "My plugins don't seem to cause site slowness. Why is my site still slow?"
842
+ msgstr ""
843
+
844
+ #: templates/help.php:330
845
+ msgid ""
846
+ "Your site can be slow for a number of reasons. Your site could have a lot of "
847
+ "traffic, other sites on your server could have a lot of traffic, you could "
848
+ "be referencing content from other sites that are slow, your Internet "
849
+ "connection could be slow, your server could be out of RAM, your site could "
850
+ "be very image heavy, your site could require a lot of HTTP requests, etc. In "
851
+ "short, a lot of factors can cause slowness on your site\n"
852
+ "<br /><br />\n"
853
+ "Your next stop should be to use <a href=\"%1$s\" target=\"_blank\">%2$s</a>, "
854
+ "<a href=\"%3$s\" target=\"_blank\">%4$s</a>, <a href=\"%5$s\" target=\"_blank"
855
+ "\">%6$s</a>, <a href=\"%7$s\" target=\"_blank\">%8$s</a>, and your browser's "
856
+ "development tools like <a href=\"%9$s\" target=\"_blank\">%10$s</a> for "
857
+ "Firefox, <a href=\"%11$s\" target=\"_blank\">%12$s</a> for Chrome, or <a "
858
+ "href=\"%13$s\" target=\"_blank\">%14$s</a> for Safari.\n"
859
+ "<br /><br />\n"
860
+ "After you've tuned your site up as much as possible, if you're still not "
861
+ "happy with its performance, you should consult your site/server "
862
+ "administrator or hosting support."
863
+ msgstr ""
864
+
865
+ #: templates/help.php:336
866
+ msgid "Webpage Test"
867
+ msgstr ""
868
+
869
+ #: templates/help.php:338
870
+ msgid "Google PageSpeed"
871
+ msgstr ""
872
+
873
+ #: templates/help.php:347
874
+ msgid "Where can I view the debug log?"
875
+ msgstr ""
876
+
877
+ #: templates/help.php:349
878
+ msgid ""
879
+ "Debug mode will record 100 visits to your site, then turn off "
880
+ "automatically. You can view the log below. The entries are shown in "
881
+ "reverse order with the latest visits appearing at the top of the list. You "
882
+ "can also <a href=\"%1$s\" class=\"button-secondary\">Clear the log</a> or <a "
883
+ "href=\"%2$s\" class=\"button-secondary\">Download the log</a> as a CSV."
884
+ msgstr ""
885
+
886
+ #: templates/help.php:356
887
+ msgid "Debug Log"
888
+ msgstr ""
889
+
890
+ #: templates/help.php:365 templates/help.php:405
891
+ msgctxt "Symbol meaning number"
892
+ msgid "#"
893
+ msgstr ""
894
+
895
+ #: templates/help.php:398
896
+ msgid "ago"
897
+ msgstr ""
898
+
899
+ #: templates/help.php:424
900
+ msgid "What if I get a warning about usort()?"
901
+ msgstr ""
902
+
903
+ #: templates/help.php:426
904
+ msgctxt "Warning message is taken verbatim from PHP output"
905
+ msgid ""
906
+ "Warning messages like this: <code>Warning: usort() [function.usort]: Array "
907
+ "was modified by the user comparison function</code> are due to a known php "
908
+ "bug. See <a href=\"%s\" target=\"_blank\">php bug #50688</a> for more "
909
+ "information. This warning does not affect the functionality of your site "
910
+ "and it is not visible to your users."
911
+ msgstr ""
912
+
913
+ #: templates/help.php:433
914
+ msgid "Does this plugin increase memory usage on my site?"
915
+ msgstr ""
916
+
917
+ #: templates/help.php:435
918
+ msgid ""
919
+ "When you run a performance scan on your site, the memory requirements go up "
920
+ "during the scan. Accordingly, P3 sets your <a href=\"%1$s\" target=\"_blank"
921
+ "\">%2$s</a> to 256 MB and <a href=\"%3$s\" target=\"_blank\">%4$s</a> to 90 "
922
+ "seconds during a performance scan. These changes are not permanent and are "
923
+ "only in effect when a performance scan is actively running."
924
+ msgstr ""
925
+
926
+ #: templates/help.php:436
927
+ msgid "memory limit"
928
+ msgstr ""
929
+
930
+ #: templates/help.php:437
931
+ msgid "time limit"
932
+ msgstr ""
933
+
934
+ #: templates/help.php:443 templates/help.php:448
935
+ msgid "Glossary"
936
+ msgstr ""
937
+
938
+ #: templates/help.php:461
939
+ msgid "Total Load Time"
940
+ msgstr ""
941
+
942
+ #: templates/help.php:463
943
+ msgid ""
944
+ "The length of time the site took to load. This is an observed measurement "
945
+ "(start timing when the page was requested, stop timing when the page was "
946
+ "delivered to the browser, calculate the difference). Lower is better."
947
+ msgstr ""
948
+
949
+ #: templates/help.php:469 templates/view-scan.php:414
950
+ #: templates/view-scan.php:472 templates/view-scan.php:887
951
+ msgid "Site Load Time"
952
+ msgstr ""
953
+
954
+ #: templates/help.php:471 templates/view-scan.php:886
955
+ msgid ""
956
+ "The calculated total load time minus the profile overhead. This is closer to "
957
+ "your site's real-life load time. Lower is better."
958
+ msgstr ""
959
+
960
+ #: templates/help.php:476
961
+ msgid "Profile Overhead"
962
+ msgstr ""
963
+
964
+ #: templates/help.php:478
965
+ msgid ""
966
+ "The load time spent profiling code. Because the profiler slows down your "
967
+ "load time, it is important to know how much impact the profiler has. "
968
+ "However, it doesn't impact your site's real-life load time."
969
+ msgstr ""
970
+
971
+ #: templates/help.php:485
972
+ msgid ""
973
+ "The load time caused by plugins. Because of WordPress' construction, we can "
974
+ "trace a function call from a plugin through a theme through the core. The "
975
+ "profiler prioritizes plugin calls first, theme calls second, and core calls "
976
+ "last. Lower is better."
977
+ msgstr ""
978
+
979
+ #: templates/help.php:490
980
+ msgid "Theme Load Time"
981
+ msgstr ""
982
+
983
+ #: templates/help.php:492 templates/view-scan.php:910
984
+ msgid ""
985
+ "The load time spent applying the theme. Because of WordPress' construction, "
986
+ "we can trace a function call from a plugin through a theme through the core. "
987
+ "The profiler prioritizes plugin calls first, theme calls second, and core "
988
+ "calls last. Lower is better."
989
+ msgstr ""
990
+
991
+ #: templates/help.php:497
992
+ msgid "Core Load Time"
993
+ msgstr ""
994
+
995
+ #: templates/help.php:499 templates/view-scan.php:918
996
+ msgid ""
997
+ "The load time caused by the WordPress core. Because of WordPress' "
998
+ "construction, we can trace a function call from a plugin through a theme "
999
+ "through the core. The profiler prioritizes plugin calls first, theme calls "
1000
+ "second, and core calls last. This will probably be constant."
1001
+ msgstr ""
1002
+
1003
+ #: templates/help.php:504
1004
+ msgid "Margin of Error"
1005
+ msgstr ""
1006
+
1007
+ #: templates/help.php:506
1008
+ msgid ""
1009
+ "This is the difference between the observed runtime (what actually happened) "
1010
+ "and expected runtime (adding the plugin runtime, theme runtime, core "
1011
+ "runtime, and profiler overhead).\n"
1012
+ "<br /><br />\n"
1013
+ "There are several reasons this margin of error can exist. Most likely, the "
1014
+ "profiler is missing microseconds while adding the runtime it observed. Using "
1015
+ "a network clock to set the time (NTP) can also cause minute timing changes.\n"
1016
+ "<br /><br />\n"
1017
+ "Ideally, this number should be zero, but there's nothing you can do to "
1018
+ "change it. It will give you an idea of how accurate the other results are."
1019
+ msgstr ""
1020
+
1021
+ #: templates/help.php:515
1022
+ msgid "Observed"
1023
+ msgstr ""
1024
+
1025
+ #: templates/help.php:517
1026
+ msgid ""
1027
+ "The time the site took to load. This is an observed measurement (start "
1028
+ "timing when the page was requested, stop timing when the page was delivered "
1029
+ "to the browser, calculate the difference)."
1030
+ msgstr ""
1031
+
1032
+ #: templates/help.php:522
1033
+ msgid "Expected"
1034
+ msgstr ""
1035
+
1036
+ #: templates/help.php:524 templates/view-scan.php:934
1037
+ msgid ""
1038
+ "The expected site load time calculated by adding plugin load time, core load "
1039
+ "time, theme load time, and profiler overhead."
1040
+ msgstr ""
1041
+
1042
+ #: templates/help.php:529
1043
+ msgid "Plugin Function Calls"
1044
+ msgstr ""
1045
+
1046
+ #: templates/help.php:531
1047
+ msgid ""
1048
+ "The number of PHP function calls generated by a plugin. Fewer is better."
1049
+ msgstr ""
1050
+
1051
+ #: templates/help.php:536
1052
+ msgid "Memory Usage"
1053
+ msgstr ""
1054
+
1055
+ #: templates/help.php:538
1056
+ msgid ""
1057
+ "The amount of RAM usage observed. This is reported by <a href=\"%s\" target="
1058
+ "\"_blank\">memory_get_peak_usage()</a>. Lower is better."
1059
+ msgstr ""
1060
+
1061
+ #: templates/help.php:547
1062
+ msgid ""
1063
+ "The number of queries sent to the database. This is reported by the "
1064
+ "WordPress function <a href=\"%s\" target=\"_blank\">get_num_queries()</a>. "
1065
+ "Fewer is better."
1066
+ msgstr ""
1067
+
1068
+ #: templates/help.php:566
1069
+ msgid "License"
1070
+ msgstr ""
1071
+
1072
+ #: templates/help.php:568 templates/template.php:108
1073
+ msgid ""
1074
+ "P3 (Plugin Performance Profiler) is Copyright &copy; %1$s - %2$s <a href="
1075
+ "\"%3$s\" target=\"_blank\">GoDaddy.com</a>. All rights reserved."
1076
+ msgstr ""
1077
+
1078
+ #: templates/help.php:570
1079
+ msgid ""
1080
+ "This program is offered under the terms of the GNU General Public License "
1081
+ "Version 2 as published by the Free Software Foundation.\n"
1082
+ "<br /><br />\n"
1083
+ "This program offered WITHOUT WARRANTY; without even the implied warranty of "
1084
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General "
1085
+ "Public License Version 2 for the specific terms.\n"
1086
+ "<br /><br />\n"
1087
+ "A copy of the GNU General Public License has been provided with this "
1088
+ "program. Alternatively, you may find a copy of the license here: <a href="
1089
+ "\"%s\" target=\"_blank\">%s</a>."
1090
+ msgstr ""
1091
+
1092
+ #: templates/list-scans.php:16
1093
+ msgid "Are you sure you want to delete these scans?"
1094
+ msgstr ""
1095
+
1096
+ #: templates/list-scans.php:24
1097
+ msgid "Are you sure you want to delete this scan?"
1098
+ msgstr ""
1099
+
1100
+ #: templates/template.php:62
1101
+ msgid "P3 - Plugin Performance Profiler"
1102
+ msgstr ""
1103
+
1104
+ #: templates/template.php:68
1105
+ msgid "Current"
1106
+ msgstr ""
1107
+
1108
+ #: templates/template.php:70
1109
+ msgid "History"
1110
+ msgstr ""
1111
+
1112
+ #: templates/template.php:71
1113
+ msgid "Help"
1114
+ msgstr ""
1115
+
1116
+ #: templates/template.php:97
1117
+ msgid "Do you like this plugin?"
1118
+ msgstr ""
1119
+
1120
+ #: templates/template.php:99
1121
+ msgid "I just optimized my WordPress site with %1$s %2$s"
1122
+ msgstr ""
1123
+
1124
+ #: templates/template.php:99
1125
+ msgid "Tweet about it"
1126
+ msgstr ""
1127
+
1128
+ #: templates/template.php:100
1129
+ msgid "Rate it on the repository"
1130
+ msgstr ""
1131
+
1132
+ #: templates/template.php:106
1133
+ msgid "Logo"
1134
+ msgstr ""
1135
+
1136
+ #: templates/view-scan.php:51
1137
+ msgid "Toggle Series"
1138
+ msgstr ""
1139
+
1140
+ #: templates/view-scan.php:71
1141
+ msgid "Email Report"
1142
+ msgstr ""
1143
+
1144
+ #: templates/view-scan.php:75
1145
+ msgid "Send"
1146
+ msgstr ""
1147
+
1148
+ #: templates/view-scan.php:176
1149
+ msgid "No plugins"
1150
+ msgstr ""
1151
+
1152
+ #: templates/view-scan.php:206 templates/view-scan.php:311
1153
+ #: templates/view-scan.php:501 templates/view-scan.php:664
1154
+ #: templates/view-scan.php:882 templates/view-scan.php:890
1155
+ #: templates/view-scan.php:898 templates/view-scan.php:906
1156
+ #: templates/view-scan.php:914 templates/view-scan.php:922
1157
+ #: templates/view-scan.php:930
1158
+ msgid "seconds"
1159
+ msgstr ""
1160
+
1161
+ #: templates/view-scan.php:222
1162
+ msgid "WP Core time"
1163
+ msgstr ""
1164
+
1165
+ #: templates/view-scan.php:233
1166
+ msgid "Theme time"
1167
+ msgstr ""
1168
+
1169
+ #: templates/view-scan.php:244
1170
+ msgid "Plugin time"
1171
+ msgstr ""
1172
+
1173
+ #: templates/view-scan.php:328
1174
+ msgid "# of Queries"
1175
+ msgstr ""
1176
+
1177
+ #: templates/view-scan.php:394
1178
+ msgid "query"
1179
+ msgstr ""
1180
+
1181
+ #: templates/view-scan.php:394 templates/view-scan.php:967
1182
+ msgid "queries"
1183
+ msgstr ""
1184
+
1185
+ #: templates/view-scan.php:429 templates/view-scan.php:473
1186
+ #: templates/view-scan.php:527 templates/view-scan.php:577
1187
+ msgid "WP Core Time"
1188
+ msgstr ""
1189
+
1190
+ #: templates/view-scan.php:433 templates/view-scan.php:474
1191
+ #: templates/view-scan.php:540 templates/view-scan.php:578
1192
+ msgid "Theme"
1193
+ msgstr ""
1194
+
1195
+ #: templates/view-scan.php:607
1196
+ msgid "No data"
1197
+ msgstr ""
1198
+
1199
+ #: templates/view-scan.php:698
1200
+ msgid "Runtime By Plugin"
1201
+ msgstr ""
1202
+
1203
+ #: templates/view-scan.php:699 templates/view-scan.php:708
1204
+ msgid "Detailed Breakdown"
1205
+ msgstr ""
1206
+
1207
+ #: templates/view-scan.php:700
1208
+ msgid "Simple Timeline"
1209
+ msgstr ""
1210
+
1211
+ #: templates/view-scan.php:701 templates/view-scan.php:835
1212
+ msgid "Detailed Timeline"
1213
+ msgstr ""
1214
+
1215
+ #: templates/view-scan.php:702 templates/view-scan.php:800
1216
+ msgid "Query Timeline"
1217
+ msgstr ""
1218
+
1219
+ #: templates/view-scan.php:703 templates/view-scan.php:872
1220
+ msgid "Advanced Metrics"
1221
+ msgstr ""
1222
+
1223
+ #: templates/view-scan.php:714 templates/view-scan.php:771
1224
+ #: templates/view-scan.php:841
1225
+ msgid "Seconds"
1226
+ msgstr ""
1227
+
1228
+ #: templates/view-scan.php:721 templates/view-scan.php:751
1229
+ #: templates/view-scan.php:778 templates/view-scan.php:813
1230
+ #: templates/view-scan.php:848
1231
+ msgctxt "How to interpret the chart or graph"
1232
+ msgid "Legend"
1233
+ msgstr ""
1234
+
1235
+ #: templates/view-scan.php:733
1236
+ msgid "Component"
1237
+ msgstr ""
1238
+
1239
+ #: templates/view-scan.php:743
1240
+ msgid "Runtime by Plugin"
1241
+ msgstr ""
1242
+
1243
+ #: templates/view-scan.php:765
1244
+ msgid "Summary Timeline"
1245
+ msgstr ""
1246
+
1247
+ #: templates/view-scan.php:806
1248
+ msgid "Queries"
1249
+ msgstr ""
1250
+
1251
+ #: templates/view-scan.php:878
1252
+ msgid ""
1253
+ "The time the site took to load. This is an observed measurement (start "
1254
+ "timing when the page was requested, stop timing when the page was delivered "
1255
+ "to the browser, calculate the difference). Lower is better."
1256
+ msgstr ""
1257
+
1258
+ #: templates/view-scan.php:879
1259
+ msgid "Total Load Time:"
1260
+ msgstr ""
1261
+
1262
+ #: templates/view-scan.php:882 templates/view-scan.php:890
1263
+ #: templates/view-scan.php:898 templates/view-scan.php:906
1264
+ #: templates/view-scan.php:914 templates/view-scan.php:922
1265
+ #: templates/view-scan.php:930 templates/view-scan.php:951
1266
+ #: templates/view-scan.php:959 templates/view-scan.php:967
1267
+ msgctxt "Abbreviation for 'average'"
1268
+ msgid "avg."
1269
+ msgstr ""
1270
+
1271
+ #: templates/view-scan.php:894
1272
+ msgid ""
1273
+ "The load time spent profiling code. Because the profiler slows down your "
1274
+ "load time, it is important to know how much impact the profiler has. "
1275
+ "However, it doesn't impact your site's\treal-life load time."
1276
+ msgstr ""
1277
+
1278
+ #: templates/view-scan.php:895
1279
+ msgid "Profile Overhead:"
1280
+ msgstr ""
1281
+
1282
+ #: templates/view-scan.php:902
1283
+ msgid ""
1284
+ "The load time caused by plugins. Because of WordPress' construction, we can "
1285
+ "trace a function call from a plugin through a theme through the core. The "
1286
+ "profiler prioritizes plugin calls first, theme calls second, and core calls "
1287
+ "last. Lower is better."
1288
+ msgstr ""
1289
+
1290
+ #: templates/view-scan.php:903
1291
+ msgid "Plugin Load Time:"
1292
+ msgstr ""
1293
+
1294
+ #: templates/view-scan.php:911
1295
+ msgid "Theme Load Time:"
1296
+ msgstr ""
1297
+
1298
+ #: templates/view-scan.php:919
1299
+ msgid "Core Load Time:"
1300
+ msgstr ""
1301
+
1302
+ #: templates/view-scan.php:926
1303
+ msgid ""
1304
+ "This is the difference between the observed runtime (what actually happened) "
1305
+ "and expected runtime (adding the plugin runtime, theme runtime, core "
1306
+ "runtime, and profiler overhead). There are several reasons this margin of "
1307
+ "error can exist. Most likely, the profiler is missing microseconds while "
1308
+ "adding the runtime it observed. Using a network clock to set the time (NTP) "
1309
+ "can also cause minute timing changes. Ideally, this number should be zero, "
1310
+ "but there's nothing you can do to change it. It will give you an idea of how "
1311
+ "accurate the other results are."
1312
+ msgstr ""
1313
+
1314
+ #: templates/view-scan.php:927
1315
+ msgid "Margin of Error:"
1316
+ msgstr ""
1317
+
1318
+ #: templates/view-scan.php:933
1319
+ msgid ""
1320
+ "How long the site took to load. This is an observed measurement (start "
1321
+ "timing when the page was requested, stop timing when the page was delivered "
1322
+ "to the browser, calculate the difference)."
1323
+ msgstr ""
1324
+
1325
+ #: templates/view-scan.php:933
1326
+ msgid "observed"
1327
+ msgstr ""
1328
+
1329
+ #: templates/view-scan.php:934
1330
+ msgid "expected"
1331
+ msgstr ""
1332
+
1333
+ #: templates/view-scan.php:939
1334
+ msgid ""
1335
+ "The number of visits registered during a profiling session. More visits "
1336
+ "produce a more accurate summary."
1337
+ msgstr ""
1338
+
1339
+ #: templates/view-scan.php:940
1340
+ msgid "Visits:"
1341
+ msgstr ""
1342
+
1343
+ #: templates/view-scan.php:947
1344
+ msgid ""
1345
+ "The number of PHP ticks recorded during the profiling session. A tick is "
1346
+ "loosely correlated to a PHP statement or function call. Fewer is better."
1347
+ msgstr ""
1348
+
1349
+ #: templates/view-scan.php:948
1350
+ msgid "Number of PHP ticks:"
1351
+ msgstr ""
1352
+
1353
+ #: templates/view-scan.php:951
1354
+ msgid "calls"
1355
+ msgstr ""
1356
+
1357
+ #: templates/view-scan.php:955
1358
+ msgid ""
1359
+ "The amount of RAM usage observed. This is reported by memory_get_peak_usage"
1360
+ "(). Lower is better."
1361
+ msgstr ""
1362
+
1363
+ #: templates/view-scan.php:956
1364
+ msgid "Memory Usage:"
1365
+ msgstr ""
1366
+
1367
+ #: templates/view-scan.php:963
1368
+ msgid ""
1369
+ "The count of queries sent to the database. This is reported by the "
1370
+ "WordPress function get_num_queries(). Lower is better."
1371
+ msgstr ""
1372
+
1373
+ #: templates/view-scan.php:964
1374
+ msgid "MySQL Queries:"
1375
+ msgstr ""
1376
+
1377
+ #: templates/view-scan.php:979 templates/view-scan.php:980
1378
+ msgid "Email these results"
1379
+ msgstr ""
1380
+
1381
+ #: templates/view-scan.php:986
1382
+ msgid "From:"
1383
+ msgstr ""
1384
+
1385
+ #: templates/view-scan.php:988
1386
+ msgid "Enter the e-mail address to send from"
1387
+ msgstr ""
1388
+
1389
+ #: templates/view-scan.php:992
1390
+ msgid "Recipient:"
1391
+ msgstr ""
1392
+
1393
+ #: templates/view-scan.php:995
1394
+ msgid "Enter the e-mail address where you would like to send these results"
1395
+ msgstr ""
1396
+
1397
+ #: templates/view-scan.php:999
1398
+ msgid "Subject:"
1399
+ msgstr ""
1400
+
1401
+ #: templates/view-scan.php:1001
1402
+ msgid "Performance Profile Results for %s"
1403
+ msgstr ""
1404
+
1405
+ #: templates/view-scan.php:1001
1406
+ msgid "Enter the e-mail subject"
1407
+ msgstr ""
1408
+
1409
+ #: templates/view-scan.php:1005
1410
+ msgid "Message:"
1411
+ msgstr ""
1412
+
1413
+ #: templates/view-scan.php:1005
1414
+ msgid "(optional)"
1415
+ msgstr ""
1416
+
1417
+ #: templates/view-scan.php:1006
1418
+ msgid ""
1419
+ "Hello,\n"
1420
+ "\n"
1421
+ "I profiled my WordPress site's performance using the Profile Plugin and I "
1422
+ "wanted\n"
1423
+ "to share the results with you. Please take a look at the information below:"
1424
+ msgstr ""
1425
+
1426
+ #: templates/view-scan.php:1013
1427
+ msgid "Results:"
1428
+ msgstr ""
1429
+
1430
+ #: templates/view-scan.php:1013
1431
+ msgid "(system generated, do not edit)"
1432
+ msgstr ""
1433
+
1434
+ #: templates/view-scan.php:1019
1435
+ msgid ""
1436
+ "WordPress Plugin Profile Report\n"
1437
+ "===========================================\n"
1438
+ "Report date: %1$s\n"
1439
+ "Theme name: %2$s\n"
1440
+ "Pages browsed: %3$s\n"
1441
+ "Avg. load time: %4$s sec\n"
1442
+ "Number of plugins: %5$s\n"
1443
+ "Plugin impact: %6$s of load time\n"
1444
+ "Avg. plugin time: %7$s sec\n"
1445
+ "Avg. core time: %8$s sec\n"
1446
+ "Avg. theme time: %9$s sec\n"
1447
+ "Avg. mem usage: %10$s MB\n"
1448
+ "Avg. ticks: %11$s\n"
1449
+ "Avg. db queries : %12$s\n"
1450
+ "Margin of error : %13$s sec\n"
1451
+ "\n"
1452
+ "Plugin list:\n"
1453
+ "===========================================\n"
1454
+ "%14$s\n"
1455
+ msgstr ""
1456
+
1457
+ #: templates/view-scan.php:1061
1458
+ msgid "Loading"
1459
+ msgstr ""
1460
+
1461
+ #: templates/view-scan.php:1064
1462
+ msgid "There was a problem sending the e-mail:"
1463
+ msgstr ""
1464
+
1465
+ #: templates/view-scan.php:1067
1466
+ msgid "Your report was sent successfully to"
1467
+ msgstr ""
1468
+
1469
+ #: templates/view-scan.php:1070
1470
+ msgid "Done"
1471
+ msgstr ""
1472
+
1473
+ #. Plugin Name of the plugin/theme
1474
+ msgid "P3 (Plugin Performance Profiler)"
1475
+ msgstr ""
1476
+
1477
+ #. Plugin URI of the plugin/theme
1478
+ msgid "http://support.godaddy.com/godaddy/wordpress-p3-plugin/"
1479
+ msgstr ""
1480
+
1481
+ #. Description of the plugin/theme
1482
+ msgid ""
1483
+ "See which plugins are slowing down your site. Create a profile of your "
1484
+ "WordPress site's plugins' performance by measuring their impact on your "
1485
+ "site's load time."
1486
+ msgstr ""
1487
+
1488
+ #. Author of the plugin/theme
1489
+ msgid "GoDaddy.com"
1490
+ msgstr ""
1491
+
1492
+ #. Author URI of the plugin/theme
1493
+ msgid "http://www.godaddy.com/"
1494
+ msgstr ""
readme.txt CHANGED
@@ -2,8 +2,10 @@
2
  Contributors: Godaddy, StarfieldTech
3
  Tags: debug, debugging, developer, development, performance, plugin, profiler, speed
4
  Requires at least: 3.3
5
- Tested up to: 3.3.1
6
- Stable tag: 1.2.0
 
 
7
 
8
  See which plugins are slowing down your site. This plugin creates a performance report for your site.
9
 
@@ -43,6 +45,9 @@ Manual installation:
43
 
44
  == Upgrade Notice ==
45
 
 
 
 
46
  = 1.2.0 =
47
  Many compatibility fixes based on user feedback. Upgrading is recommended.
48
 
@@ -63,6 +68,10 @@ This version addresses a path disclosure issue. Users are encouraged to upgrade
63
 
64
  == Frequently Asked Questions ==
65
 
 
 
 
 
66
  = What if I get a warning about usort()? =
67
 
68
  Warning messages like this: `Warning: usort() [function.usort]: Array was modified by the user comparison function` are due to a known php bug. See [php bug #50688](https://bugs.php.net/bug.php?id=50688) for more information. This warning does not affect the functionality of your site and it is not visible to your users.
@@ -77,8 +86,42 @@ We love to make P3 better. When reporting a bug, please visit this page so we c
77
 
78
  Thanks!
79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  == Changelog ==
81
 
 
 
 
 
 
 
 
 
 
 
 
82
  = 1.2.0 =
83
  * Remove .profiling_enabled file, store profiling flag as a WordPress option
84
  * Remove code that writes to .htaccess file
2
  Contributors: Godaddy, StarfieldTech
3
  Tags: debug, debugging, developer, development, performance, plugin, profiler, speed
4
  Requires at least: 3.3
5
+ Tested up to: 3.4
6
+ Stable tag: 1.3.0
7
+ License: GPLv2
8
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
10
  See which plugins are slowing down your site. This plugin creates a performance report for your site.
11
 
45
 
46
  == Upgrade Notice ==
47
 
48
+ = 1.3.0 =
49
+ Internationalized P3, major refactoring for lower memory usage, compatibility with WordPress 3.4.
50
+
51
  = 1.2.0 =
52
  Many compatibility fixes based on user feedback. Upgrading is recommended.
53
 
68
 
69
  == Frequently Asked Questions ==
70
 
71
+ = I installed P3, what now? =
72
+
73
+ Open the **Tools** menu, then open **P3 Plugin Profiler** then click **Scan Now**.
74
+
75
  = What if I get a warning about usort()? =
76
 
77
  Warning messages like this: `Warning: usort() [function.usort]: Array was modified by the user comparison function` are due to a known php bug. See [php bug #50688](https://bugs.php.net/bug.php?id=50688) for more information. This warning does not affect the functionality of your site and it is not visible to your users.
86
 
87
  Thanks!
88
 
89
+ = Help! I used P3 and now my site is down! =
90
+
91
+ First, get your site back up! There are two ways to do this. Try the emergency shutoff switch first. If that doesn't work, delete the plugin files.
92
+
93
+ Emergency Shutoff Switch
94
+
95
+ 1. Visit yoursite.com/wordpress/index.php?P3_SHUTOFF=1
96
+
97
+ Delete the Plugin Files
98
+
99
+ 1. Delete wp-content/plugins/p3-profiler (the whole folder)
100
+ 2. Delete wp-content/mu-plugins/p3-profiler.php (if it exists)
101
+
102
+ This can happen if P3 hits the memory limit on your server while it's running. This happens most often on sites with many active plugins or a complex theme. Consider switching to the Twenty Eleven theme or deactivating a few plugins before re-running P3.
103
+
104
+ = I get "Warning: file_put_contents( .... )" =
105
+
106
+ Please check your media settings. This is in Settings -> Media -> Store uploads in this folder. If this folder is not set correctly, P3 won't know where to read the files.
107
+
108
+ = How do I use P3 with multisite? =
109
+
110
+ P3 is available on the Tools menu for each site in the network.
111
+
112
  == Changelog ==
113
 
114
+ = 1.3.0 =
115
+ * Internationalized P3
116
+ * Compatibility with WordPress 3.4.0
117
+ * Fixed a bug with European decimalization (0,00 vs. 0.00)
118
+ * Major refactoring for better adherence to best practices, using fewer hooks, and consuming less memory
119
+ * Raised memory limit override to 256M so large backtraces don't kill the site
120
+ * Added a kill switch. If P3 is causing problems, visit yoursite.com/wordpress/index.php?P3_SHUTOFF=1 to turn off P3
121
+ * Added automatic error detection. If a page fails to load during profiling, the next page load will turn off P3 automatically
122
+ * Removed ajax error alerts; they weren't helpful
123
+ * Path to the profiles folder is now determined on the init hook
124
+
125
  = 1.2.0 =
126
  * Remove .profiling_enabled file, store profiling flag as a WordPress option
127
  * Remove code that writes to .htaccess file
start-profile.php CHANGED
@@ -2,7 +2,47 @@
2
 
3
  // If profiling hasn't started, start it
4
  if ( !isset( $GLOBALS['p3_profiler'] ) && basename( __FILE__ ) != basename( $_SERVER['SCRIPT_FILENAME'] ) ) {
5
- declare( ticks = 1 ); // Capture every user function call
6
- include_once realpath( dirname( __FILE__ ) ) . '/class.p3-profiler.php';
7
- $GLOBALS['p3_profiler'] = new P3_Profiler(); // Go
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  }
2
 
3
  // If profiling hasn't started, start it
4
  if ( !isset( $GLOBALS['p3_profiler'] ) && basename( __FILE__ ) != basename( $_SERVER['SCRIPT_FILENAME'] ) ) {
5
+ $opts = get_option( 'p3-profiler_options' );
6
+ if ( !empty( $opts['profiling_enabled'] ) ) {
7
+ $file = realpath( dirname( __FILE__ ) ) . '/classes/class.p3-profiler.php';
8
+ if ( !file_exists( $file ) ) {
9
+ return;
10
+ }
11
+ @include_once $file;
12
+ declare( ticks = 1 ); // Capture every user function call
13
+ if ( class_exists( 'P3_Profiler' ) ) {
14
+ $GLOBALS['p3_profiler'] = new P3_Profiler(); // Go
15
+ }
16
+ }
17
+ unset( $opts );
18
+ }
19
+
20
+ /**
21
+ * Get the user's IP
22
+ * @return string
23
+ */
24
+ function p3_profiler_get_ip() {
25
+ static $ip = '';
26
+ if ( !empty( $ip ) ) {
27
+ return $ip;
28
+ } else {
29
+ if ( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
30
+ $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
31
+ } elseif ( !empty ( $_SERVER['HTTP_X_REAL_IP'] ) ) {
32
+ $ip = $_SERVER['HTTP_X_REAL_IP'];
33
+ } else {
34
+ $ip = $_SERVER['REMOTE_ADDR'];
35
+ }
36
+ return $ip;
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Disable profiling
42
+ * @return void
43
+ */
44
+ function p3_profiler_disable() {
45
+ $opts = get_option( 'p3-profiler_options' );
46
+ $opts['profiling_enabled'] = false;
47
+ update_option( 'p3-profiler_options', $opts );
48
  }
templates/callouts.php CHANGED
@@ -1,6 +1,8 @@
1
  <?php
2
  if ( !defined('P3_PATH') )
3
  die( 'Forbidden ');
 
 
4
  ?>
5
  <script type="text/javascript">
6
 
@@ -12,7 +14,7 @@ if ( !defined('P3_PATH') )
12
  var P3_Scan = {
13
 
14
  // List of pages to scan
15
- pages: <?php echo json_encode( $this->list_of_pages() ); ?>,
16
 
17
  // Current page
18
  current_page: 0,
@@ -57,17 +59,12 @@ if ( !defined('P3_PATH') )
57
 
58
  // Turn on the profiler
59
  jQuery.post( ajaxurl, data, function( response ) {
60
- if ( 1 != response ) {
61
- alert( "There was an error processing your request. Please reload the page and try again. [" + response + "]");
62
- } else {
63
-
64
- // Start scanning pages
65
- jQuery( "#p3-scan-frame" ).attr( "onload", "P3_Scan.next_page();" );
66
- jQuery( "#p3-scan-frame" ).attr( "src", P3_Scan.pages[0] );
67
- P3_Scan.current_page = 0;
68
- P3_Scan.update_display();
69
-
70
- }
71
  });
72
  },
73
 
@@ -80,9 +77,6 @@ if ( !defined('P3_PATH') )
80
  'p3_nonce' : '<?php echo wp_create_nonce( 'p3_ajax_stop_scan' ); ?>'
81
  }
82
  jQuery.post( ajaxurl, data, function( response ) {
83
- if ( response.indexOf( '.json' ) < 0 ) {
84
- alert( "There was an error processing your request. Please reload the page and try again. [" + response + "]");
85
- }
86
 
87
  // Hide the cancel button
88
  jQuery( "#p3-cancel-scan-buttonset" ).hide();
@@ -96,7 +90,7 @@ if ( !defined('P3_PATH') )
96
  P3_Scan.paused = true;
97
 
98
  // Update the caption
99
- jQuery( "#p3-scanning-caption" ).html( "Scanning is paused." ).css( "color", "black" );
100
  });
101
  },
102
 
@@ -115,9 +109,6 @@ if ( !defined('P3_PATH') )
115
 
116
  // Turn on the profiler
117
  jQuery.post( ajaxurl, data, function( response ) {
118
- if ( 1 != response ) {
119
- alert( "There was an error processing your request. Please reload the page and try again. [" + response + "]");
120
- } else {
121
 
122
  // Show the cancel button
123
  P3_Scan.paused = false;
@@ -126,7 +117,6 @@ if ( !defined('P3_PATH') )
126
  jQuery( "#p3-view-results-buttonset" ).hide();
127
  P3_Scan.update_display();
128
  P3_Scan.next_page();
129
- }
130
  });
131
  },
132
 
@@ -139,9 +129,6 @@ if ( !defined('P3_PATH') )
139
  'p3_nonce' : '<?php echo wp_create_nonce( 'p3_ajax_stop_scan' ); ?>'
140
  }
141
  jQuery.post( ajaxurl, data, function( response ) {
142
- if ( response.indexOf( '.json' ) < 0 ) {
143
- alert( "There was an error processing your request. Please reload the page and try again. [" + response + "]");
144
- }
145
 
146
  // Hide the cancel button
147
  jQuery( "#p3-cancel-scan-buttonset" ).hide();
@@ -152,13 +139,13 @@ if ( !defined('P3_PATH') )
152
  jQuery( "#p3-view-results-submit" ).attr( "data-scan-name", response );
153
 
154
  // Update the caption
155
- jQuery( "#p3-scanning-caption" ).html( "Scanning is complete." ).css( "color", "black" );
156
  });
157
  },
158
 
159
  // Update the display
160
  update_display : function() {
161
- jQuery( "#p3-scanning-caption" ).html( 'Scanning ' + P3_Scan.pages[P3_Scan.current_page] ).css( "color", "" );
162
  jQuery( "#p3-progress" ).progressbar( "value", ( P3_Scan.current_page / ( P3_Scan.pages.length - 1 ) ) * 100 );
163
  },
164
 
@@ -187,10 +174,10 @@ if ( !defined('P3_PATH') )
187
  // Sync save settings
188
  function p3_sync_advanced_settings() {
189
  if ( jQuery( "#p3-use-current-ip" ).prop( "checked" ) ) {
190
- jQuery( "#p3-advanced-ip" ).val( "<?php echo esc_js( $GLOBALS['p3_profiler']->get_ip() ); ?>" );
191
  jQuery( "#p3-advanced-ip" ).prop( "disabled", true );
192
  } else {
193
- <?php $ip = get_option( 'p3-profiler_ip_address' ); if ( empty( $ip ) ) { $ip = $GLOBALS['p3_profiler']->get_ip(); } ?>
194
  jQuery( "#p3-advanced-ip" ).val( "<?php echo esc_js( $ip ); ?>" );
195
  jQuery( "#p3-advanced-ip" ).prop( "disabled", false );
196
  }
@@ -212,11 +199,11 @@ if ( !defined('P3_PATH') )
212
  'modal' : true,
213
  'width' : 450,
214
  'height' : 425,
215
- 'title' : "Advanced Settings",
216
  'buttons' :
217
  [
218
  {
219
- text: 'OK',
220
  'class' : 'button-secondary',
221
  click: function() {
222
 
@@ -229,17 +216,14 @@ if ( !defined('P3_PATH') )
229
  'p3_cache_buster' : $( '#p3-cache-buster' ).prop( 'checked' ),
230
  'p3_debug' : $( '#p3-debug' ).prop( 'checked' ),
231
  'p3_nonce' : '<?php echo wp_create_nonce( 'p3_save_settings' ); ?>'
232
- }
233
  $.post( ajaxurl, data, function( response ) {
234
- if ( 1 != response ) {
235
- alert( "There was an error saving your settings. Please reload the page and try again. [" + response + "]");
236
- }
237
  $( "#p3-ip-dialog" ).dialog( "close" );
238
  });
239
  }
240
  },
241
  {
242
- text: 'Cancel',
243
  'class': 'p3-cancel-button',
244
  click: function() {
245
  $( this ).dialog( "close" );
@@ -257,7 +241,7 @@ if ( !defined('P3_PATH') )
257
  'modal' : true,
258
  'width': 800,
259
  'height' : 600,
260
- 'title' : "Performance Scan",
261
  'dialogClass' : 'noPadding'
262
  });
263
 
@@ -270,7 +254,7 @@ if ( !defined('P3_PATH') )
270
  'modal' : true,
271
  'width' : 425,
272
  'height' : 180,
273
- 'title' : 'Scan Name'
274
  // 'dialogClass' : 'noTitle'
275
  });
276
 
@@ -337,9 +321,6 @@ if ( !defined('P3_PATH') )
337
  'p3_nonce' : '<?php echo wp_create_nonce( 'p3_ajax_stop_scan' ); ?>'
338
  }
339
  jQuery.post( ajaxurl, data, function( response ) {
340
- if ( response.indexOf( '.json' ) < 0 ) {
341
- alert( "There was an error processing your request. Please reload the page and try again. [" + response + "]");
342
- }
343
  location.reload();
344
  });
345
  });
@@ -371,7 +352,6 @@ if ( !defined('P3_PATH') )
371
  // Stay checked to keep the styling
372
  $( this ).prop( "checked", true );
373
  $( this ).button( "refresh" );
374
-
375
 
376
  // Form data
377
  data = {
@@ -386,9 +366,6 @@ if ( !defined('P3_PATH') )
386
 
387
  // Turn on the profiler
388
  jQuery.post( ajaxurl, data, function( response ) {
389
- if ( 1 != response ) {
390
- alert( "There was an error processing your request. Please reload the page and try again. [" + response + "]");
391
- }
392
  });
393
 
394
  $( "#p3-scan-name-dialog" ).dialog( "close" );
@@ -403,11 +380,7 @@ if ( !defined('P3_PATH') )
403
  'p3_nonce' : '<?php echo wp_create_nonce( 'p3_ajax_stop_scan' ); ?>'
404
  }
405
  jQuery.post( ajaxurl, data, function( response ) {
406
- if ( response.indexOf( '.json' ) < 0 ) {
407
- alert( "There was an error processing your request. Please reload the page and try again. [" + response + "]");
408
- } else {
409
- location.href = "<?php echo add_query_arg( array( 'p3_action' => 'view-scan', 'current_scan' => '1', 'name' => null ) ); ?>&name=" + response;
410
- }
411
  })
412
  $( "#p3-scanner-dialog" ).dialog( "close" );
413
  });
@@ -498,22 +471,22 @@ if ( !defined('P3_PATH') )
498
 
499
  <td>
500
  <div class="ui-widget-header" id="p3-scan-form-wrapper">
501
- <?php if ( false !== ( $info = $this->scan_enabled() ) ) { ?>
502
  <!-- Stop scan button -->
503
 
504
  <strong>IP:</strong><?php echo htmlentities( $info['ip'] ); ?>
505
  <div class="p3-big-button"><input type="checkbox" checked="checked" id="p3-stop-scan-submit" />
506
- <label for="p3-stop-scan-submit">Stop Scan</label></div>
507
  <?php echo htmlentities( $info['name'] ); ?>
508
 
509
  <?php } else { ?>
510
 
511
  <!-- Start scan button -->
512
  <?php echo wp_nonce_field( 'p3_ajax_start_scan', 'p3_nonce' ); ?>
513
- <strong>My IP:</strong><?php echo htmlentities( $GLOBALS['p3_profiler']->get_ip() ); ?>
514
  <div class="p3-big-button"><input type="checkbox" checked="checked" id="p3-start-scan-submit" />
515
- <label for="p3-start-scan-submit">Start Scan</label></div>
516
- <a href="javascript:;" id="p3-advanced-settings">Advanced Settings</a>
517
 
518
  <?php } ?>
519
  </div>
@@ -521,9 +494,9 @@ if ( !defined('P3_PATH') )
521
 
522
  <!-- First callout cell -->
523
  <td class="p3-callout">
524
- <div class="p3-callout-outer-wrapper qtip-tip" title="Total number of active plugins, including must-use plugins, on your site.">
525
  <div class="p3-callout-inner-wrapper">
526
- <div class="p3-callout-caption">Total Plugins:</div>
527
  <div class="p3-callout-data">
528
  <?php
529
  // Get the total number of plugins
@@ -536,61 +509,61 @@ if ( !defined('P3_PATH') )
536
  echo $active_plugins;
537
  ?>
538
  </div>
539
- <div class="p3-callout-caption">(currently active)</div>
540
  </div>
541
  </div>
542
  </td>
543
 
544
  <!-- Second callout cell -->
545
  <td class="p3-callout">
546
- <div class="p3-callout-outer-wrapper qtip-tip" title="Total number of seconds dedicated to plugin code per visit on your site."
547
- <?php if ( !empty( $this->scan ) ) { ?>title="From <?php echo basename( $this->scan ); ?><?php } ?>">
548
  <div class="p3-callout-inner-wrapper">
549
- <div class="p3-callout-caption">Plugin Load Time</div>
550
  <div class="p3-callout-data">
551
- <?php if ( null === $this->profile ) { ?>
552
- <span class="p3-faded-grey">n/a</span>
553
  <?php } else { ?>
554
- <?php printf( '%.3f', $this->profile->averages['plugins'] ); ?>
555
  <?php } ?>
556
  </div>
557
- <div class="p3-callout-caption">(sec. per visit)</div>
558
  </div>
559
  </div>
560
  </td>
561
 
562
  <!-- Third callout cell -->
563
  <td class="p3-callout">
564
- <div class="p3-callout-outer-wrapper qtip-tip" title="Percent of load time on your site dedicated to plugin code."
565
- <?php if ( !empty( $this->scan ) ) { ?>title="From <?php echo basename( $this->scan ); ?><?php } ?>">
566
  <div class="p3-callout-inner-wrapper">
567
- <div class="p3-callout-caption">Plugin Impact</div>
568
  <div class="p3-callout-data">
569
- <?php if ( null === $this->profile ) { ?>
570
- <span class="p3-faded-grey">n/a</span>
571
  <?php } else { ?>
572
- <?php printf( '%.1f%%', $this->profile->averages['plugin_impact'] ); ?>
573
  <?php } ?>
574
  </div>
575
- <div class="p3-callout-caption">(of page load time)</div>
576
  </div>
577
  </div>
578
  </td>
579
 
580
  <!-- Fourth callout cell -->
581
  <td class="p3-callout">
582
- <div class="p3-callout-outer-wrapper qtip-tip" title="Total number of database queries per visit."
583
- <?php if ( !empty( $this->scan ) ) { ?>title="From <?php echo basename( $this->scan ); ?><?php } ?>">
584
  <div class="p3-callout-inner-wrapper">
585
- <div class="p3-callout-caption">MySQL Queries</div>
586
  <div class="p3-callout-data">
587
- <?php if ( null === $this->profile ) { ?>
588
- <span class="p3-faded-grey">n/a</span>
589
  <?php } else { ?>
590
- <?php echo round( $this->profile->averages['queries'] ); ?>
591
  <?php } ?>
592
  </div>
593
- <div class="p3-callout-caption">per visit</div>
594
  </div>
595
  </div>
596
  </td>
@@ -601,34 +574,38 @@ if ( !defined('P3_PATH') )
601
  <!-- Dialog for IP settings -->
602
  <div id="p3-ip-dialog" class="p3-dialog">
603
  <div>
604
- IP address or pattern:<br /><br />
605
- <input type="checkbox" id="p3-use-current-ip" <?php if ( true == get_option( 'p3-profiler_use_current_ip' ) ) : ?>checked="checked"<?php endif; ?> />
606
- <label for="p3-use-current-ip">Use my IP address</label>
607
  <br />
608
- <input type="text" id="p3-advanced-ip" style="width:90%;" size="35" value="" title="Enter IP address or regular expression pattern" />
609
  <br />
610
- <em class="p3-em">Example: 1.2.3.4 or ( 1.2.3.4|4.5.6.7 )</em>
611
  </div>
612
  <br />
613
  <div>
614
- <input type="checkbox" id="p3-disable-opcode-cache" <?php if ( true == get_option( 'p3-profiler_disable_opcode_cache' ) ) : ?>checked="checked"<?php endif; ?> />
615
- <label for="p3-disable-opcode-cache">Attempt to disable opcode optimizers <em>(recommended)</em></label>
616
  <br />
617
- <em class="p3-em">This can increase accuracy in plugin detection, but decrease accuracy in timing</em>
618
  </div>
619
  <br />
620
  <div>
621
- <input type="checkbox" id="p3-cache-buster" <?php if ( true == get_option( 'p3-profiler_cache_buster' ) ) : ?>checked="checked"<?php endif; ?> />
622
- <label for="p3-cache-buster">Attempt to circumvent browser cache</label>
623
  <br />
624
- <em class="p3-em">This may help fix a "No visits recorded" error message. See the <a href="<?php echo add_query_arg( array( 'p3_action' => 'help', 'current_scan' => null ) ); ?>#q-debug-log">help</a> page for details.</em>
 
 
625
  </div>
626
  <br />
627
  <div>
628
- <input type="checkbox" id="p3-debug" <?php if ( true == get_option( 'p3-profiler_debug' ) ) : ?>checked="checked"<?php endif; ?> />
629
- <label for="p3-debug">Debug mode</label>
630
  <br />
631
- <em class="p3-em">This will log the last 100 visits. Check the <a href="<?php echo add_query_arg( array( 'p3_action' => 'help', 'current_scan' => null ) ); ?>#q-debug-log">help</a> page to view log messages.</em>
 
 
632
  </div>
633
  </div>
634
 
@@ -638,23 +615,20 @@ if ( !defined('P3_PATH') )
638
  data-defaultsrc="<?php echo ( true === force_ssl_admin() ? str_replace( 'http://', 'https://', home_url() ) : home_url() ); ?>">
639
  </iframe>
640
  <div id="p3-scan-caption">
641
- The scanner will analyze the speed and resource usage of all active plugins on your website.
642
- It may take several minutes, and this window must remain open for the scan to finish successfully.
643
  </div>
644
  <div id="p3-manual-scan-caption" style="display: none;">
645
  <table>
646
  <tr>
647
  <td>
648
- Click the links and pages of your site, and the scanner will
649
- analyze the speed and resource usage of all of your active
650
- plugins.
651
  </td>
652
  <td width="220">
653
- <a href="javascript:;" id="p3-manual-scan-cancel">Cancel</a>
654
  &nbsp;&nbsp;&nbsp;
655
  <span class="p3-big-button">
656
  <input type="checkbox" id="p3-manual-scan-done-submit" checked="checked" />
657
- <label for="p3-manual-scan-done-submit">I'm Done</label>
658
  </span>
659
  </td>
660
  </tr>
@@ -664,40 +638,40 @@ if ( !defined('P3_PATH') )
664
 
665
  <!-- Dialog for choose manual or auto scan -->
666
  <div id="p3-scan-name-dialog" class="p3-dialog">
667
- <div style="padding-top: 10px;">Scan name:
668
- <input type="text" name="p3_scan_name" id="p3-scan-name" title="Enter scan name here"
669
  value="scan_<?php echo date( 'Y-m-d' ); ?>_<?php echo substr( md5( uniqid() ), -8 );?>" size="35" maxlength="100" />
670
  </div>
671
- <div style="padding-top: 10px;"><em class="p3-em">Enter the name of a previous scan to continue scanning</em></div>
672
  <br />
673
  <div class="p3-big-button">
674
- <input type="checkbox" id="p3-auto-scan-submit" checked="checked" /><label for="p3-auto-scan-submit">Auto Scan</label>
675
- <input type="checkbox" id="p3-manual-scan-submit" checked="checked" /><label for="p3-manual-scan-submit">Manual Scan</label>
676
  </div>
677
  </div>
678
 
679
  <!-- Dialog for progress bar -->
680
  <div id="p3-progress-dialog" class="p3-dialog">
681
  <div id="p3-scanning-caption">
682
- Scanning ...
683
  </div>
684
  <div id="p3-progress"></div>
685
 
686
  <!-- Cancel button -->
687
  <div class="p3-big-button" id="p3-cancel-scan-buttonset">
688
- <input type="checkbox" id="p3-cancel-scan-submit" checked="checked" /><label for="p3-cancel-scan-submit">Stop Scan</label>
689
  </div>
690
 
691
  <!-- View / resume buttons -->
692
  <div class="p3-big-button" id="p3-resume-scan-buttonset" style="display: none;">
693
- <input type="checkbox" id="p3-resume-scan-submit" checked="checked" /><label for="p3-resume-scan-submit">Resume</label>
694
  <input type="checkbox" id="p3-view-incomplete-results-submit" checked="checked" data-scan-name="" />
695
- <label for="p3-view-incomplete-results-submit">View Results</label>
696
  </div>
697
 
698
  <!-- View results button -->
699
  <div class="p3-big-button" id="p3-view-results-buttonset" style="display: none;">
700
  <input type="checkbox" id="p3-view-results-submit" checked="checked" data-scan-name="" />
701
- <label for="p3-view-results-submit">View Results</label>
702
  </div>
703
  </div>
1
  <?php
2
  if ( !defined('P3_PATH') )
3
  die( 'Forbidden ');
4
+
5
+ $opts = get_option( 'p3-profiler_options' );
6
  ?>
7
  <script type="text/javascript">
8
 
14
  var P3_Scan = {
15
 
16
  // List of pages to scan
17
+ pages: <?php echo json_encode( self::list_of_pages() ); ?>,
18
 
19
  // Current page
20
  current_page: 0,
59
 
60
  // Turn on the profiler
61
  jQuery.post( ajaxurl, data, function( response ) {
62
+
63
+ // Start scanning pages
64
+ jQuery( "#p3-scan-frame" ).attr( "onload", "P3_Scan.next_page();" );
65
+ jQuery( "#p3-scan-frame" ).attr( "src", P3_Scan.pages[0] );
66
+ P3_Scan.current_page = 0;
67
+ P3_Scan.update_display();
 
 
 
 
 
68
  });
69
  },
70
 
77
  'p3_nonce' : '<?php echo wp_create_nonce( 'p3_ajax_stop_scan' ); ?>'
78
  }
79
  jQuery.post( ajaxurl, data, function( response ) {
 
 
 
80
 
81
  // Hide the cancel button
82
  jQuery( "#p3-cancel-scan-buttonset" ).hide();
90
  P3_Scan.paused = true;
91
 
92
  // Update the caption
93
+ jQuery( "#p3-scanning-caption" ).html( "<?php _e( 'Scanning is paused.', 'p3-profiler' ); ?>" ).css( "color", "black" );
94
  });
95
  },
96
 
109
 
110
  // Turn on the profiler
111
  jQuery.post( ajaxurl, data, function( response ) {
 
 
 
112
 
113
  // Show the cancel button
114
  P3_Scan.paused = false;
117
  jQuery( "#p3-view-results-buttonset" ).hide();
118
  P3_Scan.update_display();
119
  P3_Scan.next_page();
 
120
  });
121
  },
122
 
129
  'p3_nonce' : '<?php echo wp_create_nonce( 'p3_ajax_stop_scan' ); ?>'
130
  }
131
  jQuery.post( ajaxurl, data, function( response ) {
 
 
 
132
 
133
  // Hide the cancel button
134
  jQuery( "#p3-cancel-scan-buttonset" ).hide();
139
  jQuery( "#p3-view-results-submit" ).attr( "data-scan-name", response );
140
 
141
  // Update the caption
142
+ jQuery( "#p3-scanning-caption" ).html( "<?php _e( 'Scanning is complete.', 'p3-profiler' ); ?>" ).css( "color", "black" );
143
  });
144
  },
145
 
146
  // Update the display
147
  update_display : function() {
148
+ jQuery( "#p3-scanning-caption" ).html( '<?php _e( 'Scanning', 'p3-profiler' ); ?> ' + P3_Scan.pages[P3_Scan.current_page] ).css( "color", "" );
149
  jQuery( "#p3-progress" ).progressbar( "value", ( P3_Scan.current_page / ( P3_Scan.pages.length - 1 ) ) * 100 );
150
  },
151
 
174
  // Sync save settings
175
  function p3_sync_advanced_settings() {
176
  if ( jQuery( "#p3-use-current-ip" ).prop( "checked" ) ) {
177
+ jQuery( "#p3-advanced-ip" ).val( "<?php echo esc_js( p3_profiler_get_ip() ); ?>" );
178
  jQuery( "#p3-advanced-ip" ).prop( "disabled", true );
179
  } else {
180
+ <?php $ip = $opts['ip_address']; if ( empty( $ip ) ) { $ip = p3_profiler_get_ip(); } ?>
181
  jQuery( "#p3-advanced-ip" ).val( "<?php echo esc_js( $ip ); ?>" );
182
  jQuery( "#p3-advanced-ip" ).prop( "disabled", false );
183
  }
199
  'modal' : true,
200
  'width' : 450,
201
  'height' : 425,
202
+ 'title' : "<?php _e( 'Advanced Settings', 'p3-profiler' ); ?>",
203
  'buttons' :
204
  [
205
  {
206
+ text: '<?php _e( 'OK', 'p3-profiler' ); ?>',
207
  'class' : 'button-secondary',
208
  click: function() {
209
 
216
  'p3_cache_buster' : $( '#p3-cache-buster' ).prop( 'checked' ),
217
  'p3_debug' : $( '#p3-debug' ).prop( 'checked' ),
218
  'p3_nonce' : '<?php echo wp_create_nonce( 'p3_save_settings' ); ?>'
219
+ };
220
  $.post( ajaxurl, data, function( response ) {
 
 
 
221
  $( "#p3-ip-dialog" ).dialog( "close" );
222
  });
223
  }
224
  },
225
  {
226
+ text: '<?php _e( 'Cancel', 'p3-profiler'); ?>',
227
  'class': 'p3-cancel-button',
228
  click: function() {
229
  $( this ).dialog( "close" );
241
  'modal' : true,
242
  'width': 800,
243
  'height' : 600,
244
+ 'title' : "<?php _e( 'Performance Scan', 'p3-profiler' ); ?>",
245
  'dialogClass' : 'noPadding'
246
  });
247
 
254
  'modal' : true,
255
  'width' : 425,
256
  'height' : 180,
257
+ 'title' : '<?php _e( 'Scan Name', 'p3-profiler' ); ?>'
258
  // 'dialogClass' : 'noTitle'
259
  });
260
 
321
  'p3_nonce' : '<?php echo wp_create_nonce( 'p3_ajax_stop_scan' ); ?>'
322
  }
323
  jQuery.post( ajaxurl, data, function( response ) {
 
 
 
324
  location.reload();
325
  });
326
  });
352
  // Stay checked to keep the styling
353
  $( this ).prop( "checked", true );
354
  $( this ).button( "refresh" );
 
355
 
356
  // Form data
357
  data = {
366
 
367
  // Turn on the profiler
368
  jQuery.post( ajaxurl, data, function( response ) {
 
 
 
369
  });
370
 
371
  $( "#p3-scan-name-dialog" ).dialog( "close" );
380
  'p3_nonce' : '<?php echo wp_create_nonce( 'p3_ajax_stop_scan' ); ?>'
381
  }
382
  jQuery.post( ajaxurl, data, function( response ) {
383
+ location.href = "<?php echo add_query_arg( array( 'p3_action' => 'view-scan', 'current_scan' => '1', 'name' => null ) ); ?>&name=" + response;
 
 
 
 
384
  })
385
  $( "#p3-scanner-dialog" ).dialog( "close" );
386
  });
471
 
472
  <td>
473
  <div class="ui-widget-header" id="p3-scan-form-wrapper">
474
+ <?php if ( false !== ( $info = self::scan_enabled() ) ) { ?>
475
  <!-- Stop scan button -->
476
 
477
  <strong>IP:</strong><?php echo htmlentities( $info['ip'] ); ?>
478
  <div class="p3-big-button"><input type="checkbox" checked="checked" id="p3-stop-scan-submit" />
479
+ <label for="p3-stop-scan-submit"><?php _e( 'Stop Scan', 'p3-profiler' ); ?></label></div>
480
  <?php echo htmlentities( $info['name'] ); ?>
481
 
482
  <?php } else { ?>
483
 
484
  <!-- Start scan button -->
485
  <?php echo wp_nonce_field( 'p3_ajax_start_scan', 'p3_nonce' ); ?>
486
+ <strong><?php _e( 'My IP:', 'p3-profiler' ); ?></strong><?php echo htmlentities( p3_profiler_get_ip() ); ?>
487
  <div class="p3-big-button"><input type="checkbox" checked="checked" id="p3-start-scan-submit" />
488
+ <label for="p3-start-scan-submit"><?php _e( 'Start Scan', 'p3-profiler' ); ?></label></div>
489
+ <a href="javascript:;" id="p3-advanced-settings"><?php _e( 'Advanced Settings', 'p3-profiler' ); ?></a>
490
 
491
  <?php } ?>
492
  </div>
494
 
495
  <!-- First callout cell -->
496
  <td class="p3-callout">
497
+ <div class="p3-callout-outer-wrapper qtip-tip" title="<?php esc_attr_e( 'Total number of active plugins, including must-use plugins, on your site.', 'p3-profiler' ); ?>">
498
  <div class="p3-callout-inner-wrapper">
499
+ <div class="p3-callout-caption"><?php _e( 'Total Plugins:', 'p3-profiler' ); ?></div>
500
  <div class="p3-callout-data">
501
  <?php
502
  // Get the total number of plugins
509
  echo $active_plugins;
510
  ?>
511
  </div>
512
+ <div class="p3-callout-caption">(<?php _e( 'currently active', 'p3-profiler' ); ?>)</div>
513
  </div>
514
  </div>
515
  </td>
516
 
517
  <!-- Second callout cell -->
518
  <td class="p3-callout">
519
+ <div class="p3-callout-outer-wrapper qtip-tip" title="<?php esc_attr_e( 'Total number of seconds dedicated to plugin code per visit on your site.', 'p3-profiler' ); ?>"
520
+ <?php if ( !empty( self::$scan ) ) { ?>title="<?php esc_attr_e( 'From', 'p3-profiler' ); ?> <?php echo basename( self::$scan ); ?><?php } ?>">
521
  <div class="p3-callout-inner-wrapper">
522
+ <div class="p3-callout-caption"><?php _e( 'Plugin Load Time', 'p3-profiler' ); ?></div>
523
  <div class="p3-callout-data">
524
+ <?php if ( null === self::$profile ) { ?>
525
+ <span class="p3-faded-grey"><?php _e( 'n/a', 'p3-profiler' ); ?></span>
526
  <?php } else { ?>
527
+ <?php printf( '%.3f', self::$profile->averages['plugins'] ); ?>
528
  <?php } ?>
529
  </div>
530
+ <div class="p3-callout-caption">(<?php _e( 'sec. per visit', 'p3-profiler' ); ?>)</div>
531
  </div>
532
  </div>
533
  </td>
534
 
535
  <!-- Third callout cell -->
536
  <td class="p3-callout">
537
+ <div class="p3-callout-outer-wrapper qtip-tip" title="<?php esc_attr_e( 'Percent of load time on your site dedicated to plugin code', 'p3-profiler' ); ?>"
538
+ <?php if ( !empty( self::$scan ) ) { ?>title="<?php esc_attr_e( 'From', 'p3-profiler' ); ?> <?php echo basename( self::$scan ); ?><?php } ?>">
539
  <div class="p3-callout-inner-wrapper">
540
+ <div class="p3-callout-caption"><?php _e( 'Plugin Impact', 'p3-profiler' ); ?></div>
541
  <div class="p3-callout-data">
542
+ <?php if ( null === self::$profile ) { ?>
543
+ <span class="p3-faded-grey"><?php _e( 'n/a', 'p3-profiler' ); ?></span>
544
  <?php } else { ?>
545
+ <?php printf( '%.1f%%', self::$profile->averages['plugin_impact'] ); ?>
546
  <?php } ?>
547
  </div>
548
+ <div class="p3-callout-caption">(<?php _e( 'of page load time', 'p3-profiler' ); ?>)</div>
549
  </div>
550
  </div>
551
  </td>
552
 
553
  <!-- Fourth callout cell -->
554
  <td class="p3-callout">
555
+ <div class="p3-callout-outer-wrapper qtip-tip" title="<?php esc_attr_e( 'Total number of database queries per visit', 'p3-profiler' ); ?>"
556
+ <?php if ( !empty( self::$scan ) ) { ?>title="<?php esc_attr_e( 'From', 'p3-profiler' ); ?> <?php echo basename( self::$scan ); ?><?php } ?>">
557
  <div class="p3-callout-inner-wrapper">
558
+ <div class="p3-callout-caption"><?php _e( 'MySQL Queries', 'p3-profiler' ); ?></div>
559
  <div class="p3-callout-data">
560
+ <?php if ( null === self::$profile ) { ?>
561
+ <span class="p3-faded-grey"><?php _e( 'n/a', 'p3-profiler' ); ?></span>
562
  <?php } else { ?>
563
+ <?php echo round( self::$profile->averages['queries'] ); ?>
564
  <?php } ?>
565
  </div>
566
+ <div class="p3-callout-caption"><?php _e( 'per visit', 'p3-profiler' ); ?></div>
567
  </div>
568
  </div>
569
  </td>
574
  <!-- Dialog for IP settings -->
575
  <div id="p3-ip-dialog" class="p3-dialog">
576
  <div>
577
+ <?php _e( 'IP address or pattern:', 'p3-profiler' ); ?><br /><br />
578
+ <input type="checkbox" id="p3-use-current-ip" <?php if ( true == $opts['use_current_ip'] ) : ?>checked="checked"<?php endif; ?> />
579
+ <label for="p3-use-current-ip"><?php _e( 'Use my IP address', 'p3-profiler' ); ?></label>
580
  <br />
581
+ <input type="text" id="p3-advanced-ip" style="width:90%;" size="35" value="" title="<?php esc_attr_e( 'Enter IP address or regular expression pattern', 'p3-profiler' ); ?>" />
582
  <br />
583
+ <em class="p3-em"><?php _e( 'Example: 1.2.3.4 or ( 1.2.3.4|4.5.6.7 )', 'p3-profiler' ); ?></em>
584
  </div>
585
  <br />
586
  <div>
587
+ <input type="checkbox" id="p3-disable-opcode-cache" <?php if ( true == $opts['disable_opcode_cache'] ) : ?>checked="checked"<?php endif; ?> />
588
+ <label for="p3-disable-opcode-cache"><?php _e( 'Attempt to disable opcode optimizers', 'p3-profiler' ); ?> <em>(<?php _e( 'recommended', 'p3-profiler' ); ?>)</em></label>
589
  <br />
590
+ <em class="p3-em"><?php _e( 'This can increase accuracy in plugin detection, but decrease accuracy in timing', 'p3-profiler' ); ?></em>
591
  </div>
592
  <br />
593
  <div>
594
+ <input type="checkbox" id="p3-cache-buster" <?php if ( true == $opts['cache_buster'] ) : ?>checked="checked"<?php endif; ?> />
595
+ <label for="p3-cache-buster"><?php _e( 'Attempt to circumvent browser cache', 'p3-profiler' ); ?></label>
596
  <br />
597
+ <em class="p3-em"><?php printf( __('This may help fix a "No visits recorded" error message. See the <a href="%s">help</a> page for details.', 'p3-profiler' ),
598
+ add_query_arg( array( 'p3_action' => 'help', 'current_scan' => null ) ) . '#q-debug-log'
599
+ ); ?> </em>
600
  </div>
601
  <br />
602
  <div>
603
+ <input type="checkbox" id="p3-debug" <?php if ( true == $opts['debug'] ) : ?>checked="checked"<?php endif; ?> />
604
+ <label for="p3-debug"><?php _e( 'Debug mode', 'p3-profiler' ); ?></label>
605
  <br />
606
+ <em class="p3-em"><?php printf( __('This will log the last 100 visits. Check the <a href="%s">help</a> page to view log messages.', 'p3-profiler' ),
607
+ add_query_arg( array( 'p3_action' => 'help', 'current_scan' => null ) ) . '#q-debug-log'
608
+ ); ?></em>
609
  </div>
610
  </div>
611
 
615
  data-defaultsrc="<?php echo ( true === force_ssl_admin() ? str_replace( 'http://', 'https://', home_url() ) : home_url() ); ?>">
616
  </iframe>
617
  <div id="p3-scan-caption">
618
+ <?php _e( 'The scanner will analyze the speed and resource usage of all active plugins on your website. It may take several minutes, and this window must remain open for the scan to finish successfully.', 'p3-profiler' ); ?>
 
619
  </div>
620
  <div id="p3-manual-scan-caption" style="display: none;">
621
  <table>
622
  <tr>
623
  <td>
624
+ <?php _e( 'Click the links and pages of your site, and the scanner will analyze the speed and resource usage of all of your active plugins.', 'p3-profiler' ); ?>
 
 
625
  </td>
626
  <td width="220">
627
+ <a href="javascript:;" id="p3-manual-scan-cancel"><?php _e( 'Cancel', 'p3-profiler' ); ?></a>
628
  &nbsp;&nbsp;&nbsp;
629
  <span class="p3-big-button">
630
  <input type="checkbox" id="p3-manual-scan-done-submit" checked="checked" />
631
+ <label for="p3-manual-scan-done-submit"><?php _e( "I'm Done", 'p3-profiler' ); ?></label>
632
  </span>
633
  </td>
634
  </tr>
638
 
639
  <!-- Dialog for choose manual or auto scan -->
640
  <div id="p3-scan-name-dialog" class="p3-dialog">
641
+ <div style="padding-top: 10px;"><?php _e( 'Scan name:', 'p3-profiler' ); ?>
642
+ <input type="text" name="p3_scan_name" id="p3-scan-name" title="<?php esc_attr_e( 'Enter scan name here', 'p3-profiler' ); ?>"
643
  value="scan_<?php echo date( 'Y-m-d' ); ?>_<?php echo substr( md5( uniqid() ), -8 );?>" size="35" maxlength="100" />
644
  </div>
645
+ <div style="padding-top: 10px;"><em class="p3-em"><?php _e( 'Enter the name of a previous scan to continue scanning', 'p3-profiler' ); ?></em></div>
646
  <br />
647
  <div class="p3-big-button">
648
+ <input type="checkbox" id="p3-auto-scan-submit" checked="checked" /><label for="p3-auto-scan-submit"><?php _e( 'Auto Scan' , 'p3-profiler' ); ?></label>
649
+ <input type="checkbox" id="p3-manual-scan-submit" checked="checked" /><label for="p3-manual-scan-submit"><?php _e( 'Manual Scan', 'p3-profiler' ); ?></label>
650
  </div>
651
  </div>
652
 
653
  <!-- Dialog for progress bar -->
654
  <div id="p3-progress-dialog" class="p3-dialog">
655
  <div id="p3-scanning-caption">
656
+ <?php _e( 'Scanning ...', 'p3-profiler' ); ?>
657
  </div>
658
  <div id="p3-progress"></div>
659
 
660
  <!-- Cancel button -->
661
  <div class="p3-big-button" id="p3-cancel-scan-buttonset">
662
+ <input type="checkbox" id="p3-cancel-scan-submit" checked="checked" /><label for="p3-cancel-scan-submit"><?php _e( 'Stop Scan', 'p3-profiler' ); ?></label>
663
  </div>
664
 
665
  <!-- View / resume buttons -->
666
  <div class="p3-big-button" id="p3-resume-scan-buttonset" style="display: none;">
667
+ <input type="checkbox" id="p3-resume-scan-submit" checked="checked" /><label for="p3-resume-scan-submit"><?php _e( 'Resume', 'p3-profiler' ); ?></label>
668
  <input type="checkbox" id="p3-view-incomplete-results-submit" checked="checked" data-scan-name="" />
669
+ <label for="p3-view-incomplete-results-submit"><?php _e( 'View Results', 'p3-profiler' ); ?></label>
670
  </div>
671
 
672
  <!-- View results button -->
673
  <div class="p3-big-button" id="p3-view-results-buttonset" style="display: none;">
674
  <input type="checkbox" id="p3-view-results-submit" checked="checked" data-scan-name="" />
675
+ <label for="p3-view-results-submit"><?php _e( 'View Results', 'p3-profiler' ); ?></label>
676
  </div>
677
  </div>
templates/help.php CHANGED
@@ -7,10 +7,10 @@ if ( !defined('P3_PATH') )
7
  jQuery( document ).ready( function( $) {
8
  $( "#toggle-glossary" ).click( function() {
9
  $( "#glossary-terms" ).toggle();
10
- if ( "Hide Glossary" == $( "#toggle-glossary" ).html() ) {
11
- $( "#toggle-glossary" ).html( "Show Glossary" );
12
  } else {
13
- $( "#toggle-glossary" ).html( "Hide Glossary" );
14
  }
15
  });
16
  $( "#glossary-terms td.term" ).click( function() {
@@ -21,30 +21,30 @@ if ( !defined('P3_PATH') )
21
  });
22
  $( "#p3-glossary-table td.term:first" ).click();
23
  $( "#p3-hide-glossary" ).click( function() {
24
- if ( "Hide" == $( this ).html() ) {
25
  $( "#p3-glossary-table tbody" ).hide();
26
  $( "#p3-glossary-table tfoot" ).hide();
27
- $( this ).html( "Show" );
28
  } else {
29
  $( "#p3-glossary-table tbody" ).show();
30
  $( "#p3-glossary-table tfoot" ).show();
31
- $( this ).html( "Hide" );
32
  }
33
  });
34
 
35
 
36
  // Debug log
37
  $( "#p3-hide-debug-log" ).click( function() {
38
- if ( "Hide" == $( this ).html() ) {
39
  $( "#p3-debug-log-table thead" ).hide();
40
  $( "#p3-debug-log-table tbody" ).hide();
41
  $( "#p3-debug-log-table tfoot" ).hide();
42
- $( this ).html( "Show" );
43
  } else {
44
  $( "#p3-debug-log-table thead" ).show();
45
  $( "#p3-debug-log-table tbody" ).show();
46
  $( "#p3-debug-log-table tfoot" ).show();
47
- $( this ).html( "Hide" );
48
  }
49
  });
50
  $( "#p3-debug-log-container table tbody tr:even ").addClass( "even" );
@@ -64,7 +64,7 @@ if ( !defined('P3_PATH') )
64
  }
65
  });
66
  $( "div.p3-question blockquote:not(:first )" ).each( function() {
67
- $( this ).after( '<a href="#top">Back to top</a>' );
68
  });
69
  $( "#p3-help-toc" ).html( "<ul>" + links.join( "\n" ) + "</ul>" );
70
 
@@ -74,7 +74,7 @@ if ( !defined('P3_PATH') )
74
 
75
  <div class="p3-question">
76
  <a name="top">&nbsp;</a>
77
- <h2 class="p3-help-question">Contents</h2>
78
  <blockquote>
79
  <div id="p3-help-toc"></div>
80
  </blockquote>
@@ -82,216 +82,209 @@ if ( !defined('P3_PATH') )
82
 
83
 
84
  <div class="p3-question">
85
- <h2 class="p3-help-question">What does the P3 plugin do?</h2>
86
  <blockquote>
87
- This plugin does just what its name says, it creates a profile of your WordPress site's plugins' performance
88
- by measuring their impact on your site's load time.
89
- <br /><br />
90
- Often times, WordPress sites load slowly because of poorly-configured plugins or because there are so many of
91
- them. This plugin can help you narrow down the cause of your site's slowness.
92
  </blockquote>
93
  </div>
94
 
95
  <div class="p3-question">
96
- <h2 class="p3-help-question">How do I use this?</h2>
97
  <blockquote>
98
- Simply click "Start Scan" to run an automated scan of your site. The scanner generates some traffic on your
99
- site and monitors your site's performance on the server, then shows you the results. With this information,
100
- you can decide what action to take.
101
  </blockquote>
102
  </div>
103
 
104
  <div class="p3-question">
105
- <h2 class="p3-help-question">What do I do with these results?</h2>
106
  <blockquote>
107
- If your site loads in an acceptable time (usually &lt; 0.5 seconds), you might consider other explanation for
108
- sluggish loading. For example, loading large images, large videos, or a lot of content can cause slowness.
109
- Tools like <a href="http://www.webpagetest.org/" target="_blank">webpagetest.org</a>, <a href="http://getfirebug.com/"
110
- target="_blank">Firebug</a>, <a href="http://tools.pingdom.com/" target="_blank">Pingdom tools</a>, or
111
- <a href="http://developer.apple.com/technologies/safari/developer-tools.html" target="_blank">Safari Developer Tools</a>
112
- or <a href="http://code.google.com/chrome/devtools/docs/overview.html" target="_blank">Chrome Developer Tools</a> can
113
- show you a connection breakdown of your site's content.
114
  </blockquote>
115
  </div>
116
 
117
  <div class="p3-question">
118
- <h2 class="p3-help-question" data-question-id="q-circumvent-cache">How do I fix "No visits recorded..." ?</h2>
119
  <blockquote>
120
- This error message means that after being disabled, the profiler did not record any traffic on your site. There are several common
121
- causes for this:
122
  <ul>
123
  <li>
124
- <strong>Cause:</strong> Your site is using a caching plugin. The pages that are being scanned aren't actually loading on
125
- the server because they're cached in your browser or on the server before WordPress can generate them. The P3 plugin doesn't
126
- load and doesn't record any traffic.
127
  <br />
128
- <strong>Solution:</strong> Enable the "Attempt to circumvent browser cache" option in the advanced settings.
 
129
  </li>
130
  <li>
131
- <strong>Cause:</strong> The IP address you've entered in the advanced settings dialog doesn't match the IP address you're
132
- scanning from.
133
  <br />
134
- <strong>Solution:</strong> Check the IP address you've entered and try again.
 
135
  </li>
136
  <li>
137
- <strong>Cause:</strong> You've selected a manual scan, but haven't generated any traffic.
 
138
  <br />
139
- <strong>Solution:</strong> Try the automated scan.
 
140
  </li>
141
  </ul>
142
  </blockquote>
143
  </div>
144
 
145
  <div class="p3-question">
146
- <h2 class="p3-help-question">Why did P3 only record 2 or 3 visits during the scan?</h2>
147
  <blockquote>
148
- If your site is using a caching plugin, some pages might be cached in your browser or on the server and are loading before before WordPress
149
- can generate them. When this happens, the P3 plugin doesn't load and doesn't record any traffic. Please enable the "Attempt to circumvent
150
- browser cache" option in the advanced settings.
151
  </blockquote>
152
  </div>
153
 
154
  <div class="p3-question">
155
- <h2 class="p3-help-question">How does this work?</h2>
156
  <blockquote>
157
- When you activate the plugin by clicking "Start Scan," it detects visits from your IP address, and actively monitors
158
- all <a href="http://php.net/functions" target="_blank">php user defined function calls</a> while the server generates
159
- your WordPress pages. It then records the information in a report file you can view later. When the scan is complete,
160
- or you click "Stop Scan," the plugin becomes dormant again.
161
  </blockquote>
162
  </div>
163
 
164
  <div class="p3-question">
165
- <h2 class="p3-help-question">How does my site load the plugin?</h2>
166
  <blockquote>
167
- This plugin automatically creates a <a href="http://codex.wordpress.org/Must_Use_Plugins" target="_blank">must-use</a>
168
- plugin to load before other plugins. If that doesn't work, it runs like a regular plugin.
 
169
  <br /><br />
170
- You are currently using:
171
- <?php
172
- // must-use plugin file
173
- $mu_file = WPMU_PLUGIN_DIR . '/p3-profiler.php';
174
- ?>
175
- <?php /* must-use plugin file is there and not-empty */ ?>
176
- <?php if ( file_exists( $mu_file ) && filesize( $mu_file ) > 0 ){ ?>
177
- <a href="http://codex.wordpress.org/Must_Use_Plugins" target="_blank">must-use plugin</a>
178
- - <code><?php echo realpath( $mu_file ); ?></code>
179
- <?php /* default, using this plugin file */ ?>
180
- <?php } else { ?>
181
- <a href="http://codex.wordpress.org/Plugins" target="_blank">plugin</a>
182
- - <code><?php echo realpath( P3_PATH . '/p3-profiler.php' ); ?></code>
183
- <?php } ?>
184
  </blockquote>
185
  </div>
186
 
187
  <div class="p3-question">
188
- <h2 class="p3-help-question">How accurate are these results?</h2>
189
  <blockquote>
190
- The results have an inherent margin of error because of the nature of the tool and its multi-layered design.
191
- The plugin changes the environment to measure it, and that makes it impossible to get completely accurate results.
192
- <br /><br />
193
- It gets really close, though! The "margin of error" on the Advanced Metrics page displays the discrepancy between
194
- the measured results (the time for your site's PHP code to completely run) and the expected results (sum of the plugins,
195
- core, theme, profile load times) to show you the plugin's accuracy.
196
- <br /><br />
197
- If you want more accurate results, you'll need to resort to a different profiler like <a href="http://xdebug.org/" target="_blank">xdebug</a>,
198
- but this will not break down results by plugin.
199
  </blockquote>
200
  </div>
201
 
202
  <div class="p3-question">
203
- <h2 class="p3-help-question">Why are some plugins slow?</h2>
204
  <blockquote>
205
- WordPress is a complex ecosystem of plugins and themes, and it lives on a complex ecosystem of software on your web server.
206
- <br /><br />
207
- If a plugin runs slowly just once, it's probably an anomaly, a transient hiccup, and you can safely ignore it.
208
- <br /><br />
209
- If a plugin shows slowness once on a reguarly basis (e.g. every time you run a scan, once a day, once an hour), a scheduled
210
- task might be causing it. Plugins that backup your site, monitor your site for changes, contact outside sources (e.g. RSS feeds),
211
- warm up caches, etc. can exhibit this kind of behavior.
212
- <br /><br />
213
- If a plugin shows as fast-slow-fast-slow-fast-slow, it could be caused as the plugin loads its main code, then a follow-up piece
214
- of code, like a piece of generated JavaScript.
215
- <br /><br />
216
- If a plugin consistently shows slowness, you might want to contact the plugin author or try deactivating the plugin temporarily
217
- to see if it makes a difference on your site.
218
  </blockquote>
219
  </div>
220
 
221
  <div class="p3-question">
222
- <h2 class="p3-help-question">How are these results different from YSlow / PageSpeed / Webpagetest.org / Pingdom Tools?</h2>
223
  <blockquote>
224
- This plugin measures how your site was generated on the server. Tools like <a href="http://developer.yahoo.com/yslow/"
225
- target="_blank">YSlow</a>, <a href="https://developers.google.com/pagespeed/" target="_blank">PageSpeed</a>,
226
- <a href="http://www.webpagetest.org/" target="_blank">Webpagetest.org</a>, and <a href="http://tools.pingdom.com/fpt/"
227
- target="_blank">Pingdom Tools</a> measure how your site looks to the browser.
 
 
228
  </blockquote>
229
  </div>
230
 
231
  <div class="p3-question">
232
- <h2 class="p3-help-question">What can interfere with testing?</h2>
233
  <blockquote>
234
- Opcode optimizers can interfere with PHP backtraces. Leaving opcode optimizers turned on will result in timing that more accurately
235
- reflects your site's real performance, but the function calls to plugins may be "optimized" out of the backtraces and some
236
- plugins (especially those with only one hook) might not show up. Disabling opcode caches results in slower times, but shows all plugins.
237
- <br /><br />
238
- By default, this plugin attempts to disable any detected opcode optimizers when it runs. You can change this setting by clicking "Advanced
239
- Settings" under "Start Scan."
240
- <br /><br />
241
- Caching plugins that have an option to disable caches for logged in users will not give you the same performance profile that
242
- an anonymous users experience. To get around this, you should select a manual scan, then run an incognito browser window, or run
243
- another browser, and browse your site as a logged out user. When you're finished, click "I'm done," and your scan should show the
244
- performance of an anonymous user.
245
  </blockquote>
246
  </div>
247
 
248
  <div class="p3-question">
249
- <h2 class="p3-help-question" data-question-id="q-opcode-optimizer">Is my site using an opcode optimizer?</h2>
250
  <blockquote>
251
  <?php $detected = 0; if ( extension_loaded( 'xcache' ) ) { $detected++; ?>
252
- Your site is using XCache. Although XCache reports that no opcode optimization won't be implemented until
253
- version 2.0, this has been known to cause problems with P3.<br />
254
  <?php } ?>
255
  <?php if ( extension_loaded( 'apc' ) ) { $detected++; ?>
256
- Your site is using APC. This has not been known to cause problems with P3.<br />
 
257
  <?php } ?>
258
  <?php if ( extension_loaded( 'eaccelerator' ) && ini_get( 'eaccelerator.optimizer' ) ) { $detected++; ?>
259
- Your site is using eaccelerator with optimization enabled. This has been known to cause problems with P3. To temporarily
260
- disable the optimizer
261
  <?php if ( 'apache2handler' == strtolower( php_sapi_name() ) ) { ?>
262
- you can add <code>php_flag eaccelerator.optimizer Off</code> to your site's .htaccess file.
263
  <?php } elseif ( version_compare( PHP_VERSION, '5.3.0' ) >= 0 ) { ?>
264
- you can add <code>eaccelerator.optimizer = 0</code> to your site's <a href="http://php.net/manual/en/configuration.file.per-user.php" target="_blank"><?php echo ini_get( 'user_ini.filename' ); ?> file</a>.
 
 
 
265
  <?php } else { ?>
266
- you can ask your hosting provider.
267
  <?php } ?>
268
  <br />
269
  <?php } ?>
270
  <?php if ( extension_loaded( 'Zend Optimizer+' ) && ini_get( 'zend_optimizerplus.optimization_level' ) > 0 ) { $detected++; ?>
271
- Your site is using Zend Optimizer+. This has not been known to cause problems with P3.<br />
 
272
  <?php } ?>
273
  <?php if ( extension_loaded( 'IonCube Loader' ) ) { $detected++; ?>
274
- Your site is using the IonCube loader. This has not been known to cause problems with P3. <br />
 
275
  <?php } ?>
276
  <?php if ( extension_loaded( 'wincache' ) ) { $detected++; ?>
277
- Your site is using wincache. This has not been known to cause problems with P3. <br />
 
278
  <?php } ?>
279
  <?php if ( extension_loaded( 'Zend Guard Loader' ) ) { $detected++; ?>
280
- Your site is using the Zend Guard loader. This has not been known to cause problems with P3. <br />
 
281
  <?php } ?>
282
  <?php if ( extension_loaded( 'Zend Optimizer' ) ) { $detected++; ?>
283
- Your site is using the Zend Optimizer. This extension has not been tested with P3. Please report any problems.<br />
 
284
  <?php } ?>
285
  <?php if ( !$detected ) { ?>
286
- P3 has not detected any opcode optimizers on your site. Although none were detected, an opcode optimizer may still be present.
287
- Contact your server administrator with any questions.
288
  <?php } ?>
289
  </blockquote>
290
  </div>
291
 
292
 
293
  <div class="p3-question">
294
- <h2 class="p3-help-question">How much room do these profiles take up on my server</h2>
295
  <blockquote>
296
  <?php
297
  $total_size = 0;
@@ -304,95 +297,81 @@ if ( !defined('P3_PATH') )
304
  closedir( $dir );
305
 
306
  ?>
307
- The scans are stored in <code><?php echo realpath( P3_PROFILES_PATH ); ?></code> and
308
- take up <?php echo $this->readable_size( $total_size ); ?> of disk space. Each time you
309
- run a scan, this storage requirement goes up, and each time you delete a scan, it
310
- goes down.
311
  </blockquote>
312
  </div>
313
 
314
  <div class="p3-question">
315
- <h2 class="p3-help-question">Is this plugin always running?</h2>
316
  <blockquote>
317
- The short answer is no.
318
- <br /><br />
319
- The more detailed answer is the loader is always running, but checks very early in the page
320
- loading process to see if you've enabled profiling mode and if the user's IP address matches
321
- the IP address the plugin is monitoring. For multisite installations, it also matches the site URL.
322
- If all these match, the plugin becomes active and profiles. Otherwise, your site loads as normal
323
- with no other code overhead.
324
- <br /><br />
325
- Deactivating the plugin ensures it's not running at all, and does not delete your scans. However,
326
- uninstalling the plugin does delete your scans.
327
  </blockquote>
328
  </div>
329
 
330
  <div class="p3-question">
331
- <h2 class="p3-help-question">How can I test specific pages on my site?</h2>
332
  <blockquote>
333
- When you start a scan, choose "Manual Scan" and then you can visit specific links on your site that
334
- you want to profile. If you want to profile the admin section, just click the "X" in the top right
335
- of the scan window and you'll be returned to your admin section. You can browse as normal, then come
336
- back to the profile page and click "Stop Scan" when you're ready to view the results.
337
- <br /><br />
338
- To scan your site as an anonymous user, select "Manual Mode" as above, but instead of clicking your
339
- site in the scan window, open a different browser (or an incognito window) and browse your site as a
340
- logged out user. When you're done, close that browser and return to your admin. Click "I'm done" and
341
- view your scan results.
342
  </blockquote>
343
  </div>
344
 
345
  <div class="p3-question">
346
- <h2 class="p3-help-question">My plugins don't seem to cause site slowness. Why is my site still slow?</h2>
347
  <blockquote>
348
- Your site can be slow for a number of reasons. Your site could have a lot of traffic, other sites on
349
- your server could have a lot of traffic, you could be referencing content from other sites that are slow,
350
- your Internet connection could be slow, your server could be out of RAM, your site could be very image
351
- heavy, your site could require a lot of HTTP requests, etc. In short, a lot of factors can cause slowness
352
- on your site
353
- <br /><br />
354
- Your next stop should be to use <a href="http://tools.pingdom.com/" target="_blank">Pingdom Tools</a>,
355
- <a href="http://webpagetest.org/" target="_blank">Webpage Test</a>, <a href="http://developer.yahoo.com/yslow/"
356
- target="_blank">YSlow</a>, <a href="https://developers.google.com/pagespeed/" target="_blank">Google PageSpeed</a>,
357
- and your browser's development tools like <a href="http://getfirebug.com/" target="_blank">Firebug</a> for Firefox,
358
- <a href="http://code.google.com/chrome/devtools/docs/overview.html" target="_blank">Chrome Developer Tools</a> for
359
- Chrome, or <a href="http://developer.apple.com/technologies/safari/developer-tools.html" target="_blank">Safari
360
- Developer Tools</a> for Safari.
361
- <br /><br />
362
- After you've tuned your site up as much as possible, if you're still not happy with its performance, you should
363
- consult your site/server administrator or hosting support.
364
  </blockquote>
365
  </div>
366
 
367
  <div class="p3-question">
368
- <h2 class="p3-help-question" data-question-id="q-debug-log">Where can I view the debug log?</h2>
369
  <blockquote>
370
- Debug mode will record 100 visits to your site, then turn off automatically. You can view the log below. The entries
371
- are shown in reverse order with the latest visits appearing at the top of the list. You can also
372
- <a href="<?php echo wp_nonce_url( add_query_arg( array( 'p3_action' => 'clear-debug-log' ) ), 'p3-clear-debug-log' ) ; ?>" class="button-secondary">Clear the log</a> or
373
- <a href="<?php echo wp_nonce_url( add_query_arg( array( 'p3_action' => 'download-debug-log' ) ), 'p3-download-debug-log' ) ; ?>" class="button-secondary">Download the log</a> as a CSV.
374
  <br /><br />
375
  <div id="p3-debug-log-container">
376
  <div class="ui-widget-header" id="p3-debug-log-header" style="padding: 8px;">
377
- <strong>Debug Log</strong>
378
  <div style="position: relative; top: 0px; right: 80px; float: right;">
379
- <a href="javascript:;" id="p3-hide-debug-log">Hide</a>
380
  </div>
381
  </div>
382
  <div>
383
  <table class="p3-results-table" id="p3-debug-log-table" cellpadding="0" cellspacing="0" border="0">
384
  <thead>
385
  <tr>
386
- <td><strong>#</strong></td>
387
- <td><strong>Profiling Enabled</strong></td>
388
- <td><strong>Recording IP</strong></td>
389
- <td><strong>Scan Name</strong></td>
390
- <td><strong>Recording</strong></td>
391
- <td><strong>Disable Optimizers</strong></td>
392
- <td><strong>URL</strong></td>
393
- <td><strong>Visitor IP</strong></td>
394
- <td><strong>Time</strong></td>
395
- <td><strong>PID</strong></td>
396
  </tr>
397
  </thead>
398
  <tbody>
@@ -423,16 +402,16 @@ if ( !defined('P3_PATH') )
423
  </tbody>
424
  <tfoot>
425
  <tr>
426
- <td><strong>#</strong></td>
427
- <td><strong>Profiling Enabled</strong></td>
428
- <td><strong>Recording IP</strong></td>
429
- <td><strong>Scan Name</strong></td>
430
- <td><strong>Recording</strong></td>
431
- <td><strong>Disable Optimizers</strong></td>
432
- <td><strong>URL</strong></td>
433
- <td><strong>Visitor IP</strong></td>
434
- <td><strong>Time</strong></td>
435
- <td><strong>PID</strong></td>
436
  </tr>
437
  </tfoot>
438
  </table>
@@ -442,35 +421,33 @@ if ( !defined('P3_PATH') )
442
  </div>
443
 
444
  <div class="p3-question">
445
- <h2 class="p3-help-question">What if I get a warning about usort()?</h2>
446
  <blockquote>
447
- Warning messages like this:
448
- <code>Warning: usort() [function.usort]: Array was modified by the user comparison function</code> are due
449
- to a known php bug. See <a href="https://bugs.php.net/bug.php?id=50688" target="_blank">php bug #50688</a>
450
- for more information. This warning does not affect the functionality of your site and it is not visible
451
- to your users.
452
  </blockquote>
453
  </div>
454
 
455
  <div class="p3-question">
456
- <h2 class="p3-help-question">Does this plugin increase memory usage on my site?</h2>
457
  <blockquote>
458
- When you run a performance scan on your site, the memory requirements go up during the scan. Accordingly, P3 sets your
459
- <a href="http://www.php.net/manual/en/ini.core.php#ini.memory-limit" target="_blank">memory limit</a> to 128
460
- MB and <a href="http://php.net/set_time_limit" target="_blank">request timeout</a> to 90 seconds during a
461
- performance scan. These changes are not permanent and are only in effect when a performance scan is actively running.
462
  </blockquote>
463
  </div>
464
 
465
  <div class="p3-question">
466
- <h2 class="p3-help-question" style="border-bottom-width: 0px !important;">Glossary</h2>
467
  <blockquote>
468
  <div>
469
  <div id="p3-glossary-container">
470
  <div class="ui-widget-header" id="p3-glossary-header" style="padding: 8px;">
471
- <strong>Glossary</strong>
472
  <div style="position: relative; top: 0px; right: 80px; float: right;">
473
- <a href="javascript:;" id="p3-hide-glossary">Hide</a>
474
  </div>
475
  </div>
476
  <div>
@@ -481,113 +458,95 @@ if ( !defined('P3_PATH') )
481
  <div id="glossary">
482
  <table width="100%" cellpadding="0" cellspacing="0" border="0" id="glossary-terms">
483
  <tr>
484
- <td width="200" class="term"><strong>Total Load Time</strong>
485
  <div id="total-load-time-definition" style="display: none;" class="definition">
486
- The length of time the site took to load. This is an observed measurement (start timing when
487
- the page was requested, stop timing when the page was delivered to the browser, calculate the
488
- difference). Lower is better.
489
  </div>
490
  </td>
491
  <td width="400" rowspan="12" id="p3-glossary-term-display">&nbsp;</td>
492
  </tr>
493
  <tr>
494
- <td class="term"><strong>Site Load Time</strong>
495
  <div id="site-load-time-definition" style="display: none;" class="definition">
496
- The calculated total load time minus the profile overhead. This is closer to your site's
497
- real-life load time. Lower is better.
498
  </div>
499
  </td>
500
  </tr>
501
  <tr>
502
- <td class="term"><strong>Profile Overhead</strong>
503
  <div id="profile-overhead-definition" style="display: none;" class="definition">
504
- The load time spent profiling code. Because the profiler slows down your load time, it is
505
- important to know how much impact the profiler has. However, it doesn't impact your site's
506
- real-life load time.
507
  </div>
508
  </td>
509
  </tr>
510
  <tr>
511
- <td class="term"><strong>Plugin Load Time</strong>
512
  <div id="plugin-load-time-definition" style="display: none;" class="definition">
513
- The load time caused by plugins. Because of WordPress' construction, we can trace a
514
- function call from a plugin through a theme through the core. The profiler prioritizes
515
- plugin calls first, theme calls second, and core calls last. Lower is better.
516
  </div>
517
  </td>
518
  </tr>
519
  <tr>
520
- <td class="term"><strong>Theme Load Time</strong>
521
  <div id="theme-load-time-definition" style="display: none;" class="definition">
522
- The load time spent applying the theme. Because of WordPress' construction, we can trace a
523
- function call from a plugin through a theme through the core. The profiler prioritizes
524
- plugin calls first, theme calls second, and core calls last. Lower is better.
525
  </div>
526
  </td>
527
  </tr>
528
  <tr>
529
- <td class="term"><strong>Core Load Time</strong>
530
  <div id="core-load-time-definition" style="display: none;" class="definition">
531
- The load time caused by the WordPress core. Because of WordPress' construction, we can trace
532
- a function call from a plugin through a theme through the core. The profiler prioritizes
533
- plugin calls first, theme calls second, and core calls last. This will probably be constant.
534
  </div>
535
  </td>
536
  </tr>
537
  <tr>
538
- <td class="term"><strong>Margin of Error</strong>
539
  <div id="drift-definition" style="display: none;" class="definition">
540
- This is the difference between the observed runtime (what actually happened) and expected
541
- runtime (adding the plugin runtime, theme runtime, core runtime, and profiler overhead).
542
- <br /><br />
543
- There are several reasons this margin of error can exist. Most likely, the profiler is
544
- missing microseconds while adding the runtime it observed. Using a network clock to set the
545
- time (NTP) can also cause minute timing changes.
546
- <br /><br />
547
- Ideally, this number should be zero, but there's nothing you can do to change it. It
548
- will give you an idea of how accurate the other results are.
549
  </div>
550
  </td>
551
  </tr>
552
  <tr>
553
- <td class="term"><strong>Observed</strong>
554
  <div id="observed-definition" style="display: none;" class="definition">
555
- The time the site took to load. This is an observed measurement (start timing when the
556
- page was requested, stop timing when the page was delivered to the browser, calculate the
557
- difference).
558
  </div>
559
  </td>
560
  </tr>
561
  <tr>
562
- <td class="term"><strong>Expected</strong>
563
  <div id="expected-definition" style="display: none;" class="definition">
564
- The expected site load time calculated by adding plugin load time, core load time, theme
565
- load time, and profiler overhead.
566
  </div>
567
  </td>
568
  </tr>
569
  <tr>
570
- <td class="term"><strong>Plugin Function Calls</strong>
571
  <div id="plugin-funciton-calls-definition" style="display: none;" class="definition">
572
- The number of PHP function calls generated by a plugin. Fewer is better.
573
  </div>
574
  </td>
575
  </tr>
576
  <tr>
577
- <td class="term"><strong>Memory Usage</strong>
578
  <div id="memory-usage-definition" style="display: none;" class="definition">
579
- The amount of RAM usage observed. This is reported by
580
- <a href="http://php.net/memory_get_peak_usage"
581
- target="_blank">memory_get_peak_usage()</a>. Lower is better.
582
  </div>
583
  </td>
584
  </tr>
585
  <tr>
586
- <td class="term"><strong>MySQL Queries</strong>
587
  <div id="mysql-queries-definition" style="display: none;" class="definition">
588
- The number of queries sent to the database. This is reported by the WordPress function
589
- <a href="http://codex.wordpress.org/Function_Reference/get_num_queries"
590
- target="_new">get_num_queries()</a>. Fewer is better.
591
  </div>
592
  </td>
593
  </tr>
@@ -604,18 +563,17 @@ if ( !defined('P3_PATH') )
604
  </div>
605
 
606
  <div class="p3-question">
607
- <h2 class="p3-help-question">License</h2>
608
  <blockquote>
609
- <strong>P3 (Plugin Performance Profiler)</strong>
610
- <br />
611
- Copyright &copy; 2011-<?php echo date('Y'); ?> <a href="http://www.godaddy.com/" target="_blank">GoDaddy.com</a>. All rights reserved.
612
- <br /><br />
613
- This program is offered under the terms of the GNU General Public License Version 2 as published by the Free Software Foundation.
614
- <br /><br />
615
- This program offered WITHOUT WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
616
- See the GNU General Public License Version 2 for the specific terms.
617
  <br /><br />
618
- A copy of the GNU General Public License has been provided with this program. Alternatively, you may find a copy of the license here:
619
- <a href="http://www.gnu.org/licenses/gpl-2.0.html" target="_blank">http://www.gnu.org/licenses/gpl-2.0.html</a>.
 
 
 
 
 
 
620
  </blockquote>
621
  </div>
7
  jQuery( document ).ready( function( $) {
8
  $( "#toggle-glossary" ).click( function() {
9
  $( "#glossary-terms" ).toggle();
10
+ if ( "<?php _e( 'Hide Glossary', 'p3-profiler' ); ?>" == $( "#toggle-glossary" ).html() ) {
11
+ $( "#toggle-glossary" ).html( "<?php _e( 'Show Glossary', 'p3-profiler' ); ?>" );
12
  } else {
13
+ $( "#toggle-glossary" ).html( "<?php _e( 'Hide Glossary', 'p3-profiler' ); ?>" );
14
  }
15
  });
16
  $( "#glossary-terms td.term" ).click( function() {
21
  });
22
  $( "#p3-glossary-table td.term:first" ).click();
23
  $( "#p3-hide-glossary" ).click( function() {
24
+ if ( "<?php _e( 'Hide', 'p3-profiler' ); ?>" == $( this ).html() ) {
25
  $( "#p3-glossary-table tbody" ).hide();
26
  $( "#p3-glossary-table tfoot" ).hide();
27
+ $( this ).html( "<?php _e( 'Show', 'p3-profiler' ); ?>" );
28
  } else {
29
  $( "#p3-glossary-table tbody" ).show();
30
  $( "#p3-glossary-table tfoot" ).show();
31
+ $( this ).html( "<?php _e( 'Hide', 'p3-profiler' ); ?>" );
32
  }
33
  });
34
 
35
 
36
  // Debug log
37
  $( "#p3-hide-debug-log" ).click( function() {
38
+ if ( "<?php _e( 'Hide', 'p3-profiler' ); ?>" == $( this ).html() ) {
39
  $( "#p3-debug-log-table thead" ).hide();
40
  $( "#p3-debug-log-table tbody" ).hide();
41
  $( "#p3-debug-log-table tfoot" ).hide();
42
+ $( this ).html( "<?php _e( 'Show', 'p3-profiler' ); ?>" );
43
  } else {
44
  $( "#p3-debug-log-table thead" ).show();
45
  $( "#p3-debug-log-table tbody" ).show();
46
  $( "#p3-debug-log-table tfoot" ).show();
47
+ $( this ).html( "<?php _e( 'Hide', 'p3-profiler' ); ?>" );
48
  }
49
  });
50
  $( "#p3-debug-log-container table tbody tr:even ").addClass( "even" );
64
  }
65
  });
66
  $( "div.p3-question blockquote:not(:first )" ).each( function() {
67
+ $( this ).after( '<a href="#top"><?php _e( 'Back to top', 'p3-profiler' ); ?></a>' );
68
  });
69
  $( "#p3-help-toc" ).html( "<ul>" + links.join( "\n" ) + "</ul>" );
70
 
74
 
75
  <div class="p3-question">
76
  <a name="top">&nbsp;</a>
77
+ <h2 class="p3-help-question"><?php _e( 'Contents', 'p3-profiler' ); ?></h2>
78
  <blockquote>
79
  <div id="p3-help-toc"></div>
80
  </blockquote>
82
 
83
 
84
  <div class="p3-question">
85
+ <h2 class="p3-help-question"><?php _e( 'What does the P3 plugin do?', 'p3-profiler' ); ?></h2>
86
  <blockquote>
87
+ <?php _e( "This plugin does just what its name says, it creates a profile of your WordPress site's plugins' performance by measuring their impact on your site's load time.
88
+ <br /><br />
89
+ Often times, WordPress sites load slowly because of poorly-configured plugins or because there are so many of them. This plugin can help you narrow down the cause of your site's slowness.", 'p3-profiler' ); ?>
 
 
90
  </blockquote>
91
  </div>
92
 
93
  <div class="p3-question">
94
+ <h2 class="p3-help-question"><?php _e( 'How do I use this?', 'p3-profiler' ); ?></h2>
95
  <blockquote>
96
+ <?php _e( "Simply click \"Start Scan\" to run an automated scan of your site. The scanner generates some traffic on your site and monitors your site's performance on the server, then shows you the results. With this information, you can decide what action to take.", 'p3-profiler' ); ?>
 
 
97
  </blockquote>
98
  </div>
99
 
100
  <div class="p3-question">
101
+ <h2 class="p3-help-question"><?php _e( 'What do I do with these results?', 'p3-profiler' ); ?></h2>
102
  <blockquote>
103
+ <?php printf( __("If your site loads in an acceptable time (usually &lt; 0.5 seconds), you might consider other explanation for sluggish loading. For example, loading large images, large videos, or a lot of content can cause slowness. Tools like <a href=\"%1\$s\" target=\"_blank\">%2\$s</a>, <a href=\"%3\$s\" target=\"_blank\">%4\$s</a>, <a href=\"%5\$s\" target=\"_blank\">%6\$s</a>, or <a href=\"%7\$s\" target=\"_blank\">%8\$s</a> or <a href=\"%9\$s\" target=\"_blank\">%10\$s</a> can show you a connection breakdown of your site's content.", 'p3-profiler' ),
104
+ 'http://www.webpagetest.org/', __( 'webpagetest.org', 'p3-profiler' ),
105
+ 'http://getfirebug.com/', __( 'Firebug', 'p3-profiler' ),
106
+ 'http://tools.pingdom.com/', __( 'Pingdom tools', 'p3-profiler' ),
107
+ 'http://developer.apple.com/technologies/safari/developer-tools.html', __( 'Safari Developer Tools', 'p3-profiler' ),
108
+ 'http://code.google.com/chrome/devtools/docs/overview.html', __( 'Chrome Developer Tools', 'p3-profiler' )
109
+ ); ?>
110
  </blockquote>
111
  </div>
112
 
113
  <div class="p3-question">
114
+ <h2 class="p3-help-question" data-question-id="q-circumvent-cache"><?php _e( 'How do I fix "No visits recorded..." ?', 'p3-profiler' ); ?></h2>
115
  <blockquote>
116
+ <?php _e( 'This error message means that after being disabled, the profiler did not record any traffic on your site. There are several common causes for this:', 'p3-profiler' ); ?>
 
117
  <ul>
118
  <li>
119
+ <strong><?php _e( 'Cause:', 'p3-profiler' ); ?></strong>
120
+ <?php _e( "Your site is using a caching plugin. The pages that are being scanned aren't actually loading on the server because they're cached in your browser or on the server before WordPress can generate them. The P3 plugin doesn't load and doesn't record any traffic.", 'p3-profiler' ); ?>
 
121
  <br />
122
+ <strong><?php _e( 'Solution:', 'p3-profiler' ); ?></strong>
123
+ <?php _e( 'Enable the "Attempt to circumvent browser cache" option in the advanced settings.', 'p3-profiler' ); ?>
124
  </li>
125
  <li>
126
+ <strong><?php _e( 'Cause:', 'p3-profiler' ); ?></strong>
127
+ <?php _e( "The IP address you've entered in the advanced settings dialog doesn't match the IP address you're scanning from.", 'p3-profiler' ); ?>
128
  <br />
129
+ <strong><?php _e( 'Solution:', 'p3-profiler' ); ?></strong>
130
+ <?php _e( "Check the IP address you've entered and try again.", 'p3-profiler' ); ?>
131
  </li>
132
  <li>
133
+ <strong><?php _e( 'Cause:', 'p3-profiler' ); ?></strong>
134
+ <?php _e( "You've selected a manual scan, but haven't generated any traffic.", 'p3-profiler' ); ?>
135
  <br />
136
+ <strong><?php _e( 'Solution:', 'p3-profiler' ); ?></strong>
137
+ <?php _e( 'Try the automated scan.', 'p3-profiler' ); ?>
138
  </li>
139
  </ul>
140
  </blockquote>
141
  </div>
142
 
143
  <div class="p3-question">
144
+ <h2 class="p3-help-question"><?php _e( 'Why did P3 only record 2 or 3 visits during the scan?', 'p3-profiler' ); ?></h2>
145
  <blockquote>
146
+ <?php _e( "If your site is using a caching plugin, some pages might be cached in your browser or on the server and are loading before before WordPress can generate them. When this happens, the P3 plugin doesn't load and doesn't record any traffic. Please enable the \"Attempt to circumvent browser cache\" option in the advanced settings.", 'p3-profiler' ); ?>
 
 
147
  </blockquote>
148
  </div>
149
 
150
  <div class="p3-question">
151
+ <h2 class="p3-help-question"><?php _e( "How does this work?", 'p3-profiler' ); ?></h2>
152
  <blockquote>
153
+ <?php printf( __("When you activate the plugin by clicking \"Start Scan,\" it detects visits from your IP address, and actively monitors all <a href=\"%s\" target=\"_blank\">php user defined function calls</a> while the server generates your WordPress pages. It then records the information in a report file you can view later. When the scan is complete, or you click \"Stop Scan,\" the plugin becomes dormant again.", 'p3-profiler'),
154
+ 'http://php.net/functions'
155
+ ); ?>
 
156
  </blockquote>
157
  </div>
158
 
159
  <div class="p3-question">
160
+ <h2 class="p3-help-question"><?php _e( "How does my site load the plugin?", 'p3-profiler' ); ?></h2>
161
  <blockquote>
162
+ <?php printf( __("This plugin automatically creates a <a href=\"%s\" target=\"_blank\">must-use</a> plugin to load before other plugins. If that doesn't work, it runs like a regular plugin.", 'p3-profiler' ),
163
+ 'http://codex.wordpress.org/Must_Use_Plugins'
164
+ ); ?>
165
  <br /><br />
166
+ <?php _e( 'You are currently using:', 'p3-profiler' ); ?>
167
+ <?php
168
+ // must-use plugin file
169
+ $mu_file = WPMU_PLUGIN_DIR . '/p3-profiler.php';
170
+ ?>
171
+ <?php /* must-use plugin file is there and not-empty */ ?>
172
+ <?php if ( file_exists( $mu_file ) && filesize( $mu_file ) > 0 ){ ?>
173
+ <a href="http://codex.wordpress.org/Must_Use_Plugins" target="_blank"><?php _e( 'must-use plugin', 'p3-profiler' ); ?></a>
174
+ - <code><?php echo realpath( $mu_file ); ?></code>
175
+ <?php /* default, using this plugin file */ ?>
176
+ <?php } else { ?>
177
+ <a href="http://codex.wordpress.org/Plugins" target="_blank"><?php _e( 'plugin', 'p3-profiler' ); ?></a>
178
+ - <code><?php echo realpath( P3_PATH . '/p3-profiler.php' ); ?></code>
179
+ <?php } ?>
180
  </blockquote>
181
  </div>
182
 
183
  <div class="p3-question">
184
+ <h2 class="p3-help-question"><?php _e( "How accurate are these results?", 'p3-profiler' ); ?></h2>
185
  <blockquote>
186
+ <?php printf( __( "The results have an inherent margin of error because of the nature of the tool and its multi-layered design. The plugin changes the environment to measure it, and that makes it impossible to get completely accurate results.
187
+ <br /><br />
188
+ It gets really close, though! The \"margin of error\" on the Advanced Metrics page displays the discrepancy between the measured results (the time for your site's PHP code to completely run) and the expected results (sum of the plugins, core, theme, profile load times) to show you the plugin's accuracy.
189
+ <br /><br />
190
+ If you want more accurate results, you'll need to resort to a different profiler like <a href=\"%1\$s\" target=\"_blank\">%2\$s</a>, but this will not break down results by plugin.", 'p3-profiler' ),
191
+ 'http://xdebug.org/', __( 'xdebug', 'p3-profiler' )
192
+ ); ?>
 
 
193
  </blockquote>
194
  </div>
195
 
196
  <div class="p3-question">
197
+ <h2 class="p3-help-question"><?php _e( "Why are some plugins slow?", 'p3-profiler' ); ?></h2>
198
  <blockquote>
199
+ <?php _e( "WordPress is a complex ecosystem of plugins and themes, and it lives on a complex ecosystem of software on your web server.
200
+ <br /><br />
201
+ If a plugin runs slowly just once, it's probably an anomaly, a transient hiccup, and you can safely ignore it.
202
+ <br /><br />
203
+ If a plugin shows slowness once on a reguarly basis (e.g. every time you run a scan, once a day, once an hour), a scheduled task might be causing it. Plugins that backup your site, monitor your site for changes, contact outside sources (e.g. RSS feeds), warm up caches, etc. can exhibit this kind of behavior.
204
+ <br /><br />
205
+ If a plugin shows as fast-slow-fast-slow-fast-slow, it could be caused as the plugin loads its main code, then a follow-up piece of code, like a piece of generated JavaScript.
206
+ <br /><br />
207
+ If a plugin consistently shows slowness, you might want to contact the plugin author or try deactivating the plugin temporarily to see if it makes a difference on your site.", 'p3-profiler' ); ?>
 
 
 
 
208
  </blockquote>
209
  </div>
210
 
211
  <div class="p3-question">
212
+ <h2 class="p3-help-question"><?php _e( "How are these results different from YSlow / PageSpeed / Webpagetest.org / Pingdom Tools?", 'p3-profiler' ); ?></h2>
213
  <blockquote>
214
+ <?php printf( __("This plugin measures how your site was generated on the server. Tools like <a href=\"%1\$s\" target=\"_blank\">%2\$s</a>, <a href=\"%3\$s\" target=\"_blank\">%4\$s</a>, <a href=\"%5\$s\" target=\"_blank\">%6\$s</a>, and <a href=\"%7\$s\" target=\"_blank\">%8\$s</a> measure how your site looks to the browser.", 'p3-profiler'),
215
+ 'http://developer.yahoo.com/yslow/', __( 'YSlow', 'p3-profiler' ),
216
+ 'https://developers.google.com/pagespeed/', __( 'PageSpeed', 'p3-profiler' ),
217
+ 'http://www.webpagetest.org/', __( 'Webpagetest.org', 'p3-profiler' ),
218
+ 'http://tools.pingdom.com/fpt/', __( 'Pingdom Tools', 'p3-profiler' )
219
+ ); ?>
220
  </blockquote>
221
  </div>
222
 
223
  <div class="p3-question">
224
+ <h2 class="p3-help-question"><?php _e( "What can interfere with testing?", 'p3-profiler' ); ?></h2>
225
  <blockquote>
226
+ <?php _e( "Opcode optimizers can interfere with PHP backtraces. Leaving opcode optimizers turned on will result in timing that more accurately reflects your site's real performance, but the function calls to plugins may be \"optimized\" out of the backtraces and some plugins (especially those with only one hook) might not show up. Disabling opcode caches results in slower times, but shows all plugins.
227
+ <br /><br />
228
+ By default, this plugin attempts to disable any detected opcode optimizers when it runs. You can change this setting by clicking \"Advanced Settings\" under \"Start Scan.\"
229
+ <br /><br />
230
+ Caching plugins that have an option to disable caches for logged in users will not give you the same performance profile that an anonymous users experience. To get around this, you should select a manual scan, then run an incognito browser window, or run another browser, and browse your site as a logged out user. When you're finished, click \"I'm done,\" and your scan should show the performance of an anonymous user.", 'p3-profiler' ); ?>
 
 
 
 
 
 
231
  </blockquote>
232
  </div>
233
 
234
  <div class="p3-question">
235
+ <h2 class="p3-help-question" data-question-id="q-opcode-optimizer"><?php _e( "Is my site using an opcode optimizer?", 'p3-profiler' ); ?></h2>
236
  <blockquote>
237
  <?php $detected = 0; if ( extension_loaded( 'xcache' ) ) { $detected++; ?>
238
+ <?php _e( "Your site is using XCache. Although XCache reports that no opcode optimization won't be implemented until version 2.0, this has been known to cause problems with P3.", 'p3-profiler' ); ?>
239
+ <br />
240
  <?php } ?>
241
  <?php if ( extension_loaded( 'apc' ) ) { $detected++; ?>
242
+ <?php _e( "Your site is using APC. This has not been known to cause problems with P3.", 'p3-profiler' ); ?>
243
+ <br />
244
  <?php } ?>
245
  <?php if ( extension_loaded( 'eaccelerator' ) && ini_get( 'eaccelerator.optimizer' ) ) { $detected++; ?>
246
+ <?php _e( "Your site is using eaccelerator with optimization enabled. This has been known to cause problems with P3.", 'p3-profiler' ); ?>
 
247
  <?php if ( 'apache2handler' == strtolower( php_sapi_name() ) ) { ?>
248
+ <?php _e( "To temporarily disable the optimizer you can add <code>php_flag eaccelerator.optimizer Off</code> to your site's .htaccess file.", 'p3-profiler' ); ?>
249
  <?php } elseif ( version_compare( PHP_VERSION, '5.3.0' ) >= 0 ) { ?>
250
+ <?php printf( __( "To temporarily disable the optimizer you can add <code>eaccelerator.optimizer = 0</code> to your site's <a href=\"%1\$s\" target=\"_blank\">%2\$s file</a>.", 'p3-profiler' ),
251
+ 'http://php.net/manual/en/configuration.file.per-user.php',
252
+ ini_get( 'user_ini.filename' )
253
+ ); ?>
254
  <?php } else { ?>
255
+ <?php _e( "To temporarily disable the optimizer you can ask your hosting provider.", 'p3-profiler' ); ?>
256
  <?php } ?>
257
  <br />
258
  <?php } ?>
259
  <?php if ( extension_loaded( 'Zend Optimizer+' ) && ini_get( 'zend_optimizerplus.optimization_level' ) > 0 ) { $detected++; ?>
260
+ <?php _e( 'Your site is using Zend Optimizer+. This has not been known to cause problems with P3.', 'p3-profiler' ); ?>
261
+ <br />
262
  <?php } ?>
263
  <?php if ( extension_loaded( 'IonCube Loader' ) ) { $detected++; ?>
264
+ <?php _e( 'Your site is using the IonCube loader. This has not been known to cause problems with P3.', 'p3-profiler' ); ?>
265
+ <br />
266
  <?php } ?>
267
  <?php if ( extension_loaded( 'wincache' ) ) { $detected++; ?>
268
+ <?php _e( 'Your site is using wincache. This has not been known to cause problems with P3.', 'p3-profiler' ); ?>
269
+ <br />
270
  <?php } ?>
271
  <?php if ( extension_loaded( 'Zend Guard Loader' ) ) { $detected++; ?>
272
+ <?php _e( 'Your site is using the Zend Guard loader. This has not been known to cause problems with P3.', 'p3-profiler' ); ?>
273
+ <br />
274
  <?php } ?>
275
  <?php if ( extension_loaded( 'Zend Optimizer' ) ) { $detected++; ?>
276
+ <?php _e( 'Your site is using the Zend Optimizer. This extension has not been tested with P3. Please report any problems.', 'p3-profiler' ); ?>
277
+ <br />
278
  <?php } ?>
279
  <?php if ( !$detected ) { ?>
280
+ <?php _e( 'P3 has not detected any opcode optimizers on your site. Although none were detected, an opcode optimizer may still be present. Contact your server administrator with any questions.', 'p3-profiler' ); ?>
 
281
  <?php } ?>
282
  </blockquote>
283
  </div>
284
 
285
 
286
  <div class="p3-question">
287
+ <h2 class="p3-help-question"><?php _e( "How much room do these profiles take up on my server", 'p3-profiler' ); ?></h2>
288
  <blockquote>
289
  <?php
290
  $total_size = 0;
297
  closedir( $dir );
298
 
299
  ?>
300
+ <?php printf( __( "The scans are stored in <code>%1\$s</code> and take up %2\$s of disk space. Each time you run a scan, this storage requirement goes up, and each time you delete a scan, it goes down.", 'p3-profiler' ),
301
+ realpath( P3_PROFILES_PATH ),
302
+ self::readable_size( $total_size )
303
+ ); ?>
304
  </blockquote>
305
  </div>
306
 
307
  <div class="p3-question">
308
+ <h2 class="p3-help-question"><?php _e( "Is this plugin always running?", 'p3-profiler' ); ?></h2>
309
  <blockquote>
310
+ <?php _e( "The short answer is no.
311
+ <br /><br />
312
+ The more detailed answer is the loader is always running, but checks very early in the page loading process to see if you've enabled profiling mode and if the user's IP address matches the IP address the plugin is monitoring. For multisite installations, it also matches the site URL. If all these match, the plugin becomes active and profiles. Otherwise, your site loads as normal with no other code overhead.
313
+ <br /><br />
314
+ Deactivating the plugin ensures it's not running at all, and does not delete your scans. However, uninstalling the plugin does delete your scans.", 'p3-profiler' ); ?>
 
 
 
 
 
315
  </blockquote>
316
  </div>
317
 
318
  <div class="p3-question">
319
+ <h2 class="p3-help-question"><?php _e( "How can I test specific pages on my site?", 'p3-profiler' ); ?></h2>
320
  <blockquote>
321
+ <?php _e( "When you start a scan, choose \"Manual Scan\" and then you can visit specific links on your site that you want to profile. If you want to profile the admin section, just click the \"X\" in the top right of the scan window and you'll be returned to your admin section. You can browse as normal, then come back to the profile page and click \"Stop Scan\" when you're ready to view the results.
322
+ <br /><br />
323
+ To scan your site as an anonymous user, select \"Manual Mode\" as above, but instead of clicking your site in the scan window, open a different browser (or an incognito window) and browse your site as a logged out user. When you're done, close that browser and return to your admin. Click \"I'm done\" and view your scan results.", 'p3-profiler' ); ?>
 
 
 
 
 
 
324
  </blockquote>
325
  </div>
326
 
327
  <div class="p3-question">
328
+ <h2 class="p3-help-question"><?php _e( "My plugins don't seem to cause site slowness. Why is my site still slow?", 'p3-profiler' ); ?></h2>
329
  <blockquote>
330
+ <?php printf( __( "Your site can be slow for a number of reasons. Your site could have a lot of traffic, other sites on your server could have a lot of traffic, you could be referencing content from other sites that are slow, your Internet connection could be slow, your server could be out of RAM, your site could be very image heavy, your site could require a lot of HTTP requests, etc. In short, a lot of factors can cause slowness on your site
331
+ <br /><br />
332
+ Your next stop should be to use <a href=\"%1\$s\" target=\"_blank\">%2\$s</a>, <a href=\"%3\$s\" target=\"_blank\">%4\$s</a>, <a href=\"%5\$s\" target=\"_blank\">%6\$s</a>, <a href=\"%7\$s\" target=\"_blank\">%8\$s</a>, and your browser's development tools like <a href=\"%9\$s\" target=\"_blank\">%10\$s</a> for Firefox, <a href=\"%11\$s\" target=\"_blank\">%12\$s</a> for Chrome, or <a href=\"%13\$s\" target=\"_blank\">%14\$s</a> for Safari.
333
+ <br /><br />
334
+ After you've tuned your site up as much as possible, if you're still not happy with its performance, you should consult your site/server administrator or hosting support.", 'p3-profiler'),
335
+ 'http://tools.pingdom.com/', __( 'Pingdom Tools', 'p3-profiler' ),
336
+ 'http://webpagetest.org/', __( 'Webpage Test', 'p3-profiler' ),
337
+ 'http://developer.yahoo.com/yslow/', __( 'YSlow', 'p3-profiler' ),
338
+ 'https://developers.google.com/pagespeed/', __( 'Google PageSpeed', 'p3-profiler' ),
339
+ 'http://getfirebug.com/', __( 'Firebug', 'p3-profiler' ),
340
+ 'http://code.google.com/chrome/devtools/docs/overview.html', __( 'Chrome Developer Tools', 'p3-profiler' ),
341
+ 'http://developer.apple.com/technologies/safari/developer-tools.html', __( 'Safari Developer Tools', 'p3-profiler' )
342
+ ); ?>
 
 
 
343
  </blockquote>
344
  </div>
345
 
346
  <div class="p3-question">
347
+ <h2 class="p3-help-question" data-question-id="q-debug-log"><?php _e( "Where can I view the debug log?", 'p3-profiler' ); ?></h2>
348
  <blockquote>
349
+ <?php printf( __( "Debug mode will record 100 visits to your site, then turn off automatically. You can view the log below. The entries are shown in reverse order with the latest visits appearing at the top of the list. You can also <a href=\"%1\$s\" class=\"button-secondary\">Clear the log</a> or <a href=\"%2\$s\" class=\"button-secondary\">Download the log</a> as a CSV.", 'p3-profiler' ),
350
+ wp_nonce_url( add_query_arg( array( 'p3_action' => 'clear-debug-log' ) ), 'p3-clear-debug-log' ),
351
+ wp_nonce_url( add_query_arg( array( 'p3_action' => 'download-debug-log' ) ), 'p3-download-debug-log' )
352
+ ); ?>
353
  <br /><br />
354
  <div id="p3-debug-log-container">
355
  <div class="ui-widget-header" id="p3-debug-log-header" style="padding: 8px;">
356
+ <strong><?php _e( 'Debug Log', 'p3-profiler' ); ?></strong>
357
  <div style="position: relative; top: 0px; right: 80px; float: right;">
358
+ <a href="javascript:;" id="p3-hide-debug-log"><?php _e( 'Hide', 'p3-profiler' ); ?></a>
359
  </div>
360
  </div>
361
  <div>
362
  <table class="p3-results-table" id="p3-debug-log-table" cellpadding="0" cellspacing="0" border="0">
363
  <thead>
364
  <tr>
365
+ <td><strong><?php _ex( '#', 'Symbol meaning number', 'p3-profiler' ); ?></strong></td>
366
+ <td><strong><?php _e( 'Profiling Enabled', 'p3-profiler' ); ?></strong></td>
367
+ <td><strong><?php _e( 'Recording IP', 'p3-profiler' ); ?></strong></td>
368
+ <td><strong><?php _e( 'Scan Name', 'p3-profiler' ); ?></strong></td>
369
+ <td><strong><?php _e( 'Recording', 'p3-profiler' ); ?></strong></td>
370
+ <td><strong><?php _e( 'Disable Optimizers', 'p3-profiler' ); ?></strong></td>
371
+ <td><strong><?php _e( 'URL', 'p3-profiler' ); ?></strong></td>
372
+ <td><strong><?php _e( 'Visitor IP', 'p3-profiler' ); ?></strong></td>
373
+ <td><strong><?php _e( 'Time', 'p3-profiler' ); ?></strong></td>
374
+ <td><strong><?php _ex( 'PID', 'Abbreviation for process id', 'p3-profiler' ); ?></strong></td>
375
  </tr>
376
  </thead>
377
  <tbody>
402
  </tbody>
403
  <tfoot>
404
  <tr>
405
+ <td><strong><?php _ex( '#', 'Symbol meaning number', 'p3-profiler' ); ?></strong></td>
406
+ <td><strong><?php _e( 'Profiling Enabled', 'p3-profiler' ); ?></strong></td>
407
+ <td><strong><?php _e( 'Recording IP', 'p3-profiler' ); ?></strong></td>
408
+ <td><strong><?php _e( 'Scan Name', 'p3-profiler' ); ?></strong></td>
409
+ <td><strong><?php _e( 'Recording', 'p3-profiler' ); ?></strong></td>
410
+ <td><strong><?php _e( 'Disable Optimizers', 'p3-profiler' ); ?></strong></td>
411
+ <td><strong><?php _e( 'URL', 'p3-profiler' ); ?></strong></td>
412
+ <td><strong><?php _e( 'Visitor IP', 'p3-profiler' ); ?></strong></td>
413
+ <td><strong><?php _e( 'Time', 'p3-profiler' ); ?></strong></td>
414
+ <td><strong><?php _ex( 'PID', 'Abbreviation for process id', 'p3-profiler' ); ?></strong></td>
415
  </tr>
416
  </tfoot>
417
  </table>
421
  </div>
422
 
423
  <div class="p3-question">
424
+ <h2 class="p3-help-question"><?php _e( "What if I get a warning about usort()?", 'p3-profiler' ); ?></h2>
425
  <blockquote>
426
+ <?php printf( _x( "Warning messages like this: <code>Warning: usort() [function.usort]: Array was modified by the user comparison function</code> are due to a known php bug. See <a href=\"%s\" target=\"_blank\">php bug #50688</a> for more information. This warning does not affect the functionality of your site and it is not visible to your users.", 'Warning message is taken verbatim from PHP output', 'p3-profiler' ),
427
+ 'https://bugs.php.net/bug.php?id=50688'
428
+ ); ?>
 
 
429
  </blockquote>
430
  </div>
431
 
432
  <div class="p3-question">
433
+ <h2 class="p3-help-question"><?php _e( "Does this plugin increase memory usage on my site?", 'p3-profiler' ); ?></h2>
434
  <blockquote>
435
+ <?php printf( __( "When you run a performance scan on your site, the memory requirements go up during the scan. Accordingly, P3 sets your <a href=\"%1\$s\" target=\"_blank\">%2\$s</a> to 256 MB and <a href=\"%3\$s\" target=\"_blank\">%4\$s</a> to 90 seconds during a performance scan. These changes are not permanent and are only in effect when a performance scan is actively running.", 'p3-profiler' ),
436
+ 'http://www.php.net/manual/en/ini.core.php#ini.memory-limit', __( 'memory limit', 'p3-profiler' ),
437
+ 'http://php.net/set_time_limit', __( 'time limit', 'p3-profiler' )
438
+ ); ?>
439
  </blockquote>
440
  </div>
441
 
442
  <div class="p3-question">
443
+ <h2 class="p3-help-question" style="border-bottom-width: 0px !important;"><?php _e( 'Glossary', 'p3-profiler' ); ?></h2>
444
  <blockquote>
445
  <div>
446
  <div id="p3-glossary-container">
447
  <div class="ui-widget-header" id="p3-glossary-header" style="padding: 8px;">
448
+ <strong><?php _e( 'Glossary', 'p3-profiler' ); ?></strong>
449
  <div style="position: relative; top: 0px; right: 80px; float: right;">
450
+ <a href="javascript:;" id="p3-hide-glossary"><?php _e( 'Hide', 'p3-profiler' ); ?></a>
451
  </div>
452
  </div>
453
  <div>
458
  <div id="glossary">
459
  <table width="100%" cellpadding="0" cellspacing="0" border="0" id="glossary-terms">
460
  <tr>
461
+ <td width="200" class="term"><strong><?php _e( 'Total Load Time', 'p3-profiler' ); ?></strong>
462
  <div id="total-load-time-definition" style="display: none;" class="definition">
463
+ <?php _e( 'The length of time the site took to load. This is an observed measurement (start timing when the page was requested, stop timing when the page was delivered to the browser, calculate the difference). Lower is better.', 'p3-profiler' ); ?>
 
 
464
  </div>
465
  </td>
466
  <td width="400" rowspan="12" id="p3-glossary-term-display">&nbsp;</td>
467
  </tr>
468
  <tr>
469
+ <td class="term"><strong><?php _e( 'Site Load Time', 'p3-profiler' ); ?></strong>
470
  <div id="site-load-time-definition" style="display: none;" class="definition">
471
+ <?php _e( "The calculated total load time minus the profile overhead. This is closer to your site's real-life load time. Lower is better.", 'p3-profiler' ); ?>
 
472
  </div>
473
  </td>
474
  </tr>
475
  <tr>
476
+ <td class="term"><strong><?php _e( 'Profile Overhead', 'p3-profiler' ); ?></strong>
477
  <div id="profile-overhead-definition" style="display: none;" class="definition">
478
+ <?php _e( "The load time spent profiling code. Because the profiler slows down your load time, it is important to know how much impact the profiler has. However, it doesn't impact your site's real-life load time.", 'p3-profiler' ); ?>
 
 
479
  </div>
480
  </td>
481
  </tr>
482
  <tr>
483
+ <td class="term"><strong><?php _e( 'Plugin Load Time', 'p3-profiler' ); ?></strong>
484
  <div id="plugin-load-time-definition" style="display: none;" class="definition">
485
+ <?php _e( "The load time caused by plugins. Because of WordPress' construction, we can trace a function call from a plugin through a theme through the core. The profiler prioritizes plugin calls first, theme calls second, and core calls last. Lower is better.", 'p3-profiler' ); ?>
 
 
486
  </div>
487
  </td>
488
  </tr>
489
  <tr>
490
+ <td class="term"><strong><?php _e( 'Theme Load Time', 'p3-profiler' ); ?></strong>
491
  <div id="theme-load-time-definition" style="display: none;" class="definition">
492
+ <?php _e( "The load time spent applying the theme. Because of WordPress' construction, we can trace a function call from a plugin through a theme through the core. The profiler prioritizes plugin calls first, theme calls second, and core calls last. Lower is better.", 'p3-profiler' ); ?>
 
 
493
  </div>
494
  </td>
495
  </tr>
496
  <tr>
497
+ <td class="term"><strong><?php _e( 'Core Load Time' , 'p3-profiler' ); ?></strong>
498
  <div id="core-load-time-definition" style="display: none;" class="definition">
499
+ <?php _e( "The load time caused by the WordPress core. Because of WordPress' construction, we can trace a function call from a plugin through a theme through the core. The profiler prioritizes plugin calls first, theme calls second, and core calls last. This will probably be constant.", 'p3-profiler' ); ?>
 
 
500
  </div>
501
  </td>
502
  </tr>
503
  <tr>
504
+ <td class="term"><strong><?php _e( 'Margin of Error', 'p3-profiler' ); ?></strong>
505
  <div id="drift-definition" style="display: none;" class="definition">
506
+ <?php _e( "This is the difference between the observed runtime (what actually happened) and expected runtime (adding the plugin runtime, theme runtime, core runtime, and profiler overhead).
507
+ <br /><br />
508
+ There are several reasons this margin of error can exist. Most likely, the profiler is missing microseconds while adding the runtime it observed. Using a network clock to set the time (NTP) can also cause minute timing changes.
509
+ <br /><br />
510
+ Ideally, this number should be zero, but there's nothing you can do to change it. It will give you an idea of how accurate the other results are.", 'p3-profiler' ); ?>
 
 
 
 
511
  </div>
512
  </td>
513
  </tr>
514
  <tr>
515
+ <td class="term"><strong><?php _e( 'Observed', 'p3-profiler' ); ?></strong>
516
  <div id="observed-definition" style="display: none;" class="definition">
517
+ <?php _e( "The time the site took to load. This is an observed measurement (start timing when the page was requested, stop timing when the page was delivered to the browser, calculate the difference).", 'p3-profiler' ); ?>
 
 
518
  </div>
519
  </td>
520
  </tr>
521
  <tr>
522
+ <td class="term"><strong><?php _e( 'Expected', 'p3-profiler' ); ?></strong>
523
  <div id="expected-definition" style="display: none;" class="definition">
524
+ <?php _e( 'The expected site load time calculated by adding plugin load time, core load time, theme load time, and profiler overhead.', 'p3-profiler' ); ?>
 
525
  </div>
526
  </td>
527
  </tr>
528
  <tr>
529
+ <td class="term"><strong><?php _e( 'Plugin Function Calls' , 'p3-profiler' ); ?></strong>
530
  <div id="plugin-funciton-calls-definition" style="display: none;" class="definition">
531
+ <?php _e( "The number of PHP function calls generated by a plugin. Fewer is better.", 'p3-profiler' ); ?>
532
  </div>
533
  </td>
534
  </tr>
535
  <tr>
536
+ <td class="term"><strong><?php _e( 'Memory Usage', 'p3-profiler' ); ?></strong>
537
  <div id="memory-usage-definition" style="display: none;" class="definition">
538
+ <?php printf( __( "The amount of RAM usage observed. This is reported by <a href=\"%s\" target=\"_blank\">memory_get_peak_usage()</a>. Lower is better.", 'p3-profiler' ),
539
+ 'http://php.net/memory_get_peak_usage'
540
+ ); ?>
541
  </div>
542
  </td>
543
  </tr>
544
  <tr>
545
+ <td class="term"><strong><?php _e( 'MySQL Queries', 'p3-profiler' ); ?></strong>
546
  <div id="mysql-queries-definition" style="display: none;" class="definition">
547
+ <?php printf( __( "The number of queries sent to the database. This is reported by the WordPress function <a href=\"%s\" target=\"_blank\">get_num_queries()</a>. Fewer is better.", 'p3-profiler' ),
548
+ 'http://codex.wordpress.org/Function_Reference/get_num_queries'
549
+ ); ?>
550
  </div>
551
  </td>
552
  </tr>
563
  </div>
564
 
565
  <div class="p3-question">
566
+ <h2 class="p3-help-question"><?php _e( "License", 'p3-profiler' ); ?></h2>
567
  <blockquote>
568
+ <?php printf( __( 'P3 (Plugin Performance Profiler) is Copyright &copy; %1$s - %2$s <a href="%3$s" target="_blank">GoDaddy.com</a>. All rights reserved.', 'p3-profiler' ), 2011, date( 'Y' ), 'http://www.godaddy.com/' ); ?>
 
 
 
 
 
 
 
569
  <br /><br />
570
+ <?php printf( __( "This program is offered under the terms of the GNU General Public License Version 2 as published by the Free Software Foundation.
571
+ <br /><br />
572
+ This program offered WITHOUT WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License Version 2 for the specific terms.
573
+ <br /><br />
574
+ A copy of the GNU General Public License has been provided with this program. Alternatively, you may find a copy of the license here: <a href=\"%s\" target=\"_blank\">%s</a>.", 'p3-profiler' ),
575
+ 'http://www.gnu.org/licenses/gpl-2.0.html',
576
+ 'http://www.gnu.org/licenses/gpl-2.0.html'
577
+ ); ?>
578
  </blockquote>
579
  </div>
templates/list-scans.php CHANGED
@@ -5,7 +5,7 @@ if ( !defined('P3_PATH') )
5
  <form id="scans-filter" method="post">
6
  <input type="hidden" name="page" value="<?php echo sanitize_text_field( $_REQUEST ['page'] ); ?>" />
7
  <?php echo wp_nonce_field( 'delete_scans', 'p3_nonce' ); ?>
8
- <?php $this->scan_table->display(); ?>
9
  </form>
10
  <script type="text/javascript">
11
  jQuery(document).ready(function($) {
@@ -13,7 +13,7 @@ if ( !defined('P3_PATH') )
13
  if (0 == $("input:checked", $("#scans-filter")).length) {
14
  evt.stopPropagation();
15
  evt.preventDefault();
16
- } else if (!confirm('Are you sure you want to delete these scans?')) {
17
  evt.stopPropagation();
18
  evt.preventDefault();
19
  } else {
@@ -21,7 +21,7 @@ if ( !defined('P3_PATH') )
21
  }
22
  });
23
  $("a.delete-scan").click(function(evt) {
24
- if (confirm('Are you sure you want to delete this scan?')) {
25
 
26
  // De-select the checkboxes
27
  $("#scans-filter input:checked").prop("checked", false);
5
  <form id="scans-filter" method="post">
6
  <input type="hidden" name="page" value="<?php echo sanitize_text_field( $_REQUEST ['page'] ); ?>" />
7
  <?php echo wp_nonce_field( 'delete_scans', 'p3_nonce' ); ?>
8
+ <?php self::$scan_table->display(); ?>
9
  </form>
10
  <script type="text/javascript">
11
  jQuery(document).ready(function($) {
13
  if (0 == $("input:checked", $("#scans-filter")).length) {
14
  evt.stopPropagation();
15
  evt.preventDefault();
16
+ } else if (!confirm( '<?php _e( 'Are you sure you want to delete these scans?', 'p3-profiler' ); ?>' )) {
17
  evt.stopPropagation();
18
  evt.preventDefault();
19
  } else {
21
  }
22
  });
23
  $("a.delete-scan").click(function(evt) {
24
+ if (confirm( '<?php _e( 'Are you sure you want to delete this scan?', 'p3-profiler' ); ?>' )) {
25
 
26
  // De-select the checkboxes
27
  $("#scans-filter input:checked").prop("checked", false);
templates/template.php CHANGED
@@ -3,9 +3,9 @@
3
  $button_current_checked = '';
4
  $button_history_checked = '';
5
  $button_help_checked = '';
6
- if ( 'current-scan' == $this->action || !empty( $_REQUEST['current_scan'] ) ) {
7
  $button_current_checked = 'checked="checked"';
8
- } elseif ( 'help' == $this->action ) {
9
  $button_help_checked = 'checked="checked"';
10
  } else {
11
  $button_history_checked = 'checked="checked"';
@@ -59,19 +59,21 @@ if ( 'current-scan' == $this->action || !empty( $_REQUEST['current_scan'] ) ) {
59
 
60
  <!-- Header icon / title -->
61
  <div id="icon-plugins" class="icon32"><br/></div>
62
- <h2>P3 - Plugin Performance Profiler</h2>
63
 
64
  <!-- Header navbar -->
65
  <div class="ui-widget-header" id="p3-navbar">
66
- <input type="radio" name="p3-nav" id="button-current-scan" <?php echo $button_current_checked; ?> />
67
- <label for="button-current-scan">Current</label>
68
- <input type="radio" name="p3-nav" id="button-history-scans" <?php echo $button_history_checked; ?> />
69
- <label for="button-history-scans">History</label>
70
- <input type="radio" name="p3-nav" id="button-help" <?php echo $button_help_checked; ?> /><label for="button-help">Help</label>
 
 
71
 
72
  <div id="p3-scan-label">
73
- <?php if ( !empty( $this->profile ) ) : ?>
74
- Scan name: <?php echo $this->profile->profile_name; ?>
75
  <?php endif; ?>
76
  </div>
77
  </div>
@@ -80,28 +82,28 @@ if ( 'current-scan' == $this->action || !empty( $_REQUEST['current_scan'] ) ) {
80
  <?php require_once P3_PATH . '/templates/callouts.php'; ?>
81
 
82
  <!-- View scan or show a list of scans -->
83
- <?php if ( ( 'current-scan' == $this->action && !empty( $this->scan ) ) || 'view-scan' == $this->action ) { ?>
84
- <?php include_once P3_PATH . '/templates/view-scan.php'; ?>
85
- <?php } elseif ( 'help' == $this->action ) { ?>
86
- <?php include_once P3_PATH . '/templates/help.php'; ?>
87
  <?php } else { ?>
88
- <?php include_once P3_PATH . '/templates/list-scans.php'; ?>
89
  <?php } ?>
90
 
91
  </div>
92
 
93
  <div id="p3-reminder">
94
  <div id="p3-reminder-wrapper">
95
- Do you like this plugin?
96
  <ul>
97
- <li><a href="http://twitter.com/home?status=<?php echo rawurlencode(htmlentities('I just optimized my WordPress site with #p3plugin http://wordpress.org/extend/plugins/p3-profiler/ ')); ?>" target="_blank">Tweet</a> about it</li>
98
- <li><a href="http://wordpress.org/extend/plugins/p3-profiler/" target="_blank">Rate</a> it on the repository</li>
99
  </ul>
100
  </div>
101
  </div>
102
 
103
  <div id="p3-copyright">
104
- <img src="<?php echo plugins_url() . '/p3-profiler/logo.gif'; ?>" alt="GoDaddy.com logo" title="GoDaddy.com logo" />
105
  <br />
106
- Copyright &copy; 2011-<?php echo date('Y'); ?> <a href="http://www.godaddy.com/" target="_blank">GoDaddy.com</a>. All rights reserved.
107
  </div>
3
  $button_current_checked = '';
4
  $button_history_checked = '';
5
  $button_help_checked = '';
6
+ if ( 'current-scan' == self::$action || !empty( $_REQUEST['current_scan'] ) ) {
7
  $button_current_checked = 'checked="checked"';
8
+ } elseif ( 'help' == self::$action ) {
9
  $button_help_checked = 'checked="checked"';
10
  } else {
11
  $button_history_checked = 'checked="checked"';
59
 
60
  <!-- Header icon / title -->
61
  <div id="icon-plugins" class="icon32"><br/></div>
62
+ <h2><?php _e( 'P3 - Plugin Performance Profiler', 'p3-profiler' ); ?></h2>
63
 
64
  <!-- Header navbar -->
65
  <div class="ui-widget-header" id="p3-navbar">
66
+ <div>
67
+ <input type="radio" name="p3-nav" id="button-current-scan" <?php echo $button_current_checked; ?> />
68
+ <label for="button-current-scan"><?php _e( 'Current', 'p3-profiler' ); ?></label>
69
+ <input type="radio" name="p3-nav" id="button-history-scans" <?php echo $button_history_checked; ?> />
70
+ <label for="button-history-scans"><?php _e( 'History', 'p3-profiler' ); ?></label>
71
+ <input type="radio" name="p3-nav" id="button-help" <?php echo $button_help_checked; ?> /><label for="button-help"><?php _e( 'Help', 'p3-profiler' ); ?></label>
72
+ </div>
73
 
74
  <div id="p3-scan-label">
75
+ <?php if ( !empty( self::$profile ) ) : ?>
76
+ <?php _e( 'Scan name:', 'p3-profiler' ); ?> <?php echo self::$profile->profile_name; ?>
77
  <?php endif; ?>
78
  </div>
79
  </div>
82
  <?php require_once P3_PATH . '/templates/callouts.php'; ?>
83
 
84
  <!-- View scan or show a list of scans -->
85
+ <?php if ( ( 'current-scan' == self::$action && !empty( self::$scan ) ) || 'view-scan' == self::$action ) { ?>
86
+ <?php require_once P3_PATH . '/templates/view-scan.php'; ?>
87
+ <?php } elseif ( 'help' == self::$action ) { ?>
88
+ <?php require_once P3_PATH . '/templates/help.php'; ?>
89
  <?php } else { ?>
90
+ <?php require_once P3_PATH . '/templates/list-scans.php'; ?>
91
  <?php } ?>
92
 
93
  </div>
94
 
95
  <div id="p3-reminder">
96
  <div id="p3-reminder-wrapper">
97
+ <?php _e( 'Do you like this plugin?', 'p3-profiler' ); ?>
98
  <ul>
99
+ <li><a href="http://twitter.com/home?status=<?php echo rawurlencode( htmlentities( sprintf( __( 'I just optimized my WordPress site with %1$s %2$s', 'p3-profiler' ), '#p3plugin', 'http://wordpress.org/extend/plugins/p3-profiler/') ) ); ?>" target="_blank"><?php _e( 'Tweet about it', 'p3-profiler' ); ?></a></li>
100
+ <li><a href="http://wordpress.org/extend/plugins/p3-profiler/" target="_blank"><?php _e( 'Rate it on the repository', 'p3-profiler' ); ?></a></li>
101
  </ul>
102
  </div>
103
  </div>
104
 
105
  <div id="p3-copyright">
106
+ <img src="<?php echo plugins_url() . '/p3-profiler/css/logo.gif'; ?>" alt="<?php esc_attr_e( 'Logo', 'p3-profiler' ); ?>" title="<?php esc_attr_e( 'Logo', 'p3-profiler' ); ?>" />
107
  <br />
108
+ <?php printf( __( 'P3 (Plugin Performance Profiler) is Copyright &copy; %1$s - %2$s <a href="%3$s" target="_blank">GoDaddy.com</a>. All rights reserved.', 'p3-profiler' ), 2011, date( 'Y' ), 'http://www.godaddy.com/' ); ?>
109
  </div>
templates/view-scan.php CHANGED
@@ -3,9 +3,9 @@ if ( !defined('P3_PATH') )
3
  die( 'Forbidden ');
4
  $url_stats = array();
5
  $domain = '';
6
- if ( !empty( $this->profile ) ) {
7
- $url_stats = $this->profile->get_stats_by_url();
8
- $domain = @parse_url( $this->profile->report_url, PHP_URL_HOST );
9
  }
10
  $pie_chart_id = substr( md5( uniqid() ), -8 );
11
  $runtime_chart_id = substr( md5( uniqid() ), -8 );
@@ -21,8 +21,8 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
21
 
22
  // Raw json data ( used in the charts for tooltip data
23
  var _data = [];
24
- <?php if ( !empty( $this->scan ) && file_exists( $this->scan ) ) { ?>
25
- <?php foreach ( file( $this->scan, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES ) as $line ) { ?>
26
  _data.push(<?php echo $line; ?>);
27
  <?php } ?>
28
  <?php } ?>
@@ -48,11 +48,11 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
48
  'modal' : true,
49
  'width' : 400,
50
  'height' : 'auto',
51
- 'title' : "Toggle Series",
52
  'buttons' :
53
  [
54
  {
55
- text: 'Ok',
56
  'class' : 'button-secondary',
57
  click: function() {
58
  $(this).dialog( "close" );
@@ -68,11 +68,11 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
68
  'modal' : true,
69
  'width' : 500,
70
  'height' : 560,
71
- 'title' : "Email Report",
72
  'buttons' :
73
  [
74
  {
75
- text: 'Send',
76
  'class' : 'button-secondary',
77
  click: function() {
78
  data = {
@@ -94,7 +94,7 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
94
 
95
  // Send the data
96
  jQuery.post( ajaxurl, data, function( response ) {
97
- response = response.trim();
98
  if ( "1" == response.substring( 0, 1 ) ) {
99
  $( "#p3-email-success-recipient" ).html( jQuery( '#p3-email-results-to' ).val() );
100
  $( "#p3-email-sending-success" ).show();
@@ -118,7 +118,7 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
118
  }
119
  },
120
  {
121
- text: 'Cancel',
122
  'class': 'p3-cancel-button',
123
  click: function() {
124
  $( this ).dialog( "close" );
@@ -165,15 +165,15 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
165
  /** Plugin pie chart **/
166
  /**************************************************************/
167
  var data_<?php echo $pie_chart_id; ?> = [
168
- <?php if ( !empty( $this->profile ) ){ ?>
169
- <?php foreach ( $this->profile->plugin_times as $k => $v ) { ?>
170
  {
171
  label: "<?php echo esc_js( $k ); ?>",
172
  data: <?php echo $v; ?>
173
  },
174
  <?php } ?>
175
  <?php } else { ?>
176
- { label: 'No plugins', data: 1}
177
  <?php } ?>
178
  ];
179
  jQuery( document ).ready( function( $) {
@@ -203,7 +203,7 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
203
  $( "#p3-tooltip" ).remove();
204
  showTooltip( pos.pageX, pos.pageY,
205
  item.series.label + "<br />" + Math.round( item.series.percent ) + "%<br />" +
206
- Math.round( item.datapoint[1][0][1] * Math.pow( 10, 4 ) ) / Math.pow( 10, 4 ) + " seconds"
207
  );
208
  } else {
209
  $( "#p3-tooltip" ).remove();
@@ -219,7 +219,7 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
219
  var chart_<?php echo $runtime_chart_id; ?> = null;
220
  var data_<?php echo $runtime_chart_id; ?> = [
221
  {
222
- label: "WP Core time",
223
  data: [
224
  <?php foreach ( array_values( $url_stats ) as $k => $v ) { ?>
225
  [
@@ -230,7 +230,7 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
230
  ]
231
  },
232
  {
233
- label: "Theme time",
234
  data: [
235
  <?php foreach ( array_values( $url_stats ) as $k => $v ) { ?>
236
  [
@@ -241,7 +241,7 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
241
  ]
242
  },
243
  {
244
- label: "Plugin time",
245
  data: [
246
  <?php foreach ( array_values( $url_stats ) as $k => $v ) { ?>
247
  [
@@ -308,7 +308,7 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
308
  showTooltip( item.pageX, item.pageY,
309
  item.series.label + "<br />" +
310
  url + "<br />" +
311
- y + " seconds" );
312
  }
313
  } else {
314
  $( "#p3-tooltip" ).remove();
@@ -325,9 +325,9 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
325
  var chart_<?php echo $query_chart_id; ?> = null;
326
  var data_<?php echo $query_chart_id; ?> = [
327
  {
328
- label: "# of Queries",
329
  data: [
330
- <?php if ( !empty( $this->profile ) ){ ?>
331
  <?php foreach ( array_values( $url_stats ) as $k => $v ) { ?>
332
  [
333
  <?php echo $k + 1; ?>,
@@ -391,7 +391,7 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
391
  // Get rid of the domain
392
  url = url.replace(/http[s]?:\/\/<?php echo $domain; ?>(:\d+)?/, "" );
393
 
394
- qword = ( y == 1 ) ? "query" : "queries";
395
  showTooltip( item.pageX, item.pageY,
396
  item.series.label + "<br />" +
397
  url + "<br />" +
@@ -411,7 +411,7 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
411
  var chart_<?php echo $component_breakdown_chart_id; ?> = null;
412
  var data_<?php echo $component_breakdown_chart_id; ?> = [
413
  {
414
- label: 'Site Load Time',
415
  bars: {show: false},
416
  points: {show: false},
417
  lines: {show: true, lineWidth: 3},
@@ -420,21 +420,21 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
420
  <?php for ( $i = -999 ; $i < 999 + 2; $i++ ) { ?>
421
  [
422
  <?php echo $i; ?>,
423
- <?php echo $this->profile->averages['site']; ?>
424
  ],
425
  <?php } ?>
426
  ]
427
  },
428
  {
429
- label: 'WP Core Time',
430
- data: [[0, <?php echo $this->profile->averages['core']; ?>]]
431
  },
432
  {
433
- label: 'Theme',
434
- data: [[1, <?php echo $this->profile->averages['theme']; ?>]]
435
  },
436
  <?php $i = 2; $other = 0; ?>
437
- <?php foreach ( $this->profile->plugin_times as $k => $v ) { ?>
438
  {
439
  label: '<?php echo esc_js( $k ); ?>',
440
  data: [[
@@ -469,11 +469,11 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
469
  xaxis: {
470
  show: false,
471
  ticks: [
472
- [0, 'Site Load Time'],
473
- [1, 'WP Core Time'],
474
- [2, 'Theme'],
475
  <?php $i = 3; ?>
476
- <?php foreach ( $this->profile->plugin_times as $k => $v ) { ?>
477
  [
478
  <?php echo $i++ ?>,
479
  '<?php echo esc_js( $k ); ?>'
@@ -498,7 +498,7 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
498
  if ( item ) {
499
  $( "#p3-tooltip" ).remove();
500
  showTooltip( pos.pageX, pos.pageY,
501
- item.series.label + "<br />" + Math.round( item.datapoint[1] * Math.pow( 10, 4 ) ) / Math.pow( 10, 4 ) + " seconds"
502
  );
503
  } else {
504
  $( "#p3-tooltip" ).remove();
@@ -524,9 +524,9 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
524
  var chart_<?php echo $component_runtime_chart_id; ?> = null;
525
  var data_<?php echo $component_runtime_chart_id; ?> = [
526
  {
527
- label: "WP Core Time",
528
  data: [
529
- <?php if ( !empty( $this->profile ) ){ ?>
530
  <?php foreach ( array_values( $url_stats ) as $k => $v ) { ?>
531
  [
532
  <?php echo $k + 1; ?>,
@@ -537,9 +537,9 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
537
  ]
538
  },
539
  {
540
- label: "Theme",
541
  data: [
542
- <?php if ( !empty( $this->profile ) ){ ?>
543
  <?php foreach ( array_values( $url_stats ) as $k => $v ) { ?>
544
  [
545
  <?php echo $k + 1; ?>,
@@ -549,8 +549,8 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
549
  <?php } ?>
550
  ]
551
  },
552
- <?php if ( !empty( $this->profile ) && !empty( $this->profile->detected_plugins ) ) { ?>
553
- <?php foreach ( $this->profile->detected_plugins as $plugin ) { ?>
554
  {
555
  label: "<?php echo esc_js( $plugin ); ?>",
556
  data: [
@@ -573,10 +573,10 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
573
  var detailed_timeline_options = {};
574
 
575
  jQuery( document ).ready( function ( $ ) {
576
- <?php if ( !empty( $this->profile ) && !empty( $this->profile->detected_plugins ) ) { ?>
577
- jQuery( "#p3-detailed-series-toggle" ).append( '<div><label><input type="checkbox" checked="checked" class="p3-detailed-series-toggle" data-key="WP Core Time" />WP Core Time</label></div>' );
578
- jQuery( "#p3-detailed-series-toggle" ).append( '<div><label><input type="checkbox" checked="checked" class="p3-detailed-series-toggle" data-key="Theme" />Theme</label></div>' );
579
- <?php foreach ( $this->profile->detected_plugins as $plugin ) { ?>
580
  jQuery( "#p3-detailed-series-toggle" ).append( '<div><label><input type="checkbox" checked="checked" class="p3-detailed-series-toggle" data-key="<?php echo esc_html( $plugin ); ?>" /><?php echo esc_html( $plugin ); ?></label></div>' );
581
  <?php } ?>
582
  <?php } ?>
@@ -604,7 +604,7 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
604
  data = [
605
  {
606
  data: [],
607
- label: 'No data'
608
  }
609
  ]
610
  }
@@ -661,7 +661,7 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
661
  showTooltip( item.pageX, item.pageY,
662
  item.series.label + "<br />" +
663
  url + "<br />" +
664
- y + " seconds" );
665
  }
666
  } else {
667
  $( "#p3-tooltip" ).remove();
@@ -695,30 +695,30 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
695
  </script>
696
  <div id="p3-tabs">
697
  <ul>
698
- <li><a href="#p3-tabs-1">Runtime By Plugin</a></li>
699
- <li><a href="#p3-tabs-5">Detailed Breakdown</a></li>
700
- <li><a href="#p3-tabs-2">Simple Timeline</a></li>
701
- <li><a href="#p3-tabs-6">Detailed Timeline</a></li>
702
- <li><a href="#p3-tabs-3">Query Timeline</a></li>
703
- <li><a href="#p3-tabs-4">Advanced Metrics</a></li>
704
  </ul>
705
 
706
  <!-- Plugin bar chart -->
707
  <div id="p3-tabs-5">
708
- <h2>Detailed Breakdown</h2>
709
  <div class="p3-plugin-graph">
710
  <table>
711
  <tr>
712
  <td rowspan="2">
713
  <div class="p3-y-axis-label">
714
- <em class="p3-em">Seconds</em>
715
  </div>
716
  </td>
717
  <td rowspan="2">
718
  <div class="p3-graph-holder" id="p3-holder_<?php echo $component_breakdown_chart_id; ?>"></div>
719
  </td>
720
  <td>
721
- <h3>Legend</h3>
722
  </td>
723
  </tr>
724
  <tr>
@@ -730,7 +730,7 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
730
  <td>&nbsp;</td>
731
  <td colspan="2">
732
  <div class="p3-x-axis-label" style="top: -10px;">
733
- <em class="p3-em">Component</em>
734
  </div>
735
  </td>
736
  </tr>
@@ -740,7 +740,7 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
740
 
741
  <!-- Plugin pie chart div -->
742
  <div id="p3-tabs-1">
743
- <h2>Runtime by Plugin</h2>
744
  <div class="p3-plugin-graph" style="width: 570px;">
745
  <table>
746
  <tr>
@@ -748,7 +748,7 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
748
  <div style="width: 370px;" class="p3-graph-holder" id="p3-holder_<?php echo $pie_chart_id; ?>"></div>
749
  </td>
750
  <td>
751
- <h3>Legend</h3>
752
  </td>
753
  </tr>
754
  <tr>
@@ -762,20 +762,20 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
762
 
763
  <!-- Runtime line chart div -->
764
  <div id="p3-tabs-2">
765
- <h2>Summary Timeline</h2>
766
  <div class="p3-plugin-graph">
767
  <table>
768
  <tr>
769
  <td rowspan="2">
770
  <div class="p3-y-axis-label">
771
- <em class="p3-em">Seconds</em>
772
  </div>
773
  </td>
774
  <td rowspan="2">
775
  <div class="p3-graph-holder" id="p3-holder_<?php echo $runtime_chart_id; ?>"></div>
776
  </td>
777
  <td>
778
- <h3>Legend</h3>
779
  </td>
780
  </tr>
781
  <tr>
@@ -797,20 +797,20 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
797
 
798
  <!-- Query line chart div -->
799
  <div id="p3-tabs-3">
800
- <h2>Query Timeline</h2>
801
  <div class="p3-plugin-graph">
802
  <table>
803
  <tr>
804
  <td rowspan="2">
805
  <div class="p3-y-axis-label">
806
- <em class="p3-em">Queries</em>
807
  </div>
808
  </td>
809
  <td rowspan="2">
810
  <div class="p3-graph-holder" id="p3-holder_<?php echo $query_chart_id; ?>"></div>
811
  </td>
812
  <td>
813
- <h3>Legend</h3>
814
  </td>
815
  </tr>
816
  <tr>
@@ -832,20 +832,20 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
832
 
833
  <!-- Component runtime chart div -->
834
  <div id="p3-tabs-6">
835
- <h2>Detailed Timeline</h2>
836
  <div class="p3-plugin-graph">
837
  <table>
838
  <tr>
839
  <td rowspan="2">
840
  <div class="p3-y-axis-label">
841
- <em class="p3-em">Seconds</em>
842
  </div>
843
  </td>
844
  <td rowspan="2">
845
  <div class="p3-graph-holder" id="p3-holder_<?php echo $component_runtime_chart_id; ?>"></div>
846
  </td>
847
  <td>
848
- <h3>Legend</h3>
849
  </td>
850
  </tr>
851
  <tr>
@@ -869,126 +869,102 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
869
  <div id="p3-tabs-4">
870
  <div id="p3-metrics-container">
871
  <div class="ui-widget-header" id="p3-metrics-header" style="padding: 8px;">
872
- <strong>Advanced Metrics</strong>
873
  </div>
874
  <div>
875
  <table class="p3-results-table" id="p3-results-table" cellpadding="0" cellspacing="0" border="0">
876
  <tbody>
877
  <tr class="advanced">
878
- <td class="qtip-tip" title="The time the site took to load. This is an observed measurement (start
879
- timing when the page was requested, stop timing when the page was delivered to the browser,
880
- calculate the difference). Lower is better.">
881
- <strong>Total Load Time: </strong>
882
  </td>
883
  <td>
884
- <?php printf( '%.4f', $this->profile->averages['total'] ); ?> seconds <em class="p3-em">avg.</em>
885
  </td>
886
  </tr>
887
  <tr>
888
- <td class="qtip-tip" title="The calculated total load time minus the profile overhead. This is closer to your
889
- site's real-life load time. Lower is better.">
890
- <strong>Site Load Time</small></em></strong>
891
  </td>
892
  <td>
893
- <?php printf( '%.4f', $this->profile->averages['site'] ); ?> seconds <em class="p3-em">avg.</em>
894
  </td>
895
  </tr>
896
  <tr class="advanced">
897
- <td class="qtip-tip" title="The load time spent profiling code. Because the profiler slows down your load time,
898
- it is important to know how much impact the profiler has. However, it doesn't impact your site's
899
- real-life load time.">
900
- <strong>Profile Overhead: </strong>
901
  </td>
902
  <td>
903
- <?php printf( '%.4f', $this->profile->averages['profile'] ); ?> seconds <em class="p3-em">avg.</em>
904
  </td>
905
  </tr>
906
  <tr>
907
- <td class="qtip-tip" title="The load time caused by plugins. Because of WordPress' construction, we can trace a
908
- function call from a plugin through a theme through the core. The profiler prioritizes plugin calls
909
- first, theme calls second, and core calls last. Lower is better.">
910
- <strong>Plugin Load Time: </strong>
911
  </td>
912
  <td>
913
- <?php printf( '%.4f', $this->profile->averages['plugins'] ); ?> seconds <em class="p3-em">avg.</em>
914
  </td>
915
  </tr>
916
  <tr>
917
- <td class="qtip-tip" title="The load time spent applying the theme. Because of WordPress' construction, we can trace
918
- a function call from a plugin through a theme through the core. The profiler prioritizes plugin calls
919
- first, theme calls second, and core calls last. Lower is better.">
920
- <strong>Theme Load Time: </strong>
921
  </td>
922
  <td>
923
- <?php printf( '%.4f', $this->profile->averages['theme'] ); ?> seconds <em class="p3-em">avg.</em>
924
  </td>
925
  </tr>
926
  <tr>
927
- <td class="qtip-tip" title="The load time caused by the WordPress core. Because of WordPress' construction, we can
928
- trace a function call from a plugin through a theme through the core. The profiler prioritizes plugin
929
- calls first, theme calls second, and core calls last. This will probably be constant.">
930
- <strong>Core Load Time: </strong>
931
  </td>
932
  <td>
933
- <?php printf( '%.4f', $this->profile->averages['core'] ); ?> seconds <em class="p3-em">avg.</em>
934
  </td>
935
  </tr>
936
  <tr class="advanced">
937
- <td class="qtip-tip" title="This is the difference between the observed runtime (what actually happened) and expected
938
- runtime (adding the plugin runtime, theme runtime, core runtime, and profiler overhead).
939
- There are several reasons this margin of error can exist. Most likely, the profiler is
940
- missing microseconds while adding the runtime it observed. Using a network clock to set the
941
- time (NTP) can also cause minute timing changes.
942
- Ideally, this number should be zero, but there's nothing you can do to change it. It
943
- will give you an idea of how accurate the other results are.">
944
- <strong>Margin of Error: </strong>
945
  </td>
946
  <td>
947
- <?php printf( '%.4f', $this->profile->averages['drift'] ); ?> seconds <em class="p3-em">avg.</em>
948
  <br />
949
  <em class="p3-em">
950
- (<span class="qtip-tip" title="How long the site took to load. This is an observed measurement (start timing
951
- when the page was requested, stop timing when the page was delivered to the browser, calculate the
952
- difference)."><?php printf( '%.4f', $this->profile->averages['observed'] ); ?> observed</span>,
953
- <span class="qtip-tip" title="The expected site load time calculated by adding plugin load time, core
954
- load time, theme load time, and profiler overhead.">
955
- <?php printf( '%.4f', $this->profile->averages['expected'] ); ?> expected</span>)
956
  </em>
957
  </td>
958
  </tr>
959
  <tr class="advanced">
960
- <td class="qtip-tip" title="The number of visits registered during a profiling session. More visits produce a more
961
- accurate summary.">
962
- <strong>Visits: </strong>
963
  </td>
964
  <td>
965
- <?php echo number_format( $this->profile->visits ); ?>
966
  </td>
967
  </tr>
968
  <tr class="advanced">
969
- <td class="qtip-tip" title="The number of PHP function calls generated by a plugin. Fewer is better.">
970
- <strong>Number of Plugin Function Calls: </strong>
971
  </td>
972
  <td>
973
- <?php echo number_format( $this->profile->averages['plugin_calls'] ); ?> calls <em class="p3-em">avg.</em>
974
  </td>
975
  </tr>
976
  <tr>
977
- <td class="qtip-tip" title="The amount of RAM usage observed. This is reported by memory_get_peak_usage().
978
- Lower is better.">
979
- <strong>Memory Usage: </strong>
980
  </td>
981
  <td>
982
- <?php echo number_format( $this->profile->averages['memory'] / 1024 / 1024, 2 ); ?> MB <em class="p3-em">avg.</em>
983
  </td>
984
  </tr>
985
  <tr>
986
- <td class="qtip-tip" title="The count of queries sent to the database. This is reported by the WordPress function
987
- get_num_queries(). Lower is better.">
988
- <strong>MySQL Queries: </strong>
989
  </td>
990
  <td>
991
- <?php echo round( $this->profile->averages['queries'] ); ?> queries <em class="p3-em">avg.</em>
992
  </td>
993
  </tr>
994
  </tbody>
@@ -1000,80 +976,98 @@ $component_runtime_chart_id = substr( md5( uniqid() ), -8 );
1000
  <!-- Email these results -->
1001
  <div class="button" id="p3-email-results" style="width: 155px; padding: 5px;">
1002
  <img src="<?php echo plugins_url(); ?>/p3-profiler/css/icon_mail.gif" height="22" width="22" align="center"
1003
- alt="Email these results" title="Email these results" />
1004
- <a href="javascript:;">Email these results</a>
1005
  </div>
1006
 
1007
  <!-- Email results dialog -->
1008
  <div id="p3-email-results-dialog" class="p3-dialog">
1009
  <div>
1010
- <span id="p3-email-from-label">From:</span><br />
1011
  <input type="text" id="p3-email-results-from" style="width:95%;" size="35"
1012
- value="<?php $user = wp_get_current_user(); echo $user->user_email; ?>" title="Enter the e-mail address to send from" />
1013
  </div>
1014
  <br />
1015
  <div>
1016
- <span id="p3-email-recipient-label">Recipient:</span><br />
1017
  <input type="text" id="p3-email-results-to" style="width:95%;" size="35"
1018
  value="<?php $user = wp_get_current_user(); echo $user->user_email; ?>"
1019
- title="Enter the e-mail address where you would like to send these results" />
1020
  </div>
1021
  <br />
1022
  <div>
1023
- <span id="p3-email-subject-label">Subject:</span><br />
1024
  <input type="text" id="p3-email-results-subject" style="width:95%;" size="35"
1025
- value="Performance Profile Results - <?php bloginfo( 'name' ); ?>" title="Enter the e-mail subject" />
1026
  </div>
1027
  <br />
1028
  <div>
1029
- <span id="p3-email-message-label">Message: <em class="p3-em">(optional)</em><br /></span>
1030
- <textarea id="p3-email-results-message" style="width: 95%; height: 100px;">Hello,
1031
 
1032
  I profiled my WordPress site's performance using the Profile Plugin and I wanted
1033
- to share the results with you. Please take a look at the information below:</textarea>
1034
  </div>
1035
  <br />
1036
  <div>
1037
- <span id="p3-email-results-label">Results: <em class="p3-em">(system generated, do not edit)</em></span><br />
1038
  <textarea disabled="disabled" id="p3-email-results-results" style="width: 95%; height: 120px;"><?php
1039
- echo "WordPress Plugin Profile Report\n";
1040
- echo "===========================================\n";
1041
- echo 'Report date: ' . date( 'D M j, Y', $this->profile->report_date ) . "\n";
1042
- echo 'Theme name: ' . $this->profile->theme_name . "\n";
1043
- echo 'Pages browsed: ' . $this->profile->visits . "\n";
1044
- echo 'Avg. load time: ' . sprintf( '%.4f', $this->profile->averages['site'] ) . " sec\n";
1045
- echo 'Number of plugins: ' . count( $this->profile->detected_plugins ) . " \n";
1046
- echo 'Plugin impact: ' . sprintf( '%.2f%%', $this->profile->averages['plugin_impact'] ) . " % of load time\n";
1047
- echo 'Avg. plugin time: ' . sprintf( '%.4f', $this->profile->averages['plugins'] ) . " sec\n";
1048
- echo 'Avg. core time: ' . sprintf( '%.4f', $this->profile->averages['core'] ) . " sec\n";
1049
- echo 'Avg. theme time: ' . sprintf( '%.4f', $this->profile->averages['theme'] ) . " sec\n";
1050
- echo 'Avg. mem usage: ' . number_format( $this->profile->averages['memory'] / 1024 / 1024, 2 ) . " MB\n";
1051
- echo 'Avg. plugin calls: ' . number_format( $this->profile->averages['plugin_calls'] ) . "\n";
1052
- echo 'Avg. db queries : ' . sprintf( '%.2f', $this->profile->averages['queries'] ) . "\n";
1053
- echo 'Margin of error : ' . sprintf( '%.4f', $this->profile->averages['drift'] ) . " sec\n";
1054
- echo "\nPlugin list:\n";
1055
- echo "===========================================\n";
1056
- foreach ( $this->profile->plugin_times as $k => $v) {
1057
- echo $k . ' - ' . sprintf('%.4f sec', $v) . ' - ' . sprintf( '%.2f%%', $v * 100 / array_sum( $this->profile->plugin_times ) ) . "\n";
1058
  }
1059
- ?></textarea>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1060
  </div>
1061
- <input type="hidden" id="p3-email-results-scan" value="<?php echo basename( $this->scan ); ?>" />
1062
  </div>
1063
 
1064
  <!-- Email sending dialog -->
1065
  <div id="p3-email-sending-dialog" class="p3-dialog">
1066
  <div id="p3-email-sending-loading">
1067
- <img src="<?php echo get_site_url() . '/wp-admin/images/loading.gif' ?>" height="16" width="16" title="Loading" alt="Loading" />
1068
  </div>
1069
  <div id="p3-email-sending-error">
1070
- There was a problem sending the e-mail: <span id="p3-email-error"></span>
1071
  </div>
1072
  <div id="p3-email-sending-success">
1073
- Your report was sent successfully to <span id="p3-email-success-recipient"></span>
1074
  </div>
1075
  <div id="p3-email-sending-close">
1076
- <input type="checkbox" id="p3-email-sending-close-submit" checked="checked" /><label for="p3-email-sending-close-submit">Done</label>
1077
  </div>
1078
  </div>
1079
 
3
  die( 'Forbidden ');
4
  $url_stats = array();
5
  $domain = '';
6
+ if ( !empty( self::$profile ) ) {
7
+ $url_stats = self::$profile->get_stats_by_url();
8
+ $domain = @parse_url( self::$profile->report_url, PHP_URL_HOST );
9
  }
10
  $pie_chart_id = substr( md5( uniqid() ), -8 );
11
  $runtime_chart_id = substr( md5( uniqid() ), -8 );
21
 
22
  // Raw json data ( used in the charts for tooltip data
23
  var _data = [];
24
+ <?php if ( !empty( self::$scan ) && file_exists( self::$scan ) ) { ?>
25
+ <?php foreach ( file( self::$scan, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES ) as $line ) { ?>
26
  _data.push(<?php echo $line; ?>);
27
  <?php } ?>
28
  <?php } ?>
48
  'modal' : true,
49
  'width' : 400,
50
  'height' : 'auto',
51
+ 'title' : "<?php _e( 'Toggle Series', 'p3-profiler' ); ?>",
52
  'buttons' :
53
  [
54
  {
55
+ text: '<?php _e( 'OK', 'p3-profiler' ); ?>',
56
  'class' : 'button-secondary',
57
  click: function() {
58
  $(this).dialog( "close" );
68
  'modal' : true,
69
  'width' : 500,
70
  'height' : 560,
71
+ 'title' : "<?php _e( 'Email Report', 'p3-profiler' ); ?>",
72
  'buttons' :
73
  [
74
  {
75
+ text: '<?php _e( 'Send', 'p3-profiler' ); ?>',
76
  'class' : 'button-secondary',
77
  click: function() {
78
  data = {
94
 
95
  // Send the data
96
  jQuery.post( ajaxurl, data, function( response ) {
97
+ response = response.trim();
98
  if ( "1" == response.substring( 0, 1 ) ) {
99
  $( "#p3-email-success-recipient" ).html( jQuery( '#p3-email-results-to' ).val() );
100
  $( "#p3-email-sending-success" ).show();
118
  }
119
  },
120
  {
121
+ text: '<?php _e( 'Cancel', 'p3-profiler' ) ?>',
122
  'class': 'p3-cancel-button',
123
  click: function() {
124
  $( this ).dialog( "close" );
165
  /** Plugin pie chart **/
166
  /**************************************************************/
167
  var data_<?php echo $pie_chart_id; ?> = [
168
+ <?php if ( !empty( self::$profile ) ){ ?>
169
+ <?php foreach ( self::$profile->plugin_times as $k => $v ) { ?>
170
  {
171
  label: "<?php echo esc_js( $k ); ?>",
172
  data: <?php echo $v; ?>
173
  },
174
  <?php } ?>
175
  <?php } else { ?>
176
+ { label: '<?php _e( 'No plugins', 'p3-profiler' ); ?>', data: 1}
177
  <?php } ?>
178
  ];
179
  jQuery( document ).ready( function( $) {
203
  $( "#p3-tooltip" ).remove();
204
  showTooltip( pos.pageX, pos.pageY,
205
  item.series.label + "<br />" + Math.round( item.series.percent ) + "%<br />" +
206
+ Math.round( item.datapoint[1][0][1] * Math.pow( 10, 4 ) ) / Math.pow( 10, 4 ) + " <?php _e( 'seconds', 'p3-profiler' ); ?>"
207
  );
208
  } else {
209
  $( "#p3-tooltip" ).remove();
219
  var chart_<?php echo $runtime_chart_id; ?> = null;
220
  var data_<?php echo $runtime_chart_id; ?> = [
221
  {
222
+ label: "<?php _e( 'WP Core time', 'p3-profiler' ); ?>",
223
  data: [
224
  <?php foreach ( array_values( $url_stats ) as $k => $v ) { ?>
225
  [
230
  ]
231
  },
232
  {
233
+ label: "<?php _e( 'Theme time', 'p3-profiler' ); ?>",
234
  data: [
235
  <?php foreach ( array_values( $url_stats ) as $k => $v ) { ?>
236
  [
241
  ]
242
  },
243
  {
244
+ label: "<?php _e( 'Plugin time', 'p3-profiler' ); ?>",
245
  data: [
246
  <?php foreach ( array_values( $url_stats ) as $k => $v ) { ?>
247
  [
308
  showTooltip( item.pageX, item.pageY,
309
  item.series.label + "<br />" +
310
  url + "<br />" +
311
+ y + " <?php _e( 'seconds', 'p3-profiler' ); ?>" );
312
  }
313
  } else {
314
  $( "#p3-tooltip" ).remove();
325
  var chart_<?php echo $query_chart_id; ?> = null;
326
  var data_<?php echo $query_chart_id; ?> = [
327
  {
328
+ label: "<?php _e( '# of Queries', 'p3-profiler' ); ?>",
329
  data: [
330
+ <?php if ( !empty( self::$profile ) ){ ?>
331
  <?php foreach ( array_values( $url_stats ) as $k => $v ) { ?>
332
  [
333
  <?php echo $k + 1; ?>,
391
  // Get rid of the domain
392
  url = url.replace(/http[s]?:\/\/<?php echo $domain; ?>(:\d+)?/, "" );
393
 
394
+ qword = ( y == 1 ) ? "<?php _e( 'query', 'p3-profiler' ); ?>" : "<?php _e( 'queries', 'p3-profiler' ); ?>";
395
  showTooltip( item.pageX, item.pageY,
396
  item.series.label + "<br />" +
397
  url + "<br />" +
411
  var chart_<?php echo $component_breakdown_chart_id; ?> = null;
412
  var data_<?php echo $component_breakdown_chart_id; ?> = [
413
  {
414
+ label: '<?php _e( 'Site Load Time', 'p3-profiler' ); ?>',
415
  bars: {show: false},
416
  points: {show: false},
417
  lines: {show: true, lineWidth: 3},
420
  <?php for ( $i = -999 ; $i < 999 + 2; $i++ ) { ?>
421
  [
422
  <?php echo $i; ?>,
423
+ <?php echo self::$profile->averages['site']; ?>
424
  ],
425
  <?php } ?>
426
  ]
427
  },
428
  {
429
+ label: '<?php _e( 'WP Core Time', 'p3-profiler' ); ?>',
430
+ data: [[0, <?php echo self::$profile->averages['core']; ?>]]
431
  },
432
  {
433
+ label: '<?php _e( 'Theme', 'p3-profiler' ); ?>',
434
+ data: [[1, <?php echo self::$profile->averages['theme']; ?>]]
435
  },
436
  <?php $i = 2; $other = 0; ?>
437
+ <?php foreach ( self::$profile->plugin_times as $k => $v ) { ?>
438
  {
439
  label: '<?php echo esc_js( $k ); ?>',
440
  data: [[
469
  xaxis: {
470
  show: false,
471
  ticks: [
472
+ [0, '<?php _e( 'Site Load Time', 'p3-profiler' ); ?>'],
473
+ [1, '<?php _e( 'WP Core Time', 'p3-profiler' ); ?>'],
474
+ [2, '<?php _e( 'Theme', 'p3-profiler' ); ?>'],
475
  <?php $i = 3; ?>
476
+ <?php foreach ( self::$profile->plugin_times as $k => $v ) { ?>
477
  [
478
  <?php echo $i++ ?>,
479
  '<?php echo esc_js( $k ); ?>'
498
  if ( item ) {
499
  $( "#p3-tooltip" ).remove();
500
  showTooltip( pos.pageX, pos.pageY,
501
+ item.series.label + "<br />" + Math.round( item.datapoint[1] * Math.pow( 10, 4 ) ) / Math.pow( 10, 4 ) + " <?php _e('seconds', 'p3-profiler' ); ?>"
502
  );
503
  } else {
504
  $( "#p3-tooltip" ).remove();
524
  var chart_<?php echo $component_runtime_chart_id; ?> = null;
525
  var data_<?php echo $component_runtime_chart_id; ?> = [
526
  {
527
+ label: "<?php _e( 'WP Core Time', 'p3-profiler' ); ?>",
528
  data: [
529
+ <?php if ( !empty( self::$profile ) ){ ?>
530
  <?php foreach ( array_values( $url_stats ) as $k => $v ) { ?>
531
  [
532
  <?php echo $k + 1; ?>,
537
  ]
538
  },
539
  {
540
+ label: "<?php _e( 'Theme', 'p3-profiler' ); ?>",
541
  data: [
542
+ <?php if ( !empty( self::$profile ) ){ ?>
543
  <?php foreach ( array_values( $url_stats ) as $k => $v ) { ?>
544
  [
545
  <?php echo $k + 1; ?>,
549
  <?php } ?>
550
  ]
551
  },
552
+ <?php if ( !empty( self::$profile ) && !empty( self::$profile->detected_plugins ) ) { ?>
553
+ <?php foreach ( self::$profile->detected_plugins as $plugin ) { ?>
554
  {
555
  label: "<?php echo esc_js( $plugin ); ?>",
556
  data: [
573
  var detailed_timeline_options = {};
574
 
575
  jQuery( document ).ready( function ( $ ) {
576
+ <?php if ( !empty( self::$profile ) && !empty( self::$profile->detected_plugins ) ) { ?>
577
+ jQuery( "#p3-detailed-series-toggle" ).append( '<div><label><input type="checkbox" checked="checked" class="p3-detailed-series-toggle" data-key="<?php esc_attr_e( 'WP Core Time', 'p3-profiler' ); ?>" /><?php _e( 'WP Core Time', 'p3-profiler' ); ?></label></div>' );
578
+ jQuery( "#p3-detailed-series-toggle" ).append( '<div><label><input type="checkbox" checked="checked" class="p3-detailed-series-toggle" data-key="<?php esc_attr_e( 'Theme', 'p3-profiler' ); ?>" /><?php _e( 'Theme', 'p3-profiler' ); ?></label></div>' );
579
+ <?php foreach ( self::$profile->detected_plugins as $plugin ) { ?>
580
  jQuery( "#p3-detailed-series-toggle" ).append( '<div><label><input type="checkbox" checked="checked" class="p3-detailed-series-toggle" data-key="<?php echo esc_html( $plugin ); ?>" /><?php echo esc_html( $plugin ); ?></label></div>' );
581
  <?php } ?>
582
  <?php } ?>
604
  data = [
605
  {
606
  data: [],
607
+ label: '<?php _e( 'No data', 'p3-profiler' ); ?>'
608
  }
609
  ]
610
  }
661
  showTooltip( item.pageX, item.pageY,
662
  item.series.label + "<br />" +
663
  url + "<br />" +
664
+ y + " <?php _e( 'seconds', 'p3-profiler' ); ?>" );
665
  }
666
  } else {
667
  $( "#p3-tooltip" ).remove();
695
  </script>
696
  <div id="p3-tabs">
697
  <ul>
698
+ <li><a href="#p3-tabs-1"><?php _e( 'Runtime By Plugin', 'p3-profiler' ); ?></a></li>
699
+ <li><a href="#p3-tabs-5"><?php _e( 'Detailed Breakdown', 'p3-profiler' ); ?></a></li>
700
+ <li><a href="#p3-tabs-2"><?php _e( 'Simple Timeline', 'p3-profiler' ); ?></a></li>
701
+ <li><a href="#p3-tabs-6"><?php _e( 'Detailed Timeline', 'p3-profiler' ); ?></a></li>
702
+ <li><a href="#p3-tabs-3"><?php _e( 'Query Timeline', 'p3-profiler' ); ?></a></li>
703
+ <li><a href="#p3-tabs-4"><?php _e( 'Advanced Metrics', 'p3-profiler' ); ?></a></li>
704
  </ul>
705
 
706
  <!-- Plugin bar chart -->
707
  <div id="p3-tabs-5">
708
+ <h2><?php _e( 'Detailed Breakdown', 'p3-profiler' ); ?></h2>
709
  <div class="p3-plugin-graph">
710
  <table>
711
  <tr>
712
  <td rowspan="2">
713
  <div class="p3-y-axis-label">
714
+ <em class="p3-em"><?php _e( 'Seconds', 'p3-profiler' ); ?></em>
715
  </div>
716
  </td>
717
  <td rowspan="2">
718
  <div class="p3-graph-holder" id="p3-holder_<?php echo $component_breakdown_chart_id; ?>"></div>
719
  </td>
720
  <td>
721
+ <h3><?php _ex( 'Legend', 'How to interpret the chart or graph', 'p3-profiler' ); ?></h3>
722
  </td>
723
  </tr>
724
  <tr>
730
  <td>&nbsp;</td>
731
  <td colspan="2">
732
  <div class="p3-x-axis-label" style="top: -10px;">
733
+ <em class="p3-em"><?php _e( 'Component', 'p3-profiler' ); ?></em>
734
  </div>
735
  </td>
736
  </tr>
740
 
741
  <!-- Plugin pie chart div -->
742
  <div id="p3-tabs-1">
743
+ <h2><?php _e( 'Runtime by Plugin', 'p3-profiler' ); ?></h2>
744
  <div class="p3-plugin-graph" style="width: 570px;">
745
  <table>
746
  <tr>
748
  <div style="width: 370px;" class="p3-graph-holder" id="p3-holder_<?php echo $pie_chart_id; ?>"></div>
749
  </td>
750
  <td>
751
+ <h3><?php _ex( 'Legend', 'How to interpret the chart or graph', 'p3-profiler' ); ?></h3>
752
  </td>
753
  </tr>
754
  <tr>
762
 
763
  <!-- Runtime line chart div -->
764
  <div id="p3-tabs-2">
765
+ <h2><?php _e( 'Summary Timeline', 'p3-profiler' ); ?></h2>
766
  <div class="p3-plugin-graph">
767
  <table>
768
  <tr>
769
  <td rowspan="2">
770
  <div class="p3-y-axis-label">
771
+ <em class="p3-em"><?php _e( 'Seconds', 'p3-profiler' ); ?></em>
772
  </div>
773
  </td>
774
  <td rowspan="2">
775
  <div class="p3-graph-holder" id="p3-holder_<?php echo $runtime_chart_id; ?>"></div>
776
  </td>
777
  <td>
778
+ <h3><?php _ex( 'Legend', 'How to interpret the chart or graph', 'p3-profiler' ); ?></h3>
779
  </td>
780
  </tr>
781
  <tr>
797
 
798
  <!-- Query line chart div -->
799
  <div id="p3-tabs-3">
800
+ <h2><?php _e( 'Query Timeline', 'p3-profiler' ); ?></h2>
801
  <div class="p3-plugin-graph">
802
  <table>
803
  <tr>
804
  <td rowspan="2">
805
  <div class="p3-y-axis-label">
806
+ <em class="p3-em"><?php _e( 'Queries', 'p3-profiler' ) ;?></em>
807
  </div>
808
  </td>
809
  <td rowspan="2">
810
  <div class="p3-graph-holder" id="p3-holder_<?php echo $query_chart_id; ?>"></div>
811
  </td>
812
  <td>
813
+ <h3><?php _ex( 'Legend', 'How to interpret the chart or graph', 'p3-profiler' ); ?></h3>
814
  </td>
815
  </tr>
816
  <tr>
832
 
833
  <!-- Component runtime chart div -->
834
  <div id="p3-tabs-6">
835
+ <h2><?php _e( 'Detailed Timeline', 'p3-profiler' ); ?></h2>
836
  <div class="p3-plugin-graph">
837
  <table>
838
  <tr>
839
  <td rowspan="2">
840
  <div class="p3-y-axis-label">
841
+ <em class="p3-em"><?php _e( 'Seconds', 'p3-profiler' ); ?></em>
842
  </div>
843
  </td>
844
  <td rowspan="2">
845
  <div class="p3-graph-holder" id="p3-holder_<?php echo $component_runtime_chart_id; ?>"></div>
846
  </td>
847
  <td>
848
+ <h3><?php _ex( 'Legend', 'How to interpret the chart or graph', 'p3-profiler' ); ?></h3>
849
  </td>
850
  </tr>
851
  <tr>
869
  <div id="p3-tabs-4">
870
  <div id="p3-metrics-container">
871
  <div class="ui-widget-header" id="p3-metrics-header" style="padding: 8px;">
872
+ <strong><?php _e( 'Advanced Metrics', 'p3-profiler' ); ?></strong>
873
  </div>
874
  <div>
875
  <table class="p3-results-table" id="p3-results-table" cellpadding="0" cellspacing="0" border="0">
876
  <tbody>
877
  <tr class="advanced">
878
+ <td class="qtip-tip" title="<?php esc_attr_e( "The time the site took to load. This is an observed measurement (start timing when the page was requested, stop timing when the page was delivered to the browser, calculate the difference). Lower is better.", 'p3-profiler' ); ?>">
879
+ <strong><?php _e( 'Total Load Time:', 'p3-profiler' ); ?></strong>
 
 
880
  </td>
881
  <td>
882
+ <?php printf( '%.4f', self::$profile->averages['total'] ); ?><?php _e( 'seconds', 'p3-profiler' ); ?> <em class="p3-em"><?php _ex( 'avg.', "Abbreviation for 'average'", 'p3-profiler' ); ?></em>
883
  </td>
884
  </tr>
885
  <tr>
886
+ <td class="qtip-tip" title="<?php esc_attr_e( "The calculated total load time minus the profile overhead. This is closer to your site's real-life load time. Lower is better.", 'p3-profiler' ); ?>">
887
+ <strong><?php _e( 'Site Load Time', 'p3-profiler' ); ?></small></em></strong>
 
888
  </td>
889
  <td>
890
+ <?php printf( '%.4f', self::$profile->averages['site'] ); ?><?php _e( 'seconds', 'p3-profiler' ); ?> <em class="p3-em"><?php _ex( 'avg.', "Abbreviation for 'average'", 'p3-profiler' ); ?></em>
891
  </td>
892
  </tr>
893
  <tr class="advanced">
894
+ <td class="qtip-tip" title="<?php esc_attr_e( "The load time spent profiling code. Because the profiler slows down your load time, it is important to know how much impact the profiler has. However, it doesn't impact your site's real-life load time.", 'p3-profiler' ); ?>">
895
+ <strong><?php _e( 'Profile Overhead:', 'p3-profiler' ); ?></strong>
 
 
896
  </td>
897
  <td>
898
+ <?php printf( '%.4f', self::$profile->averages['profile'] ); ?><?php _e( 'seconds', 'p3-profiler' ); ?> <em class="p3-em"><?php _ex( 'avg.', "Abbreviation for 'average'", 'p3-profiler' ); ?></em>
899
  </td>
900
  </tr>
901
  <tr>
902
+ <td class="qtip-tip" title="<?php esc_attr_e( "The load time caused by plugins. Because of WordPress' construction, we can trace a function call from a plugin through a theme through the core. The profiler prioritizes plugin calls first, theme calls second, and core calls last. Lower is better.", 'p3-profiler' ); ?>">
903
+ <strong><?php _e( 'Plugin Load Time:', 'p3-profiler' ); ?></strong>
 
 
904
  </td>
905
  <td>
906
+ <?php printf( '%.4f', self::$profile->averages['plugins'] ); ?><?php _e( 'seconds', 'p3-profiler' ); ?> <em class="p3-em"><?php _ex( 'avg.', "Abbreviation for 'average'", 'p3-profiler' ); ?></em>
907
  </td>
908
  </tr>
909
  <tr>
910
+ <td class="qtip-tip" title="<?php esc_attr_e( "The load time spent applying the theme. Because of WordPress' construction, we can trace a function call from a plugin through a theme through the core. The profiler prioritizes plugin calls first, theme calls second, and core calls last. Lower is better.", 'p3-profiler' ); ?>">
911
+ <strong><?php _e( 'Theme Load Time:', 'p3-profiler' ); ?></strong>
 
 
912
  </td>
913
  <td>
914
+ <?php printf( '%.4f', self::$profile->averages['theme'] ); ?><?php _e( 'seconds', 'p3-profiler' ); ?> <em class="p3-em"><?php _ex( 'avg.', "Abbreviation for 'average'", 'p3-profiler' ); ?></em>
915
  </td>
916
  </tr>
917
  <tr>
918
+ <td class="qtip-tip" title="<?php esc_attr_e( "The load time caused by the WordPress core. Because of WordPress' construction, we can trace a function call from a plugin through a theme through the core. The profiler prioritizes plugin calls first, theme calls second, and core calls last. This will probably be constant.", 'p3-profiler' ); ?>">
919
+ <strong><?php _e( 'Core Load Time:', 'p3-profiler' ); ?></strong>
 
 
920
  </td>
921
  <td>
922
+ <?php printf( '%.4f', self::$profile->averages['core'] ); ?><?php _e( 'seconds', 'p3-profiler' ); ?> <em class="p3-em"><?php _ex( 'avg.', "Abbreviation for 'average'", 'p3-profiler' ); ?></em>
923
  </td>
924
  </tr>
925
  <tr class="advanced">
926
+ <td class="qtip-tip" title="<?php esc_attr_e( "This is the difference between the observed runtime (what actually happened) and expected runtime (adding the plugin runtime, theme runtime, core runtime, and profiler overhead). There are several reasons this margin of error can exist. Most likely, the profiler is missing microseconds while adding the runtime it observed. Using a network clock to set the time (NTP) can also cause minute timing changes. Ideally, this number should be zero, but there's nothing you can do to change it. It will give you an idea of how accurate the other results are.", 'p3-profiler' ); ?>">
927
+ <strong><?php _e( 'Margin of Error:', 'p3-profiler' ); ?></strong>
 
 
 
 
 
 
928
  </td>
929
  <td>
930
+ <?php printf( '%.4f', self::$profile->averages['drift'] ); ?><?php _e( 'seconds', 'p3-profiler' ); ?> <em class="p3-em"><?php _ex( 'avg.', "Abbreviation for 'average'", 'p3-profiler' ); ?></em>
931
  <br />
932
  <em class="p3-em">
933
+ (<span class="qtip-tip" title="<?php esc_attr_e( "How long the site took to load. This is an observed measurement (start timing when the page was requested, stop timing when the page was delivered to the browser, calculate the difference).", 'p3-profiler' ); ?>"><?php printf( '%.4f', self::$profile->averages['observed'] ); ?> <?php _e( 'observed', 'p3-profiler' ); ?></span>,
934
+ <span class="qtip-tip" title="<?php esc_attr_e( "The expected site load time calculated by adding plugin load time, core load time, theme load time, and profiler overhead.", 'p3-profiler' ); ?>"><?php printf( '%.4f', self::$profile->averages['expected'] ); ?> <?php _e( 'expected', 'p3-profiler' ); ?></span>)
 
 
 
 
935
  </em>
936
  </td>
937
  </tr>
938
  <tr class="advanced">
939
+ <td class="qtip-tip" title="<?php esc_attr_e( "The number of visits registered during a profiling session. More visits produce a more accurate summary.", 'p3-profiler' ); ?>">
940
+ <strong><?php _e( 'Visits:', 'p3-profiler' ); ?></strong>
 
941
  </td>
942
  <td>
943
+ <?php echo number_format( self::$profile->visits ); ?>
944
  </td>
945
  </tr>
946
  <tr class="advanced">
947
+ <td class="qtip-tip" title="<?php esc_attr_e( "The number of PHP ticks recorded during the profiling session. A tick is loosely correlated to a PHP statement or function call. Fewer is better.", 'p3-profiler' ); ?>">
948
+ <strong><?php _e ( 'Number of PHP ticks:', 'p3-profiler' ); ?></strong>
949
  </td>
950
  <td>
951
+ <?php echo number_format( self::$profile->averages['plugin_calls'] ); ?> <?php _e( 'calls', 'p3-profiler' ); ?> <em class="p3-em"><?php _ex( 'avg.', "Abbreviation for 'average'", 'p3-profiler' ); ?></em>
952
  </td>
953
  </tr>
954
  <tr>
955
+ <td class="qtip-tip" title="<?php esc_attr_e( "The amount of RAM usage observed. This is reported by memory_get_peak_usage(). Lower is better.", 'p3-profiler' ); ?>">
956
+ <strong><?php _e( 'Memory Usage:', 'p3-profiler' ); ?></strong>
 
957
  </td>
958
  <td>
959
+ <?php echo number_format( self::$profile->averages['memory'] / 1024 / 1024, 2 ); ?> <?php _ex( 'MB', 'Abbreviation for megabytes', 'p3-profiler' ); ?> <em class="p3-em"><?php _ex( 'avg.', "Abbreviation for 'average'", 'p3-profiler' ); ?></em>
960
  </td>
961
  </tr>
962
  <tr>
963
+ <td class="qtip-tip" title="<?php esc_attr_e( "The count of queries sent to the database. This is reported by the WordPress function get_num_queries(). Lower is better.", 'p3-profiler' ); ?>">
964
+ <strong><?php _e( 'MySQL Queries:', 'p3-profiler' ); ?></strong>
 
965
  </td>
966
  <td>
967
+ <?php echo round( self::$profile->averages['queries'] ); ?> <?php _e( 'queries', 'p3-profiler' ); ?> <em class="p3-em"><?php _ex( 'avg.', "Abbreviation for 'average'", 'p3-profiler' ); ?></em>
968
  </td>
969
  </tr>
970
  </tbody>
976
  <!-- Email these results -->
977
  <div class="button" id="p3-email-results" style="width: 155px; padding: 5px;">
978
  <img src="<?php echo plugins_url(); ?>/p3-profiler/css/icon_mail.gif" height="22" width="22" align="center"
979
+ alt="<?php esc_attr_e( 'Email these results', 'p3-profiler' ); ?>" title="<?php esc_attr_e( 'Email these results', 'p3-profiler' ); ?>" />
980
+ <a href="javascript:;"><?php _e ( 'Email these results', 'p3-profiler' ); ?></a>
981
  </div>
982
 
983
  <!-- Email results dialog -->
984
  <div id="p3-email-results-dialog" class="p3-dialog">
985
  <div>
986
+ <span id="p3-email-from-label"><?php _e( 'From:', 'p3-profiler' ); ?></span><br />
987
  <input type="text" id="p3-email-results-from" style="width:95%;" size="35"
988
+ value="<?php $user = wp_get_current_user(); echo $user->user_email; ?>" title="<?php esc_attr_e( 'Enter the e-mail address to send from', 'p3-profiler' ); ?>" />
989
  </div>
990
  <br />
991
  <div>
992
+ <span id="p3-email-recipient-label"><?php _e( 'Recipient:', 'p3-profiler' ); ?></span><br />
993
  <input type="text" id="p3-email-results-to" style="width:95%;" size="35"
994
  value="<?php $user = wp_get_current_user(); echo $user->user_email; ?>"
995
+ title="<?php esc_attr_e( 'Enter the e-mail address where you would like to send these results', 'p3-profiler' ); ?>" />
996
  </div>
997
  <br />
998
  <div>
999
+ <span id="p3-email-subject-label"><?php _e( 'Subject:', 'p3-profiler' ); ?></span><br />
1000
  <input type="text" id="p3-email-results-subject" style="width:95%;" size="35"
1001
+ value="<?php echo esc_attr( sprintf( __( 'Performance Profile Results for %s', 'p3-profiler' ), get_bloginfo( 'name' ) ) ); ?>" title="<?php esc_attr_e( 'Enter the e-mail subject', 'p3-profiler' ); ?>" />
1002
  </div>
1003
  <br />
1004
  <div>
1005
+ <span id="p3-email-message-label"><?php _e( 'Message:', 'p3-profiler' ); ?> <em class="p3-em"><?php _e( '(optional)', 'p3-profiler' ); ?></em><br /></span>
1006
+ <textarea id="p3-email-results-message" style="width: 95%; height: 100px;"><?php esc_html_e("Hello,
1007
 
1008
  I profiled my WordPress site's performance using the Profile Plugin and I wanted
1009
+ to share the results with you. Please take a look at the information below:", 'p3-profiler' ); ?></textarea>
1010
  </div>
1011
  <br />
1012
  <div>
1013
+ <span id="p3-email-results-label"><?php _e( 'Results:', 'p3-profiler' ); ?> <em class="p3-em"><?php _e( '(system generated, do not edit)', 'p3-profiler' ); ?></em></span><br />
1014
  <textarea disabled="disabled" id="p3-email-results-results" style="width: 95%; height: 120px;"><?php
1015
+ $plugin_list = '';
1016
+ foreach ( self::$profile->plugin_times as $k => $v) {
1017
+ $plugin_list .= $k . ' - ' . sprintf('%.4f sec', $v) . ' - ' . sprintf( '%.2f%%', $v * 100 / array_sum( self::$profile->plugin_times ) ) . "\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1018
  }
1019
+ printf( __( "WordPress Plugin Profile Report
1020
+ ===========================================
1021
+ Report date: %1\$s
1022
+ Theme name: %2\$s
1023
+ Pages browsed: %3\$s
1024
+ Avg. load time: %4\$s sec
1025
+ Number of plugins: %5\$s
1026
+ Plugin impact: %6\$s of load time
1027
+ Avg. plugin time: %7\$s sec
1028
+ Avg. core time: %8\$s sec
1029
+ Avg. theme time: %9\$s sec
1030
+ Avg. mem usage: %10\$s MB
1031
+ Avg. ticks: %11\$s
1032
+ Avg. db queries : %12\$s
1033
+ Margin of error : %13\$s sec
1034
+
1035
+ Plugin list:
1036
+ ===========================================
1037
+ %14\$s
1038
+ ", 'p3-profiler' ),
1039
+ date_i18n( get_option( 'date_format' ), self::$profile->report_date ),
1040
+ self::$profile->theme_name,
1041
+ self::$profile->visits,
1042
+ sprintf( '%.4f', self::$profile->averages['site'] ),
1043
+ count( self::$profile->detected_plugins ),
1044
+ sprintf( '%.2f%%', self::$profile->averages['plugin_impact'] ),
1045
+ sprintf( '%.4f', self::$profile->averages['plugins'] ),
1046
+ sprintf( '%.4f', self::$profile->averages['core'] ),
1047
+ sprintf( '%.4f', self::$profile->averages['theme'] ),
1048
+ number_format( self::$profile->averages['memory'] / 1024 / 1024, 2 ),
1049
+ number_format( self::$profile->averages['plugin_calls'] ),
1050
+ sprintf( '%.2f', self::$profile->averages['queries'] ),
1051
+ sprintf( '%.4f', self::$profile->averages['drift'] ),
1052
+ $plugin_list
1053
+ ); ?></textarea>
1054
  </div>
1055
+ <input type="hidden" id="p3-email-results-scan" value="<?php echo basename( self::$scan ); ?>" />
1056
  </div>
1057
 
1058
  <!-- Email sending dialog -->
1059
  <div id="p3-email-sending-dialog" class="p3-dialog">
1060
  <div id="p3-email-sending-loading">
1061
+ <img src="<?php echo get_site_url() . '/wp-admin/images/loading.gif' ?>" height="16" width="16" title="<? esc_attr_e( 'Loading', 'p3-profiler' ); ?>" alt="<?php esc_attr_e( 'Loading', 'p3-profiler' ); ?>" />
1062
  </div>
1063
  <div id="p3-email-sending-error">
1064
+ <?php _e( 'There was a problem sending the e-mail:', 'p3-profiler' ); ?> <span id="p3-email-error"></span>
1065
  </div>
1066
  <div id="p3-email-sending-success">
1067
+ <?php _e( 'Your report was sent successfully to', 'p3-profiler' ); ?> <span id="p3-email-success-recipient"></span>
1068
  </div>
1069
  <div id="p3-email-sending-close">
1070
+ <input type="checkbox" id="p3-email-sending-close-submit" checked="checked" /><label for="p3-email-sending-close-submit"><?php _e( 'Done', 'p3-profiler' ); ?></label>
1071
  </div>
1072
  </div>
1073
 
uninstall.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if( !defined( 'ABSPATH' ) && !defined( 'WP_UNINSTALL_PLUGIN' ) )
4
+ exit();
5
+
6
+ // Define the profiles path
7
+ $uploads_dir = wp_upload_dir();
8
+ $profile_path = $uploads_dir['basedir'] . DIRECTORY_SEPARATOR . 'profiles';
9
+
10
+ // Unhook the profiler
11
+ update_option( 'p3-profiler_debug', false );
12
+ update_option( 'p3-profiler_debug_log', array() );
13
+ remove_action( 'shutdown', array( $p3_profiler, 'shutdown_handler' ) );
14
+
15
+ // Delete the profiles folder
16
+ if ( function_exists( 'is_multisite' ) && is_multisite() ) {
17
+ $blogs = get_blog_list( 0, 'all' );
18
+ foreach ( $blogs as $blog ) {
19
+ switch_to_blog( $blog['blog_id'] );
20
+ $uploads_dir = wp_upload_dir();
21
+ $folder = $uploads_dir['basedir'] . DIRECTORY_SEPARATOR . 'profiles' . DIRECTORY_SEPARATOR;
22
+ p3_profiler_uninstall_delete_profiles_folder( $folder );
23
+
24
+ // Remove any options - pre 1.3.0
25
+ delete_option( 'p3-profiler_disable_opcode_cache' );
26
+ delete_option( 'p3-profiler_use_current_ip' );
27
+ delete_option( 'p3-profiler_ip_address' );
28
+ delete_option( 'p3-profiler_cache_buster' );
29
+ delete_option( 'p3-profiler_debug' );
30
+ delete_option( 'p3-profiler_profiling_enabled' );
31
+
32
+ // 1.3.0 and later
33
+ delete_option( 'p3-profiler_version' );
34
+ delete_option( 'p3-profiler_options' );
35
+ delete_option( 'p3-profiler_debug_log' );
36
+ }
37
+ restore_current_blog();
38
+ } else {
39
+ p3_profiler_uninstall_delete_profiles_folder( $profile_path );
40
+
41
+ // Remove any options - pre.1.3.0
42
+ delete_option( 'p3-profiler_disable_opcode_cache' );
43
+ delete_option( 'p3-profiler_use_current_ip' );
44
+ delete_option( 'p3-profiler_ip_address' );
45
+ delete_option( 'p3-profiler_cache_buster' );
46
+ delete_option( 'p3-profiler_debug' );
47
+ delete_option( 'p3-profiler_profiling_enabled' );
48
+
49
+ // 1.3.0 and later
50
+ delete_option( 'p3-profiler_version' );
51
+ delete_option( 'p3-profiler_options' );
52
+ delete_option( 'p3-profiler_debug_log' );
53
+ }
54
+
55
+ function p3_profiler_uninstall_delete_profiles_folder( $path ) {
56
+ if ( !file_exists( $path ) )
57
+ return;
58
+ $dir = opendir( $path );
59
+ while ( ( $file = readdir( $dir ) ) !== false ) {
60
+ if ( $file != '.' && $file != '..' ) {
61
+ unlink( $path . DIRECTORY_SEPARATOR . $file );
62
+ }
63
+ }
64
+ closedir( $dir );
65
+ rmdir( $path );
66
+ }