2013-04-08 15:40:06 +00:00
< ? php
2017-03-27 14:16:00 +00:00
namespace OpcacheGui ;
2013-08-09 14:06:45 +00:00
/**
* OPcache GUI
2014-11-23 01:07:38 +00:00
*
2013-08-09 14:06:45 +00:00
* A simple but effective single - file GUI for the OPcache PHP extension .
2014-11-23 01:07:38 +00:00
*
2013-08-09 14:06:45 +00:00
* @ author Andrew Collington , andy @ amnuts . com
2020-04-06 22:33:57 +00:00
* @ version 2.5 . 3
2014-11-26 21:42:23 +00:00
* @ link https :// github . com / amnuts / opcache - gui
2013-08-09 14:06:45 +00:00
* @ license MIT , http :// acollington . mit - license . org /
*/
2015-05-08 16:04:40 +00:00
/*
* User configuration
*/
$options = [
2017-12-28 19:37:52 +00:00
'allow_filelist' => true , // show/hide the files tab
'allow_invalidate' => true , // give a link to invalidate files
'allow_reset' => true , // give option to reset the whole cache
'allow_realtime' => true , // give option to enable/disable real-time updates
'refresh_time' => 5 , // how often the data will refresh, in seconds
2020-04-06 22:17:29 +00:00
'size_precision' => 2 , // Digits after decimal point
2017-12-28 19:37:52 +00:00
'size_space' => false , // have '1MB' or '1 MB' when showing sizes
'charts' => true , // show gauge chart or just big numbers
'debounce_rate' => 250 , // milliseconds after key press to send keyup event when filtering
'cookie_name' => 'opcachegui' , // name of cookie
2019-07-13 16:17:52 +00:00
'cookie_ttl' => 365 , // days to store cookie
'highlight' => [ // highlight charts/big numbers
'memory' => true ,
'hits' => true ,
'keys' => true
]
2015-05-08 16:04:40 +00:00
];
/*
* Shouldn ' t need to alter anything else below here
*/
2014-11-23 01:07:38 +00:00
if ( ! extension_loaded ( 'Zend OPcache' )) {
2013-04-26 10:56:54 +00:00
die ( 'The Zend OPcache extension does not appear to be installed' );
2013-04-08 15:40:06 +00:00
}
2017-06-07 10:59:24 +00:00
$ocEnabled = ini_get ( 'opcache.enable' );
if ( empty ( $ocEnabled )) {
2019-07-12 00:41:26 +00:00
die ( 'The Zend OPcache extension is installed but not active' );
2017-01-06 13:40:59 +00:00
}
2019-07-12 00:41:26 +00:00
header ( 'Cache-Control: no-cache, must-revalidate' );
header ( 'Pragma: no-cache' );
2014-11-23 01:07:38 +00:00
class OpCacheService
{
2020-04-06 22:33:57 +00:00
const VERSION = '2.5.3' ;
2020-02-22 18:15:23 +00:00
2014-11-25 13:20:33 +00:00
protected $data ;
2015-05-08 16:04:40 +00:00
protected $options ;
2020-02-22 19:51:12 +00:00
protected $optimizationLevels ;
2015-05-08 16:04:40 +00:00
protected $defaults = [
2015-12-30 18:18:03 +00:00
'allow_filelist' => true ,
2015-05-08 16:04:40 +00:00
'allow_invalidate' => true ,
2015-05-11 12:59:53 +00:00
'allow_reset' => true ,
'allow_realtime' => true ,
'refresh_time' => 5 ,
2015-05-08 16:04:40 +00:00
'size_precision' => 2 ,
'size_space' => false ,
2016-02-24 00:26:43 +00:00
'charts' => true ,
2017-12-28 19:37:52 +00:00
'debounce_rate' => 250 ,
'cookie_name' => 'opcachegui' ,
'cookie_ttl' => 365
2014-11-25 13:20:33 +00:00
];
2013-04-26 10:56:54 +00:00
2014-11-25 13:20:33 +00:00
private function __construct ( $options = [])
2014-11-23 01:07:38 +00:00
{
2020-02-22 19:51:12 +00:00
$this -> optimizationLevels = [
2020-02-22 20:15:06 +00:00
1 << 0 => 'CSE, STRING construction' ,
1 << 1 => 'Constant conversion and jumps' ,
1 << 2 => '++, +=, series of jumps' ,
2020-02-22 19:51:12 +00:00
1 << 3 => 'INIT_FCALL_BY_NAME -> DO_FCALL' ,
1 << 4 => 'CFG based optimization' ,
1 << 5 => 'DFA based optimization' ,
1 << 6 => 'CALL GRAPH optimization' ,
1 << 7 => 'SCCP (constant propagation)' ,
1 << 8 => 'TMP VAR usage' ,
1 << 9 => 'NOP removal' ,
1 << 10 => 'Merge equal constants' ,
1 << 11 => 'Adjust used stack' ,
1 << 12 => 'Remove unused variables' ,
1 << 13 => 'DCE (dead code elimination)' ,
1 << 14 => '(unsafe) Collect constants' ,
2020-02-22 20:15:06 +00:00
1 << 15 => 'Inline functions'
2020-02-22 19:51:12 +00:00
];
2020-02-22 20:15:06 +00:00
2015-05-08 16:04:40 +00:00
$this -> options = array_merge ( $this -> defaults , $options );
2014-11-23 01:07:38 +00:00
$this -> data = $this -> compileState ();
2013-08-09 14:06:45 +00:00
}
2013-04-08 15:40:06 +00:00
2014-11-26 21:42:23 +00:00
public static function init ( $options = [])
2014-11-23 01:07:38 +00:00
{
2014-11-26 21:42:23 +00:00
$self = new self ( $options );
2014-11-23 01:07:38 +00:00
if ( ! empty ( $_SERVER [ 'HTTP_X_REQUESTED_WITH' ])
&& strtolower ( $_SERVER [ 'HTTP_X_REQUESTED_WITH' ]) == 'xmlhttprequest'
) {
2015-05-11 12:59:53 +00:00
if ( isset ( $_GET [ 'reset' ]) && $self -> getOption ( 'allow_reset' )) {
2014-11-25 17:11:37 +00:00
echo '{ "success": "' . ( $self -> resetCache () ? 'yes' : 'no' ) . '" }' ;
2015-05-11 12:59:53 +00:00
} else if ( isset ( $_GET [ 'invalidate' ]) && $self -> getOption ( 'allow_invalidate' )) {
2014-11-25 17:11:37 +00:00
echo '{ "success": "' . ( $self -> resetCache ( $_GET [ 'invalidate' ]) ? 'yes' : 'no' ) . '" }' ;
} else {
2015-05-11 14:56:17 +00:00
echo json_encode ( $self -> getData (( empty ( $_GET [ 'section' ]) ? null : $_GET [ 'section' ])));
2014-11-25 17:11:37 +00:00
}
2014-11-23 01:07:38 +00:00
exit ;
2015-05-20 20:51:35 +00:00
} else if ( isset ( $_GET [ 'reset' ]) && $self -> getOption ( 'allow_reset' )) {
2014-11-23 01:07:38 +00:00
$self -> resetCache ();
2016-02-10 00:09:49 +00:00
header ( 'Location: ?' );
exit ;
2015-05-11 12:59:53 +00:00
} else if ( isset ( $_GET [ 'invalidate' ]) && $self -> getOption ( 'allow_invalidate' )) {
2014-11-23 01:07:38 +00:00
$self -> resetCache ( $_GET [ 'invalidate' ]);
2016-02-10 00:09:49 +00:00
header ( 'Location: ?' );
exit ;
2014-11-23 01:07:38 +00:00
}
return $self ;
}
2013-04-08 15:40:06 +00:00
2014-11-25 13:20:33 +00:00
public function getOption ( $name = null )
{
if ( $name === null ) {
return $this -> options ;
}
return ( isset ( $this -> options [ $name ])
? $this -> options [ $name ]
: null
);
}
2014-11-26 21:42:23 +00:00
public function getData ( $section = null , $property = null )
2014-11-23 01:07:38 +00:00
{
if ( $section === null ) {
return $this -> data ;
}
$section = strtolower ( $section );
2014-11-26 21:42:23 +00:00
if ( isset ( $this -> data [ $section ])) {
if ( $property === null || ! isset ( $this -> data [ $section ][ $property ])) {
return $this -> data [ $section ];
}
return $this -> data [ $section ][ $property ];
}
return null ;
}
public function canInvalidate ()
{
return ( $this -> getOption ( 'allow_invalidate' ) && function_exists ( 'opcache_invalidate' ));
2013-04-08 15:40:06 +00:00
}
2014-11-23 01:07:38 +00:00
public function resetCache ( $file = null )
{
$success = false ;
if ( $file === null ) {
$success = opcache_reset ();
} else if ( function_exists ( 'opcache_invalidate' )) {
$success = opcache_invalidate ( urldecode ( $file ), true );
}
if ( $success ) {
$this -> compileState ();
}
return $success ;
2013-04-08 15:40:06 +00:00
}
2015-05-08 16:04:40 +00:00
protected function size ( $size )
{
$i = 0 ;
$val = array ( 'b' , 'KB' , 'MB' , 'GB' , 'TB' , 'PB' , 'EB' , 'ZB' , 'YB' );
while (( $size / 1024 ) > 1 ) {
$size /= 1024 ;
++ $i ;
}
return sprintf ( '%.' . $this -> getOption ( 'size_precision' ) . 'f%s%s' ,
2016-02-09 23:51:09 +00:00
$size , ( $this -> getOption ( 'size_space' ) ? ' ' : '' ), $val [ $i ]
2015-05-08 16:04:40 +00:00
);
}
2014-11-23 01:07:38 +00:00
protected function compileState ()
{
2014-11-25 13:20:33 +00:00
$status = opcache_get_status ();
2014-11-23 01:07:38 +00:00
$config = opcache_get_configuration ();
2019-07-11 22:55:54 +00:00
$missingConfig = array_diff_key ( ini_get_all ( 'zend opcache' , false ), $config [ 'directives' ]);
if ( ! empty ( $missingConfig )) {
$config [ 'directives' ] = array_merge ( $config [ 'directives' ], $missingConfig );
}
2013-04-22 12:28:29 +00:00
2014-11-25 13:20:33 +00:00
$files = [];
2015-12-30 18:18:03 +00:00
if ( ! empty ( $status [ 'scripts' ]) && $this -> getOption ( 'allow_filelist' )) {
2014-11-23 01:07:38 +00:00
uasort ( $status [ 'scripts' ], function ( $a , $b ) {
return $a [ 'hits' ] < $b [ 'hits' ];
});
2014-11-25 13:20:33 +00:00
foreach ( $status [ 'scripts' ] as & $file ) {
$file [ 'full_path' ] = str_replace ( '\\' , '/' , $file [ 'full_path' ]);
$file [ 'readable' ] = [
'hits' => number_format ( $file [ 'hits' ]),
2015-05-08 16:04:40 +00:00
'memory_consumption' => $this -> size ( $file [ 'memory_consumption' ])
2014-11-25 13:20:33 +00:00
];
}
$files = array_values ( $status [ 'scripts' ]);
2014-11-23 01:07:38 +00:00
}
2020-02-22 17:26:43 +00:00
if ( $config [ 'directives' ][ 'opcache.file_cache_only' ] || ! empty ( $status [ 'file_cache_only' ])) {
2019-07-12 00:31:05 +00:00
$overview = false ;
} else {
$overview = array_merge (
$status [ 'memory_usage' ], $status [ 'opcache_statistics' ], [
'used_memory_percentage' => round ( 100 * (
( $status [ 'memory_usage' ][ 'used_memory' ] + $status [ 'memory_usage' ][ 'wasted_memory' ])
/ $config [ 'directives' ][ 'opcache.memory_consumption' ])),
'hit_rate_percentage' => round ( $status [ 'opcache_statistics' ][ 'opcache_hit_rate' ]),
2019-07-13 16:17:52 +00:00
'used_key_percentage' => round ( 100 * (
$status [ 'opcache_statistics' ][ 'num_cached_keys' ]
/ $status [ 'opcache_statistics' ][ 'max_cached_keys' ])),
2019-07-12 00:31:05 +00:00
'wasted_percentage' => round ( $status [ 'memory_usage' ][ 'current_wasted_percentage' ], 2 ),
'readable' => [
'total_memory' => $this -> size ( $config [ 'directives' ][ 'opcache.memory_consumption' ]),
'used_memory' => $this -> size ( $status [ 'memory_usage' ][ 'used_memory' ]),
'free_memory' => $this -> size ( $status [ 'memory_usage' ][ 'free_memory' ]),
'wasted_memory' => $this -> size ( $status [ 'memory_usage' ][ 'wasted_memory' ]),
'num_cached_scripts' => number_format ( $status [ 'opcache_statistics' ][ 'num_cached_scripts' ]),
'hits' => number_format ( $status [ 'opcache_statistics' ][ 'hits' ]),
'misses' => number_format ( $status [ 'opcache_statistics' ][ 'misses' ]),
'blacklist_miss' => number_format ( $status [ 'opcache_statistics' ][ 'blacklist_misses' ]),
'num_cached_keys' => number_format ( $status [ 'opcache_statistics' ][ 'num_cached_keys' ]),
'max_cached_keys' => number_format ( $status [ 'opcache_statistics' ][ 'max_cached_keys' ]),
'interned' => null ,
'start_time' => date ( 'Y-m-d H:i:s' , $status [ 'opcache_statistics' ][ 'start_time' ]),
'last_restart_time' => ( $status [ 'opcache_statistics' ][ 'last_restart_time' ] == 0
2014-11-23 01:07:38 +00:00
? 'never'
2016-09-23 15:39:17 +00:00
: date ( 'Y-m-d H:i:s' , $status [ 'opcache_statistics' ][ 'last_restart_time' ])
2014-11-23 01:07:38 +00:00
)
2019-07-12 00:31:05 +00:00
]
2014-11-23 01:07:38 +00:00
]
2019-07-12 00:31:05 +00:00
);
}
2018-02-08 20:23:48 +00:00
2017-07-31 13:25:14 +00:00
if ( ! empty ( $status [ 'interned_strings_usage' ])) {
$overview [ 'readable' ][ 'interned' ] = [
'buffer_size' => $this -> size ( $status [ 'interned_strings_usage' ][ 'buffer_size' ]),
'strings_used_memory' => $this -> size ( $status [ 'interned_strings_usage' ][ 'used_memory' ]),
'strings_free_memory' => $this -> size ( $status [ 'interned_strings_usage' ][ 'free_memory' ]),
'number_of_strings' => number_format ( $status [ 'interned_strings_usage' ][ 'number_of_strings' ])
];
}
2013-04-08 15:40:06 +00:00
2014-11-24 00:09:48 +00:00
$directives = [];
2014-11-23 01:07:38 +00:00
ksort ( $config [ 'directives' ]);
2014-11-24 00:09:48 +00:00
foreach ( $config [ 'directives' ] as $k => $v ) {
2019-07-11 18:04:14 +00:00
if ( in_array ( $k , [ 'opcache.max_file_size' , 'opcache.memory_consumption' ]) && $v ) {
$v = $this -> size ( $v ) . " ( { $v } ) " ;
2020-02-22 19:51:12 +00:00
} elseif ( $k == 'opcache.optimization_level' ) {
$levels = [];
foreach ( $this -> optimizationLevels as $level => $info ) {
if ( $level & $v ) {
$levels [] = $info ;
}
}
$v = empty ( $levels ) ? 'none' : $levels ;
2019-07-11 18:04:14 +00:00
}
$directives [] = [
'k' => $k ,
'v' => $v
];
2014-11-24 00:09:48 +00:00
}
2014-11-23 01:07:38 +00:00
$version = array_merge (
$config [ 'version' ],
[
'php' => phpversion (),
2018-02-08 20:23:48 +00:00
'server' => empty ( $_SERVER [ 'SERVER_SOFTWARE' ]) ? '' : $_SERVER [ 'SERVER_SOFTWARE' ],
2014-11-23 01:07:38 +00:00
'host' => ( function_exists ( 'gethostname' )
? gethostname ()
: ( php_uname ( 'n' )
? : ( empty ( $_SERVER [ 'SERVER_NAME' ])
? $_SERVER [ 'HOST_NAME' ]
: $_SERVER [ 'SERVER_NAME' ]
)
)
)
]
);
return [
'version' => $version ,
'overview' => $overview ,
2014-11-25 13:20:33 +00:00
'files' => $files ,
2014-11-24 00:09:48 +00:00
'directives' => $directives ,
2014-11-23 01:07:38 +00:00
'blacklist' => $config [ 'blacklist' ],
'functions' => get_extension_funcs ( 'Zend OPcache' )
];
}
2013-04-08 15:40:06 +00:00
}
2015-05-08 16:04:40 +00:00
$opcache = OpCacheService :: init ( $options );
2013-04-09 15:44:50 +00:00
2013-04-08 15:40:06 +00:00
?>
2017-02-10 15:22:49 +00:00
<! DOCTYPE html >
2013-04-08 15:40:06 +00:00
< html >
< head >
2017-02-10 15:22:49 +00:00
< meta charset = " UTF-8 " >
2013-04-08 15:40:06 +00:00
< meta name = " viewport " content = " width=device-width,initial-scale=1.0 " >
2014-11-26 21:42:23 +00:00
< title > OPcache statistics on < ? php echo $opcache -> getData ( 'version' , 'host' ); ?> </title>
2017-02-10 15:22:49 +00:00
< script src = " //cdn.jsdelivr.net/react/15.4.2/react.min.js " ></ script >
< script src = " //cdn.jsdelivr.net/react/15.4.2/react-dom.min.js " ></ script >
< script src = " //cdn.jsdelivr.net/jquery/3.1.1/jquery.min.js " ></ script >
2013-04-08 15:40:06 +00:00
< style type = " text/css " >
2020-04-06 21:52:04 +00:00
. opcache - gui { font - family : sans - serif ; font - size : 90 % ; padding : 0 ; margin : 0 }
. opcache - gui . hide { display : none ; }
. opcache - gui . main - nav { padding - top : 20 px ; }
. opcache - gui . nav - tab - list { list - style - type : none ; padding - left : 8 px ; margin : 0 ; border - bottom : 1 px solid #ccc; }
. opcache - gui . nav - tab { display : inline - block ; padding : 0 ; margin : 0 0 - 1 px 0 ; }
. opcache - gui . nav - tab - link { display : block ; margin : 0 10 px ; padding : 15 px 30 px ; border : 1 px solid transparent ; border - bottom - color : #ccc; text-decoration: none; }
. opcache - gui . nav - tab - link : hover { background - color : #f4f4f4; text-decoration: underline; }
. opcache - gui . nav - tab - link . active : hover { background - color : initial ; }
. opcache - gui . nav - tab - link [ data - for ] . active { border : 1 px solid #ccc; border-bottom-color: #ffffff; border-top: 3px solid #6ca6ef; }
. opcache - gui . nav - tab - link - reset { background - image : url ( 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NjBFMUMyMjI3NDlGMTFFNEE3QzNGNjQ0OEFDQzQ1MkMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NjBFMUMyMjM3NDlGMTFFNEE3QzNGNjQ0OEFDQzQ1MkMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MEUxQzIyMDc0OUYxMUU0QTdDM0Y2NDQ4QUNDNDUyQyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo2MEUxQzIyMTc0OUYxMUU0QTdDM0Y2NDQ4QUNDNDUyQyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PplZ+ZkAAAD1SURBVHjazFPtDYJADIUJZAMZ4UbACWQENjBO4Ao6AW5AnODcADZQJwAnwJ55NbWhB/6zycsdpX39uDZNpsURtjgzwkDoCBecs5ITPGGMwCNAkIrQw+8ri36GhBHsavFdpILEo4wEpZxRigy009EhG760gr0VhFoyZfvJKPwsheIWIeGejBZRIxRVhMRFevbuUXBew/iE/lhlBduV0j8Jx+TvJEWPphq8n5li9utgaw6cW/h6NSt/JcnVBhQxotIgKTBrbNvIHo2G0x1rwlKqTDusxiAz6hHNL1zayTVqVKRKpa/LPljPH1sJh6l/oNSrZfwSYABtq3tFdZA5BAAAAABJRU5ErkJggg==' ); }
. opcache - gui . nav - tab - link - realtime { position : relative ; background - image : url ( 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAUCAYAAACAl21KAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODE5RUU4NUE3NDlGMTFFNDkyMzA4QzY1RjRBQkIzQjUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODE5RUU4NUI3NDlGMTFFNDkyMzA4QzY1RjRBQkIzQjUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4MTlFRTg1ODc0OUYxMUU0OTIzMDhDNjVGNEFCQjNCNSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4MTlFRTg1OTc0OUYxMUU0OTIzMDhDNjVGNEFCQjNCNSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpXjpvMAAAD2SURBVHjarFQBEcMgDKR3E1AJldA5wMEqAQmTgINqmILdFCChdUAdMAeMcukuSwnQbbnLlZLwJPkQIcrSiT/IGNQHNb8CGQDyRw+2QWUBqC+luzo4OKQZIAVrB+ssyKp3Bkijf0+ijzIh4wQppoBauMSjyDZfMSCDxYZMsfHF120T36AqWZMkgyguQ3GOfottJ5TKnHC+wfeRsC2oDVayPgr3bbN2tHBH3tWuJCPa0JUgKtFzMQrcZH3FNHAc0yOp1cCASALyngoN6lhDopkJWxdifwY9A3u7l29ImpxOFSWIOVsGwHKENIWxss2eBVKdOeeXAAMAk/Z9h4QhXmUAAAAASUVORK5CYII=' ); }
. opcache - gui . nav - tab - link - realtime . pulse :: before {
2014-11-26 23:08:44 +00:00
content : " " ; position : absolute ;
top : 13 px ; left : 3 px ; width : 18 px ; height : 18 px ;
z - index : 10 ; opacity : 0 ; background - color : transparent ;
border : 2 px solid rgb ( 255 , 116 , 0 ); border - radius : 100 % ;
animation : pulse 1 s linear 2 ;
}
2020-04-06 21:52:04 +00:00
. opcache - gui . tab - content - container { padding : 2 em ; }
. opcache - gui . tab - content { display : none ; }
. opcache - gui . tab - content - overview { display : block ; }
. opcache - gui . tab - content - overview - counts { width : 270 px ; float : right ; }
. opcache - gui . tab - content - overview - info { margin - right : 280 px ; }
. opcache - gui . graph - widget { display : block ; max - width : 100 % ; height : auto ; margin : 0 auto ; }
. opcache - gui . widget - panel { background - color : #ededed; margin-bottom: 10px; }
. opcache - gui . widget - header { background - color : #cdcdcd; padding: 4px 6px; margin: 0; text-align: center; }
. opcache - gui . widget - value { margin : 0 ; text - align : center ; }
. opcache - gui . widget - value span . large + span { font - size : 20 pt ; margin : 0 ; color : #6ca6ef; }
. opcache - gui . widget - value span . large { color : #6ca6ef; font-size: 80pt; margin: 0; padding: 0; text-align: center; }
. opcache - gui . widget - info { margin : 0 ; padding : 10 px ; }
. opcache - gui . widget - info * { margin : 0 ; line - height : 1.75 em ; text - align : left ; }
. opcache - gui . tables { margin : 0 0 1 em 0 ; border - collapse : collapse ; border - color : #fff; width: 100%; table-layout: fixed; }
. opcache - gui . tables tr { background - color : #99D0DF; border-color: #fff; }
. opcache - gui . tables th { text - align : left ; padding : 6 px ; background - color : #6ca6ef; color: #fff; border-color: #fff; font-weight: normal; }
. opcache - gui . tables td { padding : 4 px 6 px ; line - height : 1.4 em ; vertical - align : top ; border - color : #fff; overflow: hidden; overflow-wrap: break-word; text-overflow: ellipsis;}
. opcache - gui . tables tr : nth - child ( odd ) { background - color : #EFFEFF; }
. opcache - gui . tables tr : nth - child ( even ) { background - color : #E0ECEF; }
. opcache - gui . tables . file - list - table tr { background - color : #EFFEFF; }
. opcache - gui . tables . file - list - table tr . alternate { background - color : #E0ECEF; }
. opcache - gui . file - filter { width : 520 px ; }
. opcache - gui . file - metainfo { font - size : 80 % ; }
. opcache - gui . file - pathname { width : 70 % ; display : block ; }
. opcache - gui . nav - tab - link - reset ,
. opcache - gui . nav - tab - link - realtime ,
. opcache - gui . github - link { background - position : 5 px 50 % ; background - repeat : no - repeat ; background - color : transparent ; }
. opcache - gui . main - footer { border - top : 1 px solid #ccc; padding: 1em 2em; }
. opcache - gui . github - link { background - position : 0 50 % ; padding : 2 em ; text - decoration : none ; opacity : 0.7 ; background - image : url ( 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjE2MENCRkExNzVBQjExRTQ5NDBGRTUzMzQyMDVDNzFFIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjE2MENCRkEyNzVBQjExRTQ5NDBGRTUzMzQyMDVDNzFFIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MTYwQ0JGOUY3NUFCMTFFNDk0MEZFNTMzNDIwNUM3MUUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MTYwQ0JGQTA3NUFCMTFFNDk0MEZFNTMzNDIwNUM3MUUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7HtUU1AAABN0lEQVR42qyUvWoCQRSF77hCLLKC+FOlCKTyIbYQUuhbWPkSFnZ2NpabUvANLGyz5CkkYGMlFtFAUmiSM8lZOVkWsgm58K079+fMnTusZl92BXbgDrTtZ2szd8fas/XBOzmBKaiCEFyTkL4pc9L8vgpNJJDyWtDna61EoXpO+xcFfXUVqtrf7Vx7m9Pub/EatvgHoYXD4ylztC14BBVwydvydgDPHPgNaErN3jLKIxAUmEvAXK21I18SJpXBGAxyBAaMlblOWOs1bMXFkMGeBFsi0pJNe/QNuV7563+gs8LfhrRfE6GaHLuRqfnUiKi6lJ034B44EXL0baTTJWujNGkG3kBX5uRyZuRkPl3WzDTBtzjnxxiDDq83yNxUk7GYuXM53jeLuMNavvAXkv4zrJkTaeGHAAMAIal3icPMsyQAAAAASUVORK5CYII=' ); font - size : 80 % ; }
. opcache - gui . github - link : hover { opacity : 1 ; }
. opcache - gui . file - cache - only { margin - top : 0 ; }
2014-11-25 17:11:37 +00:00
@ media screen and ( max - width : 750 px ) {
2020-04-06 21:52:04 +00:00
. opcache - gui . nav - tab - list { border - bottom : 0 ; }
. opcache - gui . nav - tab { display : block ; margin : 0 ; }
. opcache - gui . nav - tab - link { display : block ; margin : 0 10 px ; padding : 10 px 0 10 px 30 px ; border : 0 ; }
. opcache - gui . nav - tab - link [ data - for ] . active { border - bottom - color : #ccc; }
. opcache - gui . tab - content - overview - info { margin - right : auto ; clear : both ; }
. opcache - gui . tab - content - overview - counts { position : relative ; display : block ; width : 100 % ; }
. opcache - gui . nav - tab - link - realtime . pulse :: before { top : 8 px ; }
2014-11-25 17:11:37 +00:00
}
@ media screen and ( max - width : 550 px ) {
2020-04-06 21:52:04 +00:00
. opcache - gui . file - filter { width : 100 % ; }
2014-11-25 17:11:37 +00:00
}
2014-11-26 23:08:44 +00:00
@ keyframes pulse {
0 % { transform : scale ( 1 ); opacity : 0 ;}
50 % { transform : scale ( 1.3 ); opacity : 0.7 ;}
100 % { transform : scale ( 1.6 ); opacity : 1 ;}
}
@- webkit - keyframes pulse {
0 % { - webkit - transform : scale ( 1 ); opacity : 0 ;}
50 % { - webkit - transform : scale ( 1.3 ); opacity : 0.7 ;}
100 % { - webkit - transform : scale ( 1.6 ); opacity : 0 ;}
}
@- moz - keyframes pulse {
0 % { - moz - transform : scale ( 1 ); opacity : 0 ;}
50 % { - moz - transform : scale ( 1.3 ); opacity : 0.7 ;}
100 % { - moz - transform : scale ( 1.6 ); opacity : 0 ;}
}
2013-04-08 15:40:06 +00:00
</ style >
</ head >
2020-04-06 21:52:04 +00:00
< body class = " opcache-gui " >
2013-04-08 15:40:06 +00:00
2014-11-26 21:42:23 +00:00
< header >
2020-04-06 21:52:04 +00:00
< nav class = " main-nav " >
< ul class = " nav-tab-list " >
< li class = " nav-tab " >< a data - for = " overview " href = " #overview " class = " active nav-tab-link " > Overview </ a ></ li >
2015-12-30 18:18:03 +00:00
< ? php if ( $opcache -> getOption ( 'allow_filelist' )) : ?>
2020-04-06 21:52:04 +00:00
< li class = " nav-tab " >< a data - for = " files " href = " #files " class = " nav-tab-link " > File usage </ a ></ li >
2015-12-30 18:18:03 +00:00
< ? php endif ; ?>
2015-05-11 12:59:53 +00:00
< ? php if ( $opcache -> getOption ( 'allow_reset' )) : ?>
2020-04-06 21:52:04 +00:00
< li class = " nav-tab " >< a href = " ?reset=1 " id = " resetCache " onclick = " return confirm('Are you sure you want to reset the cache?'); " class = " nav-tab-link nav-tab-link-reset " > Reset cache </ a ></ li >
2015-05-11 12:59:53 +00:00
< ? php endif ; ?>
< ? php if ( $opcache -> getOption ( 'allow_realtime' )) : ?>
2020-04-06 21:52:04 +00:00
< li class = " nav-tab " >< a href = " # " id = " toggleRealtime " class = " nav-tab-link nav-tab-link-realtime " > Enable real - time update </ a ></ li >
2015-05-11 12:59:53 +00:00
< ? php endif ; ?>
2014-11-26 21:42:23 +00:00
</ ul >
</ nav >
</ header >
2013-04-09 15:44:50 +00:00
2020-04-06 21:52:04 +00:00
< div id = " tabs " class = " tab-content-container " >
< div id = " overview " class = " tab-content tab-content-overview " >
< div >
< div id = " counts " class = " tab-content-overview-counts " ></ div >
< div id = " info " class = " tab-content-overview-info " >
2014-11-25 13:20:33 +00:00
< div id = " generalInfo " ></ div >
< div id = " directives " ></ div >
2014-11-26 10:14:44 +00:00
< div id = " functions " >
2020-04-06 21:52:04 +00:00
< table class = " tables " >
2014-11-26 10:14:44 +00:00
< thead >
< tr >< th > Available functions </ th ></ tr >
</ thead >
< tbody >
< ? php foreach ( $opcache -> getData ( 'functions' ) as $func ) : ?>
< tr >< td >< a href = " http://php.net/<?php echo $func ; ?> " title = " View manual page " target = " _blank " >< ? php echo $func ; ?> </a></td></tr>
< ? php endforeach ; ?>
</ tbody >
</ table >
</ div >
2014-11-25 13:20:33 +00:00
< br style = " clear:both; " />
</ div >
2013-04-08 15:40:06 +00:00
</ div >
</ div >
2020-04-06 21:52:04 +00:00
< div id = " files " class = " tab-content tab-content-files " >
2015-12-30 18:18:03 +00:00
< ? php if ( $opcache -> getOption ( 'allow_filelist' )) : ?>
2017-02-10 15:22:49 +00:00
< form action = " # " >
< label for = " frmFilter " > Start typing to filter on script path </ label >< br >
2020-04-06 21:52:04 +00:00
< input type = " text " name = " filter " id = " frmFilter " class = " file-filter " >
2017-02-10 15:22:49 +00:00
</ form >
2015-12-30 18:18:03 +00:00
< ? php endif ; ?>
2020-04-06 21:52:04 +00:00
< div id = " filelist " ></ div >
2013-04-09 15:44:50 +00:00
</ div >
2014-11-23 01:07:38 +00:00
</ div >
2020-04-06 21:52:04 +00:00
< footer class = " main-footer " >
< a class = " github-link " href = " https://github.com/amnuts/opcache-gui " target = " _blank " title = " opcache-gui (currently version <?php echo OpCacheService::VERSION; ?>) on GitHub " > https :// github . com / amnuts / opcache - gui - version < ? php echo OpCacheService :: VERSION ; ?> </a>
2014-11-26 21:42:23 +00:00
</ footer >
2014-11-25 17:11:37 +00:00
< script type = " text/javascript " >
var realtime = false ;
2014-11-26 21:42:23 +00:00
var opstate = < ? php echo json_encode ( $opcache -> getData ()); ?> ;
2016-01-06 14:02:08 +00:00
var canInvalidate = < ? php echo json_encode ( $opcache -> canInvalidate ()); ?> ;
var useCharts = < ? php echo json_encode ( $opcache -> getOption ( 'charts' )); ?> ;
2019-07-13 16:17:52 +00:00
var highlight = < ? php echo json_encode ( $opcache -> getOption ( 'highlight' )); ?> ;
2016-01-06 14:02:08 +00:00
var allowFiles = < ? php echo json_encode ( $opcache -> getOption ( 'allow_filelist' )); ?> ;
2016-02-23 15:46:34 +00:00
var debounce = function ( func , wait , immediate ) {
var timeout ;
wait = wait || 250 ;
return function () {
var context = this , args = arguments ;
var later = function () {
timeout = null ;
if ( ! immediate ) {
func . apply ( context , args );
}
};
var callNow = immediate && ! timeout ;
clearTimeout ( timeout );
timeout = setTimeout ( later , wait );
if ( callNow ) {
func . apply ( context , args );
}
};
};
function keyUp ( event ){
var compare = $ ( '#frmFilter' ) . val () . toLowerCase ();
$ ( '#filelist' ) . find ( 'table tbody tr' ) . each ( function ( index ){
if ( $ ( this ) . data ( 'path' ) . indexOf ( compare ) == - 1 ) {
$ ( this ) . addClass ( 'hide' );
} else {
$ ( this ) . removeClass ( 'hide' );
}
});
$ ( '#filelist table tbody' ) . trigger ( 'paint' );
};
2015-12-30 18:18:03 +00:00
< ? php if ( $opcache -> getOption ( 'charts' )) : ?>
2015-05-08 16:04:40 +00:00
var Gauge = function ( el , colour ) {
this . canvas = $ ( el ) . get ( 0 );
this . ctx = this . canvas . getContext ( '2d' );
this . width = this . canvas . width ;
this . height = this . canvas . height ;
this . colour = colour || '#6ca6ef' ;
this . loop = null ;
this . degrees = 0 ;
this . newdegs = 0 ;
this . text = '' ;
this . init = function () {
this . ctx . clearRect ( 0 , 0 , this . width , this . height );
this . ctx . beginPath ();
this . ctx . strokeStyle = '#e2e2e2' ;
this . ctx . lineWidth = 30 ;
this . ctx . arc ( this . width / 2 , this . height / 2 , 100 , 0 , Math . PI * 2 , false );
this . ctx . stroke ();
this . ctx . beginPath ();
this . ctx . strokeStyle = this . colour ;
this . ctx . lineWidth = 30 ;
this . ctx . arc ( this . width / 2 , this . height / 2 , 100 , 0 - ( 90 * Math . PI / 180 ), ( this . degrees * Math . PI / 180 ) - ( 90 * Math . PI / 180 ), false );
this . ctx . stroke ();
this . ctx . fillStyle = this . colour ;
this . ctx . font = '60px sans-serif' ;
this . text = Math . round (( this . degrees / 360 ) * 100 ) + '%' ;
this . ctx . fillText ( this . text , ( this . width / 2 ) - ( this . ctx . measureText ( this . text ) . width / 2 ), ( this . height / 2 ) + 20 );
};
this . draw = function () {
if ( typeof this . loop != 'undefined' ) {
clearInterval ( this . loop );
}
var self = this ;
self . loop = setInterval ( function (){ self . animate (); }, 1000 / ( this . newdegs - this . degrees ));
};
this . animate = function () {
if ( this . degrees == this . newdegs ) {
clearInterval ( this . loop );
}
if ( this . degrees < this . newdegs ) {
++ this . degrees ;
} else {
-- this . degrees ;
}
this . init ();
};
this . setValue = function ( val ) {
this . newdegs = Math . round ( 3.6 * val );
this . draw ();
};
}
< ? php endif ; ?>
2014-11-25 17:11:37 +00:00
$ ( function (){
2015-05-11 12:59:53 +00:00
< ? php if ( $opcache -> getOption ( 'allow_realtime' )) : ?>
2017-12-28 19:37:52 +00:00
function setCookie () {
var d = new Date ();
var secure = ( window . location . protocol === 'https:' ? ';secure' : '' );
d . setTime ( d . getTime () + ( < ? php echo ( $opcache -> getOption ( 'cookie_ttl' )); ?> * 86400000));
var expires = " expires= " + d . toUTCString ();
document . cookie = " <?php echo ( $opcache->getOption ('cookie_name')); ?>=true; " + expires + " ;path=/ " + secure ;
};
function removeCookie () {
var secure = ( window . location . protocol === 'https:' ? ';secure' : '' );
document . cookie = " <?php echo ( $opcache->getOption ('cookie_name')); ?>=;expires=Thu, 01 Jan 1970 00:00:01 GMT;path=/ " + secure ;
};
function getCookie () {
var v = document . cookie . match ( '(^|;) ?<?php echo ($opcache->getOption(' cookie_name ')); ?>=([^;]*)(;|$)' );
return v ? v [ 2 ] : null ;
};
2014-11-25 17:11:37 +00:00
function updateStatus () {
2014-11-26 23:08:44 +00:00
$ ( '#toggleRealtime' ) . removeClass ( 'pulse' );
2014-11-25 17:11:37 +00:00
$ . ajax ({
url : " # " ,
dataType : " json " ,
cache : false ,
success : function ( data ) {
2014-11-26 23:08:44 +00:00
$ ( '#toggleRealtime' ) . addClass ( 'pulse' );
2014-11-25 17:11:37 +00:00
opstate = data ;
overviewCountsObj . setState ({
data : opstate . overview
});
generalInfoObj . setState ({
version : opstate . version ,
start : opstate . overview . readable . start_time ,
reset : opstate . overview . readable . last_restart_time
});
filesObj . setState ({
data : opstate . files ,
count_formatted : opstate . overview . readable . num_cached_scripts ,
count : opstate . overview . num_cached_scripts
});
2016-02-23 15:46:34 +00:00
keyUp ();
2014-11-25 17:11:37 +00:00
}
});
}
$ ( '#toggleRealtime' ) . click ( function (){
if ( realtime === false ) {
2015-05-11 12:59:53 +00:00
realtime = setInterval ( function (){ updateStatus ()}, < ? php echo ( int ) $opcache -> getOption ( 'refresh_time' ) * 1000 ; ?> );
2014-11-25 17:11:37 +00:00
$ ( this ) . text ( 'Disable real-time update' );
2017-12-28 19:37:52 +00:00
setCookie ();
2014-11-25 17:11:37 +00:00
} else {
clearInterval ( realtime );
realtime = false ;
2014-11-26 23:08:44 +00:00
$ ( this ) . text ( 'Enable real-time update' ) . removeClass ( 'pulse' );
2017-12-28 19:37:52 +00:00
removeCookie ();
2014-11-25 17:11:37 +00:00
}
});
2017-12-28 19:37:52 +00:00
if ( getCookie () == 'true' ) {
realtime = setInterval ( function (){ updateStatus ()}, < ? php echo ( int ) $opcache -> getOption ( 'refresh_time' ) * 1000 ; ?> );
$ ( '#toggleRealtime' ) . text ( 'Disable real-time update' );
}
2015-05-11 12:59:53 +00:00
< ? php endif ; ?>
2014-11-25 17:11:37 +00:00
$ ( 'nav a[data-for]' ) . click ( function (){
$ ( '#tabs > div' ) . hide ();
$ ( '#' + $ ( this ) . data ( 'for' )) . show ();
$ ( 'nav a[data-for]' ) . removeClass ( 'active' );
$ ( this ) . addClass ( 'active' );
return false ;
});
$ ( document ) . on ( 'paint' , '#filelist table tbody' , function ( event , params ) {
2016-02-23 15:46:34 +00:00
var trs = $ ( '#filelist' ) . find ( 'tbody tr' );
trs . removeClass ( 'alternate' );
trs . filter ( ':not(.hide):odd' ) . addClass ( 'alternate' );
filesObj . setState ({ showing : trs . filter ( ':not(.hide)' ) . length });
2014-11-25 17:11:37 +00:00
});
2016-02-24 00:26:43 +00:00
$ ( '#frmFilter' ) . bind ( 'keyup' , debounce ( keyUp , < ? php echo $opcache -> getOption ( 'debounce_rate' ); ?> ));
2014-11-25 17:11:37 +00:00
});
2019-07-13 16:17:52 +00:00
var UsageGraph = React . createClass ({
2017-07-31 13:25:14 +00:00
getInitialState : function () {
2016-02-09 23:45:11 +00:00
return {
2019-07-13 16:17:52 +00:00
gauge : null
2016-02-09 23:45:11 +00:00
};
},
2017-07-31 13:25:14 +00:00
componentDidMount : function () {
2015-05-08 16:04:40 +00:00
if ( this . props . chart ) {
2019-07-13 16:17:52 +00:00
this . state . gauge = new Gauge ( '#' + this . props . gaugeId );
this . state . gauge . setValue ( this . props . value );
2015-05-08 16:04:40 +00:00
}
},
2017-07-31 13:25:14 +00:00
componentDidUpdate : function () {
2019-07-13 16:17:52 +00:00
if ( this . state . gauge != null ) {
this . state . gauge . setValue ( this . props . value );
2015-05-08 16:04:40 +00:00
}
},
2017-07-31 13:25:14 +00:00
render : function () {
2015-05-08 16:04:40 +00:00
if ( this . props . chart == true ) {
2020-04-06 21:52:04 +00:00
return React . createElement ( " canvas " , { id : this . props . gaugeId , className : " graph-widget " , width : " 250 " , height : " 250 " , " data-value " : this . props . value });
2015-05-08 16:04:40 +00:00
}
2017-07-31 13:25:14 +00:00
return React . createElement (
" p " ,
null ,
React . createElement (
" span " ,
{ className : " large " },
this . props . value
),
React . createElement (
" span " ,
null ,
" % "
)
);
}
});
var MemoryUsagePanel = React . createClass ({
render : function () {
return React . createElement (
" div " ,
2020-04-06 21:52:04 +00:00
{ className : " widget-panel " },
2017-07-31 13:25:14 +00:00
React . createElement (
" h3 " ,
2020-04-06 21:52:04 +00:00
{ className : " widget-header " },
2017-07-31 13:25:14 +00:00
" memory usage "
),
React . createElement (
" div " ,
2020-04-06 21:52:04 +00:00
{ className : " widget-value widget-info " },
2017-07-31 13:25:14 +00:00
React . createElement (
" p " ,
null ,
React . createElement (
" b " ,
null ,
" total memory: "
),
" " ,
this . props . total
),
React . createElement (
" p " ,
null ,
React . createElement (
" b " ,
null ,
" used memory: "
),
" " ,
this . props . used
),
React . createElement (
" p " ,
null ,
React . createElement (
" b " ,
null ,
" free memory: "
),
" " ,
this . props . free
),
React . createElement (
" p " ,
null ,
React . createElement (
" b " ,
null ,
" wasted memory: "
),
" " ,
this . props . wasted ,
" ( " ,
this . props . wastedPercent ,
" %) "
)
)
);
2015-05-08 16:04:40 +00:00
}
});
2017-07-31 13:25:14 +00:00
var StatisticsPanel = React . createClass ({
render : function () {
return React . createElement (
" div " ,
2020-04-06 21:52:04 +00:00
{ className : " widget-panel " },
2017-07-31 13:25:14 +00:00
React . createElement (
" h3 " ,
2020-04-06 21:52:04 +00:00
{ className : " widget-header " },
2017-07-31 13:25:14 +00:00
" opcache statistics "
),
React . createElement (
" div " ,
2020-04-06 21:52:04 +00:00
{ className : " widget-value widget-info " },
2017-07-31 13:25:14 +00:00
React . createElement (
" p " ,
null ,
React . createElement (
" b " ,
null ,
" number of cached files: "
),
" " ,
this . props . num_cached_scripts
),
React . createElement (
" p " ,
null ,
React . createElement (
" b " ,
null ,
" number of hits: "
),
" " ,
this . props . hits
),
React . createElement (
" p " ,
null ,
React . createElement (
" b " ,
null ,
" number of misses: "
),
" " ,
this . props . misses
),
React . createElement (
" p " ,
null ,
React . createElement (
" b " ,
null ,
" blacklist misses: "
),
" " ,
this . props . blacklist_miss
),
React . createElement (
" p " ,
null ,
React . createElement (
" b " ,
null ,
" number of cached keys: "
),
" " ,
this . props . num_cached_keys
),
React . createElement (
" p " ,
null ,
React . createElement (
" b " ,
null ,
" max cached keys: "
),
" " ,
this . props . max_cached_keys
)
)
);
}
});
var InternedStringsPanel = React . createClass ({
render : function () {
return React . createElement (
" div " ,
2020-04-06 21:52:04 +00:00
{ className : " widget-panel " },
2017-07-31 13:25:14 +00:00
React . createElement (
" h3 " ,
2020-04-06 21:52:04 +00:00
{ className : " widget-header " },
2017-07-31 13:25:14 +00:00
" interned strings usage "
),
React . createElement (
" div " ,
2020-04-06 21:52:04 +00:00
{ className : " widget-value widget-info " },
2017-07-31 13:25:14 +00:00
React . createElement (
" p " ,
null ,
React . createElement (
" b " ,
null ,
" buffer size: "
),
" " ,
this . props . buffer_size
),
React . createElement (
" p " ,
null ,
React . createElement (
" b " ,
null ,
" used memory: "
),
" " ,
this . props . strings_used_memory
),
React . createElement (
" p " ,
null ,
React . createElement (
" b " ,
null ,
" free memory: "
),
" " ,
this . props . strings_free_memory
),
React . createElement (
" p " ,
null ,
React . createElement (
" b " ,
null ,
" number of strings: "
),
" " ,
this . props . number_of_strings
)
)
);
}
});
var OverviewCounts = React . createClass ({
getInitialState : function () {
2015-05-08 16:04:40 +00:00
return {
2017-07-31 13:25:14 +00:00
data : opstate . overview ,
2019-07-13 16:17:52 +00:00
chart : useCharts ,
highlight : highlight
2015-05-08 16:04:40 +00:00
};
2014-11-24 00:09:48 +00:00
},
2017-07-31 13:25:14 +00:00
render : function () {
2019-07-12 00:31:05 +00:00
if ( this . state . data == false ) {
return React . createElement (
" p " ,
2020-04-06 21:52:04 +00:00
{ " class " : " file-cache-only " },
2019-07-12 00:31:05 +00:00
" You have " ,
React . createElement (
" i " ,
null ,
" opcache.file_cache_only "
),
" turned on. As a result, the memory information is not available. Statistics and file list may also not be returned by " ,
React . createElement (
" i " ,
null ,
" opcache_get_statistics() "
),
" . "
);
}
2017-07-31 13:25:14 +00:00
var interned = this . state . data . readable . interned != null ? React . createElement ( InternedStringsPanel , {
buffer_size : this . state . data . readable . interned . buffer_size ,
strings_used_memory : this . state . data . readable . interned . strings_used_memory ,
strings_free_memory : this . state . data . readable . interned . strings_free_memory ,
number_of_strings : this . state . data . readable . interned . number_of_strings
}) : '' ;
2019-07-13 16:17:52 +00:00
var memoryHighlight = this . state . highlight . memory ? React . createElement (
2017-07-31 13:25:14 +00:00
" div " ,
2020-04-06 21:52:04 +00:00
{ className : " widget-panel " },
2017-07-31 13:25:14 +00:00
React . createElement (
2019-07-13 16:17:52 +00:00
" h3 " ,
2020-04-06 21:52:04 +00:00
{ className : " widget-header " },
2019-07-13 16:17:52 +00:00
" memory "
2017-07-31 13:25:14 +00:00
),
React . createElement (
2019-07-13 16:17:52 +00:00
" p " ,
2020-04-06 21:52:04 +00:00
{ className : " widget-value " },
2019-07-13 16:17:52 +00:00
React . createElement ( UsageGraph , { chart : this . state . chart , value : this . state . data . used_memory_percentage , gaugeId : " memoryUsageCanvas " })
)
) : null ;
var hitsHighlight = this . state . highlight . hits ? React . createElement (
" div " ,
2020-04-06 21:52:04 +00:00
{ className : " widget-panel " },
2019-07-13 16:17:52 +00:00
React . createElement (
" h3 " ,
2020-04-06 21:52:04 +00:00
{ className : " widget-header " },
2019-07-13 16:17:52 +00:00
" hit rate "
2017-07-31 13:25:14 +00:00
),
2019-07-13 16:17:52 +00:00
React . createElement (
" p " ,
2020-04-06 21:52:04 +00:00
{ className : " widget-value " },
2019-07-13 16:17:52 +00:00
React . createElement ( UsageGraph , { chart : this . state . chart , value : this . state . data . hit_rate_percentage , gaugeId : " hitRateCanvas " })
)
) : null ;
var keysHighlight = this . state . highlight . keys ? React . createElement (
" div " ,
2020-04-06 21:52:04 +00:00
{ className : " widget-panel " },
2019-07-13 16:17:52 +00:00
React . createElement (
" h3 " ,
2020-04-06 21:52:04 +00:00
{ className : " widget-header " },
2019-07-13 16:17:52 +00:00
" keys "
),
React . createElement (
" p " ,
2020-04-06 21:52:04 +00:00
{ className : " widget-value " },
2019-07-13 16:17:52 +00:00
React . createElement ( UsageGraph , { chart : this . state . chart , value : this . state . data . used_key_percentage , gaugeId : " keyUsageCanvas " })
)
) : null ;
return React . createElement (
" div " ,
null ,
memoryHighlight ,
hitsHighlight ,
keysHighlight ,
2017-07-31 13:25:14 +00:00
React . createElement ( MemoryUsagePanel , {
total : this . state . data . readable . total_memory ,
used : this . state . data . readable . used_memory ,
free : this . state . data . readable . free_memory ,
wasted : this . state . data . readable . wasted_memory ,
wastedPercent : this . state . data . wasted_percentage
}),
React . createElement ( StatisticsPanel , {
num_cached_scripts : this . state . data . readable . num_cached_scripts ,
hits : this . state . data . readable . hits ,
misses : this . state . data . readable . misses ,
blacklist_miss : this . state . data . readable . blacklist_miss ,
num_cached_keys : this . state . data . readable . num_cached_keys ,
max_cached_keys : this . state . data . readable . max_cached_keys
}),
interned
2014-11-24 00:09:48 +00:00
);
}
});
2017-07-31 13:25:14 +00:00
var GeneralInfo = React . createClass ({
getInitialState : function () {
2014-11-24 00:09:48 +00:00
return {
2017-07-31 13:25:14 +00:00
version : opstate . version ,
2019-07-12 00:31:05 +00:00
start : opstate . overview ? opstate . overview . readable . start_time : null ,
reset : opstate . overview ? opstate . overview . readable . last_restart_time : null
2014-11-24 00:09:48 +00:00
};
},
2017-07-31 13:25:14 +00:00
render : function () {
2019-07-12 00:31:05 +00:00
var startTime = this . state . start ? React . createElement (
" tr " ,
null ,
React . createElement (
" td " ,
null ,
" Start time "
),
React . createElement (
" td " ,
null ,
this . state . start
)
) : '' ;
var lastReset = this . state . reset ? React . createElement (
" tr " ,
null ,
React . createElement (
" td " ,
null ,
" Last reset "
),
React . createElement (
" td " ,
null ,
this . state . reset
)
) : '' ;
2017-07-31 13:25:14 +00:00
return React . createElement (
" table " ,
2020-04-06 21:52:04 +00:00
{ className : " tables general-info-table " },
2017-07-31 13:25:14 +00:00
React . createElement (
" thead " ,
null ,
React . createElement (
" tr " ,
null ,
React . createElement (
" th " ,
{ colSpan : " 2 " },
" General info "
)
)
),
React . createElement (
" tbody " ,
null ,
React . createElement (
" tr " ,
null ,
React . createElement (
" td " ,
null ,
" Zend OPcache "
),
React . createElement (
" td " ,
null ,
this . state . version . version
)
),
React . createElement (
" tr " ,
null ,
React . createElement (
" td " ,
null ,
" PHP "
),
React . createElement (
" td " ,
null ,
this . state . version . php
)
2014-11-26 21:42:23 +00:00
),
2017-07-31 13:25:14 +00:00
React . createElement (
" tr " ,
null ,
React . createElement (
" td " ,
null ,
" Host "
),
React . createElement (
" td " ,
null ,
this . state . version . host
)
),
React . createElement (
" tr " ,
null ,
React . createElement (
" td " ,
null ,
" Server Software "
),
React . createElement (
" td " ,
null ,
this . state . version . server
)
),
2019-07-12 00:31:05 +00:00
startTime ,
lastReset
2014-11-26 21:42:23 +00:00
)
2014-11-24 00:09:48 +00:00
);
}
});
2017-07-31 13:25:14 +00:00
var Directives = React . createClass ({
getInitialState : function () {
return { data : opstate . directives };
2014-11-24 00:09:48 +00:00
},
2017-07-31 13:25:14 +00:00
render : function () {
var directiveNodes = this . state . data . map ( function ( directive ) {
var map = { 'opcache.' : '' , '_' : ' ' };
var dShow = directive . k . replace ( / opcache\ .| _ / gi , function ( matched ) {
2014-11-24 00:09:48 +00:00
return map [ matched ];
});
var vShow ;
if ( directive . v === true || directive . v === false ) {
vShow = React . createElement ( 'i' , {}, directive . v . toString ());
2016-10-11 11:09:28 +00:00
} else if ( directive . v === '' ) {
2014-11-24 00:09:48 +00:00
vShow = React . createElement ( 'i' , {}, 'no value' );
} else {
2020-02-22 19:51:12 +00:00
if ( Array . isArray ( directive . v )) {
vShow = directive . v . map ( function ( item , key ) {
return React . createElement (
" span " ,
{ key : key },
item ,
React . createElement ( " br " , null )
);
});
} else {
vShow = directive . v ;
}
2014-11-24 00:09:48 +00:00
}
2017-07-31 13:25:14 +00:00
return React . createElement (
" tr " ,
{ key : directive . k },
React . createElement (
" td " ,
{ title : 'View ' + directive . k + ' manual entry' },
React . createElement (
" a " ,
{ href : 'http://php.net/manual/en/opcache.configuration.php#ini.' + directive . k . replace ( / _ / g , '-' ), target : " _blank " },
dShow
)
),
React . createElement (
" td " ,
null ,
vShow
2014-11-26 21:42:23 +00:00
)
2014-11-24 00:09:48 +00:00
);
});
2017-07-31 13:25:14 +00:00
return React . createElement (
" table " ,
2020-04-06 21:52:04 +00:00
{ className : " tables directives-table " },
2017-07-31 13:25:14 +00:00
React . createElement (
" thead " ,
null ,
React . createElement (
" tr " ,
null ,
React . createElement (
" th " ,
{ colSpan : " 2 " },
" Directives "
)
)
),
React . createElement (
" tbody " ,
null ,
directiveNodes
2014-11-26 21:42:23 +00:00
)
2014-11-24 00:09:48 +00:00
);
}
});
2017-07-31 13:25:14 +00:00
var Files = React . createClass ({
getInitialState : function () {
2014-11-25 13:20:33 +00:00
return {
2017-07-31 13:25:14 +00:00
data : opstate . files ,
2015-12-30 18:18:03 +00:00
showing : null ,
allowFiles : allowFiles
2014-11-25 13:20:33 +00:00
};
},
2017-07-31 13:25:14 +00:00
handleInvalidate : function ( e ) {
2014-11-25 17:11:37 +00:00
e . preventDefault ();
if ( realtime ) {
2017-07-31 13:25:14 +00:00
$ . get ( '#' , { invalidate : e . currentTarget . getAttribute ( 'data-file' ) }, function ( data ) {
2014-11-25 17:11:37 +00:00
console . log ( 'success: ' + data . success );
}, 'json' );
} else {
window . location . href = e . currentTarget . href ;
}
},
2017-07-31 13:25:14 +00:00
render : function () {
2015-12-30 18:18:03 +00:00
if ( this . state . allowFiles ) {
2017-07-31 13:25:14 +00:00
var fileNodes = this . state . data . map ( function ( file , i ) {
2015-12-30 18:18:03 +00:00
var invalidate , invalidated ;
if ( file . timestamp == 0 ) {
2017-07-31 13:25:14 +00:00
invalidated = React . createElement (
" span " ,
null ,
React . createElement (
" i " ,
{ className : " invalid metainfo " },
" - has been invalidated "
)
);
2015-12-30 18:18:03 +00:00
}
if ( canInvalidate ) {
2017-07-31 13:25:14 +00:00
invalidate = React . createElement (
" span " ,
null ,
2019-07-12 00:31:05 +00:00
" , \xA0 " ,
2017-07-31 13:25:14 +00:00
React . createElement (
" a " ,
2020-04-06 21:52:04 +00:00
{ className : " file-metainfo " , href : '?invalidate=' + file . full_path , " data-file " : file . full_path , onClick : this . handleInvalidate },
2017-07-31 13:25:14 +00:00
" force file invalidation "
)
);
2015-12-30 18:18:03 +00:00
}
2017-07-31 13:25:14 +00:00
return React . createElement (
" tr " ,
{ key : file . full_path , " data-path " : file . full_path . toLowerCase (), className : i % 2 ? 'alternate' : '' },
React . createElement (
" td " ,
null ,
React . createElement (
2020-04-06 21:52:04 +00:00
" span " ,
{ className : " file-pathname " },
file . full_path
),
React . createElement ( FilesMeta , { data : [ file . readable . hits , file . readable . memory_consumption , file . last_used ] }),
invalidate ,
invalidated
2014-11-26 21:42:23 +00:00
)
2015-12-30 18:18:03 +00:00
);
} . bind ( this ));
2017-07-31 13:25:14 +00:00
return React . createElement (
" div " ,
null ,
React . createElement ( FilesListed , { showing : this . state . showing }),
React . createElement (
" table " ,
2020-04-06 21:52:04 +00:00
{ className : " tables file-list-table " },
2017-07-31 13:25:14 +00:00
React . createElement (
" thead " ,
null ,
React . createElement (
" tr " ,
null ,
React . createElement (
" th " ,
null ,
" Script "
2015-12-30 18:18:03 +00:00
)
2017-07-31 13:25:14 +00:00
)
),
React . createElement (
" tbody " ,
null ,
fileNodes
2015-12-30 18:18:03 +00:00
)
2014-11-26 21:42:23 +00:00
)
2014-11-25 13:20:33 +00:00
);
2015-12-30 18:18:03 +00:00
} else {
return React . createElement ( " span " , null );
}
2014-11-25 13:20:33 +00:00
}
});
2017-07-31 13:25:14 +00:00
var FilesMeta = React . createClass ({
render : function () {
return React . createElement (
" span " ,
2020-04-06 21:52:04 +00:00
{ className : " file-metainfo " },
2017-07-31 13:25:14 +00:00
React . createElement (
" b " ,
null ,
" hits: "
),
React . createElement (
" span " ,
null ,
this . props . data [ 0 ],
" , "
),
React . createElement (
" b " ,
null ,
" memory: "
),
React . createElement (
" span " ,
null ,
this . props . data [ 1 ],
" , "
),
React . createElement (
" b " ,
null ,
" last used: "
),
React . createElement (
" span " ,
null ,
this . props . data [ 2 ]
2014-11-26 21:42:23 +00:00
)
2014-11-26 11:13:39 +00:00
);
}
});
2017-07-31 13:25:14 +00:00
var FilesListed = React . createClass ({
getInitialState : function () {
2014-11-25 17:11:37 +00:00
return {
2019-07-12 00:31:05 +00:00
formatted : opstate . overview ? opstate . overview . readable . num_cached_scripts : 0 ,
total : opstate . overview ? opstate . overview . num_cached_scripts : 0
2014-11-25 17:11:37 +00:00
};
},
2017-07-31 13:25:14 +00:00
render : function () {
2014-11-25 17:11:37 +00:00
var display = this . state . formatted + ' file' + ( this . state . total == 1 ? '' : 's' ) + ' cached' ;
2014-11-26 23:08:44 +00:00
if ( this . props . showing !== null && this . props . showing != this . state . total ) {
2014-11-25 17:11:37 +00:00
display += ', ' + this . props . showing + ' showing due to filter' ;
}
2017-07-31 13:25:14 +00:00
return React . createElement (
" h3 " ,
null ,
display
);
2014-11-25 17:11:37 +00:00
}
2014-11-26 11:13:39 +00:00
});
2014-11-25 17:11:37 +00:00
2016-04-08 17:11:32 +00:00
var overviewCountsObj = ReactDOM . render ( React . createElement ( OverviewCounts , null ), document . getElementById ( 'counts' ));
var generalInfoObj = ReactDOM . render ( React . createElement ( GeneralInfo , null ), document . getElementById ( 'generalInfo' ));
var filesObj = ReactDOM . render ( React . createElement ( Files , null ), document . getElementById ( 'filelist' ));
ReactDOM . render ( React . createElement ( Directives , null ), document . getElementById ( 'directives' ));
2014-11-23 01:07:38 +00:00
</ script >
2013-04-08 15:40:06 +00:00
</ body >
</ html >