You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

966 lines
28 KiB

<?php
// #nZEDb : Denotes modifications done for nZEDb integration.
/* #nZEDb */
require_once './config.php';
$page = new AdminPage();
$nZEDbURL = $page->serverurl;
/* #nZEDb */
/**
* OPcache GUI
*
* A simple but effective single-file GUI for the OPcache PHP extension.
*
* @author Andrew Collington, andy@amnuts.com
* @version 2.0.0
* @link https://github.com/amnuts/opcache-gui
* @license MIT, http://acollington.mit-license.org/
*/
if (!extension_loaded('Zend OPcache')) {
die('The Zend OPcache extension does not appear to be installed');
}
class OpCacheService
{
protected $data;
protected $options = [
'allow_invalidate' => true
];
private function __construct($options = [])
{
$this->data = $this->compileState();
$this->options = array_merge($this->options, $options);
}
public static function init($options = [])
{
$self = new self($options);
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH'])
&& strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'
) {
if ((isset($_GET['reset']))) {
echo '{ "success": "' . ($self->resetCache() ? 'yes' : 'no') . '" }';
} else {
if ((isset($_GET['invalidate']))) {
echo
'{ "success": "' . ($self->resetCache($_GET['invalidate']) ? 'yes' : 'no') .
'" }';
} else {
echo json_encode($self->getData(@$_GET['section'] ?: null));
}
}
exit;
} else {
if ((isset($_GET['reset']))) {
$self->resetCache();
} else {
if ((isset($_GET['invalidate']))) {
$self->resetCache($_GET['invalidate']);
}
}
}
return $self;
}
/**
* @param string $name
*
* @return array|null
*/
public function getOption($name = null)
{
if ($name === null) {
return $this->options;
}
return (isset($this->options[$name]) ? $this->options[$name] : null);
}
public function getData($section = null, $property = null)
{
if ($section === null) {
return $this->data;
}
$section = strtolower($section);
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'));
}
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;
}
protected function compileState()
{
$status = opcache_get_status();
$config = opcache_get_configuration();
$memsize = function($size, $precision = 3, $space = false) {
$i = 0;
$val = [' bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
while (($size / 1024) > 1) {
$size /= 1024;
++$i;
}
return sprintf("%.{$precision}f%s%s", $size, (($space && $i) ? ' ' : ''), $val[$i]);
};
$files = [];
if (!empty($status['scripts'])) {
uasort($status['scripts'],
function($a, $b) {
return $a['hits'] < $b['hits'];
});
foreach ($status['scripts'] as &$file) {
$file['full_path'] = str_replace('\\', '/', $file['full_path']);
$file['readable'] = [
'hits' => number_format($file['hits']),
'memory_consumption' => $memsize($file['memory_consumption'])
];
}
$files = array_values($status['scripts']);
}
$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']),
'wasted_percentage' => round($status['memory_usage']['current_wasted_percentage'],
2),
'readable' => [
'total_memory' => $memsize($config['directives']['opcache.memory_consumption']),
'used_memory' => $memsize($status['memory_usage']['used_memory']),
'free_memory' => $memsize($status['memory_usage']['free_memory']),
'wasted_memory' => $memsize($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']),
'start_time' => date_format(date_create("@{$status['opcache_statistics']['start_time']}"),
'Y-m-d H:i:s'),
'last_restart_time' => ($status['opcache_statistics']['last_restart_time'] == 0
? 'never'
:
date_format(date_create("@{$status['opcache_statistics']['last_restart_time']}"),
'Y-m-d H:i:s')
)
]
]
);
$directives = [];
ksort($config['directives']);
foreach ($config['directives'] as $k => $v) {
$directives[] = ['k' => $k, 'v' => $v];
}
$version = array_merge(
$config['version'],
[
'php' => phpversion(),
'server' => $_SERVER['SERVER_SOFTWARE'],
'host' => (function_exists('gethostname')
? gethostname()
: (php_uname('n')
?: (empty($_SERVER['SERVER_NAME'])
? $_SERVER['HOST_NAME']
: $_SERVER['SERVER_NAME']
)
)
)
]
);
return [
'version' => $version,
'overview' => $overview,
'files' => $files,
'directives' => $directives,
'blacklist' => $config['blacklist'],
'functions' => get_extension_funcs('Zend OPcache')
];
}
}
$opcache = OpCacheService::init();
?>
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>OPcache statistics on <?php echo $opcache->getData('version', 'host'); ?></title>
<script src="//cdn.jsdelivr.net/react/0.12.2/react.min.js"></script>
<script src="//code.jquery.com/jquery-2.1.3.min.js"></script>
<style type="text/css">
body {
font-family: sans-serif;
font-size: 90%;
padding: 0;
margin: 0
}
nav {
padding-top: 20px;
}
nav > ul {
list-style-type: none;
padding-left: 8px;
margin: 0;
border-bottom: 1px solid #ccc;
}
nav > ul > li {
display: inline-block;
padding: 0;
margin: 0 0 -1px 0;
}
nav > ul > li > a {
display: block;
margin: 0 10px;
padding: 15px 30px;
border: 1px solid transparent;
border-bottom-color: #ccc;
text-decoration: none;
}
nav > ul > li > a:hover {
background-color: #f4f4f4;
text-decoration: underline;
}
nav > ul > li > a.active:hover {
background-color: initial;
}
nav > ul > li > a[data-for].active {
border: 1px solid #ccc;
border-bottom-color: #ffffff;
border-top: 3px solid #6ca6ef;
}
table {
margin: 0 0 1em 0;
border-collapse: collapse;
border-color: #fff;
width: 100%;
}
table caption {
text-align: left;
font-size: 1.5em;
}
table tr {
background-color: #99D0DF;
border-color: #fff;
}
table th {
text-align: left;
padding: 6px;
background-color: #6ca6ef;
color: #fff;
border-color: #fff;
font-weight: normal;
}
table td {
padding: 4px 6px;
line-height: 1.4em;
vertical-align: top;
border-color: #fff;
}
table tr:nth-child(odd) {
background-color: #EFFEFF;
}
table tr:nth-child(even) {
background-color: #E0ECEF;
}
td.pathname {
width: 70%;
}
footer {
border-top: 1px solid #ccc;
padding: 1em 2em;
}
footer a {
padding: 2em;
text-decoration: none;
opacity: 0.7;
}
footer a:hover {
opacity: 1;
}
#tabs {
padding: 2em;
}
#tabs > div {
display: none;
}
#tabs > div#overview {
display: block;
}
#resetCache, #toggleRealtime, footer > a {
background-position: 5px 50%;
background-repeat: no-repeat;
background-color: transparent;
}
footer > a {
background-position: 0 50%;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjE2MENCRkExNzVBQjExRTQ5NDBGRTUzMzQyMDVDNzFFIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjE2MENCRkEyNzVBQjExRTQ5NDBGRTUzMzQyMDVDNzFFIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MTYwQ0JGOUY3NUFCMTFFNDk0MEZFNTMzNDIwNUM3MUUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MTYwQ0JGQTA3NUFCMTFFNDk0MEZFNTMzNDIwNUM3MUUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7HtUU1AAABN0lEQVR42qyUvWoCQRSF77hCLLKC+FOlCKTyIbYQUuhbWPkSFnZ2NpabUvANLGyz5CkkYGMlFtFAUmiSM8lZOVkWsgm58K079+fMnTusZl92BXbgDrTtZ2szd8fas/XBOzmBKaiCEFyTkL4pc9L8vgpNJJDyWtDna61EoXpO+xcFfXUVqtrf7Vx7m9Pub/EatvgHoYXD4ylztC14BBVwydvydgDPHPgNaErN3jLKIxAUmEvAXK21I18SJpXBGAxyBAaMlblOWOs1bMXFkMGeBFsi0pJNe/QNuV7563+gs8LfhrRfE6GaHLuRqfnUiKi6lJ034B44EXL0baTTJWujNGkG3kBX5uRyZuRkPl3WzDTBtzjnxxiDDq83yNxUk7GYuXM53jeLuMNavvAXkv4zrJkTaeGHAAMAIal3icPMsyQAAAAASUVORK5CYII=');
font-size: 80%;
}
#resetCache {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NjBFMUMyMjI3NDlGMTFFNEE3QzNGNjQ0OEFDQzQ1MkMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NjBFMUMyMjM3NDlGMTFFNEE3QzNGNjQ0OEFDQzQ1MkMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MEUxQzIyMDc0OUYxMUU0QTdDM0Y2NDQ4QUNDNDUyQyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo2MEUxQzIyMTc0OUYxMUU0QTdDM0Y2NDQ4QUNDNDUyQyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PplZ+ZkAAAD1SURBVHjazFPtDYJADIUJZAMZ4UbACWQENjBO4Ao6AW5AnODcADZQJwAnwJ55NbWhB/6zycsdpX39uDZNpsURtjgzwkDoCBecs5ITPGGMwCNAkIrQw+8ri36GhBHsavFdpILEo4wEpZxRigy009EhG760gr0VhFoyZfvJKPwsheIWIeGejBZRIxRVhMRFevbuUXBew/iE/lhlBduV0j8Jx+TvJEWPphq8n5li9utgaw6cW/h6NSt/JcnVBhQxotIgKTBrbNvIHo2G0x1rwlKqTDusxiAz6hHNL1zayTVqVKRKpa/LPljPH1sJh6l/oNSrZfwSYABtq3tFdZA5BAAAAABJRU5ErkJggg==');
}
#toggleRealtime {
position: relative;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAUCAYAAACAl21KAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODE5RUU4NUE3NDlGMTFFNDkyMzA4QzY1RjRBQkIzQjUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODE5RUU4NUI3NDlGMTFFNDkyMzA4QzY1RjRBQkIzQjUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4MTlFRTg1ODc0OUYxMUU0OTIzMDhDNjVGNEFCQjNCNSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4MTlFRTg1OTc0OUYxMUU0OTIzMDhDNjVGNEFCQjNCNSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpXjpvMAAAD2SURBVHjarFQBEcMgDKR3E1AJldA5wMEqAQmTgINqmILdFCChdUAdMAeMcukuSwnQbbnLlZLwJPkQIcrSiT/IGNQHNb8CGQDyRw+2QWUBqC+luzo4OKQZIAVrB+ssyKp3Bkijf0+ijzIh4wQppoBauMSjyDZfMSCDxYZMsfHF120T36AqWZMkgyguQ3GOfottJ5TKnHC+wfeRsC2oDVayPgr3bbN2tHBH3tWuJCPa0JUgKtFzMQrcZH3FNHAc0yOp1cCASALyngoN6lhDopkJWxdifwY9A3u7l29ImpxOFSWIOVsGwHKENIWxss2eBVKdOeeXAAMAk/Z9h4QhXmUAAAAASUVORK5CYII=');
}
#counts {
width: 270px;
float: right;
}
#counts > div > div {
background-color: #ededed;
margin-bottom: 10px;
}
#counts > div > div > h3 {
background-color: #cdcdcd;
padding: 4px 6px;
margin: 0;
}
#counts > div > div > p {
margin: 0;
text-align: center;
}
#counts > div > div > p > span.large + span {
font-size: 20pt;
margin: 0;
}
#counts > div > div > p > span.large {
font-size: 80pt;
margin: 0;
padding: 0;
text-align: center;
}
#info {
margin-right: 280px;
}
#frmFilter {
width: 520px;
}
#moreinfo {
padding: 10px;
}
#moreinfo > p {
text-align: left !important;
line-height: 180%;
}
.metainfo {
font-size: 80%;
}
.hide {
display: none;
}
#toggleRealtime.pulse::before {
content: "";
position: absolute;
top: 13px;
left: 3px;
width: 18px;
height: 18px;
z-index: 10;
opacity: 0;
background-color: transparent;
border: 2px solid rgb(255, 116, 0);
border-radius: 100%;
-webkit-animation: pulse 1s linear 2;
-moz-animation: pulse 1s linear 2;
animation: pulse 1s linear 2;
}
@media screen and (max-width: 750px) {
#info {
margin-right: auto;
clear: both;
}
nav > ul {
border-bottom: 0;
}
nav > ul > li {
display: block;
margin: 0;
}
nav > ul > li > a {
display: block;
margin: 0 10px;
padding: 10px 0 10px 30px;
border: 0;
}
nav > ul > li > a[data-for].active {
border-bottom-color: #ccc;
}
#counts {
position: relative;
display: block;
width: 100%;
}
#toggleRealtime.pulse::before {
top: 8px;
}
}
@media screen and (max-width: 550px) {
#frmFilter {
width: 100%;
}
}
@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;
}
}
</style>
</head>
<body>
<header>
<nav>
<ul>
<!-- #nZEDb -->
<li><a href="<?php echo $nZEDbURL; ?>" class="button">nZEDb</a></li>
<!-- #nZEDb -->
<li><a data-for="overview" href="#overview" class="active">Overview</a></li>
<li><a data-for="files" href="#files">File usage</a></li>
<li><a href="?reset=1"
id="resetCache"
onclick="return confirm('Are you sure you want to reset the cache?');">Reset
cache</a>
</li>
<li><a href="#" id="toggleRealtime">Enable real-time update</a></li>
</ul>
</nav>
</header>
<div id="tabs">
<div id="overview">
<div class="container">
<div id="counts"></div>
<div id="info">
<div id="generalInfo"></div>
<div id="directives"></div>
<div id="functions">
<table>
<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>
<br style="clear:both;" />
</div>
</div>
</div>
<div id="files">
<p><label>Start typing to filter on script path<br /><input type="text"
name="filter"
id="frmFilter" /><label></p>
<div class="container" id="filelist"></div>
</div>
</div>
<footer>
<a href="https://github.com/amnuts/opcache-gui" target="_blank">https://github.com/amnuts/opcache-gui</a>
</footer>
<script type="text/javascript">
var realtime = false;
var opstate = <?php echo json_encode($opcache->getData()); ?>;
var canInvalidate = <?php echo ($opcache->canInvalidate() ? 'true' : 'false'); ?>;
$(function () {
function updateStatus() {
$('#toggleRealtime').removeClass('pulse');
$.ajax({
url: "#",
dataType: "json",
cache: false,
success: function (data) {
$('#toggleRealtime').addClass('pulse');
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
});
$('#frmFilter').trigger('keyup');
}
});
}
$('#toggleRealtime').click(function () {
if (realtime === false) {
realtime = setInterval(function () {
updateStatus()
}, 5000);
$(this).text('Disable real-time update');
} else {
clearInterval(realtime);
realtime = false;
$(this).text('Enable real-time update').removeClass('pulse');
}
});
$('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) {
var trs = $('tr', $(this)).not('.hide');
trs.filter(':odd').css({backgroundColor: '#E0ECEF'})
.end().filter(':even').css({backgroundColor: '#EFFEFF'});
filesObj.setState({showing: trs.length});
});
$('#frmFilter').bind('keyup', function (event) {
$('span.pathname').each(function (index) {
if ($(this).text().toLowerCase().indexOf($('#frmFilter').val().toLowerCase()) ==
-1) {
$(this).closest('tr').addClass('hide');
} else {
$(this).closest('tr').removeClass('hide');
}
});
$('#filelist table tbody').trigger('paint');
});
});
var OverviewCounts = React.createClass({
displayName: 'OverviewCounts',
getInitialState: function () {
return {data: opstate.overview};
},
render: function () {
return (
React.createElement("div", null,
React.createElement("div", null,
React.createElement("h3", null, "memory usage"),
React.createElement("p",
null,
React.createElement("span",
{className: "large"},
this.state.data.used_memory_percentage),
React.createElement("span", null, "%"))
),
React.createElement("div", null,
React.createElement("h3", null, "hit rate"),
React.createElement("p",
null,
React.createElement("span",
{className: "large"},
this.state.data.hit_rate_percentage),
React.createElement("span", null, "%"))
),
React.createElement("div", {id: "moreinfo"},
React.createElement("p",
null,
React.createElement("b", null, "total memory:"),
this.state.data.readable.total_memory),
React.createElement("p",
null,
React.createElement("b", null, "used memory:"),
this.state.data.readable.used_memory),
React.createElement("p",
null,
React.createElement("b", null, "free memory:"),
this.state.data.readable.free_memory),
React.createElement("p",
null,
React.createElement("b", null, "wasted memory:"),
this.state.data.readable.wasted_memory,
" (",
this.state.data.wasted_percentage,
"%)"),
React.createElement("p",
null,
React.createElement("b", null, "number of cached files:"),
this.state.data.readable.num_cached_scripts),
React.createElement("p",
null,
React.createElement("b", null, "number of hits:"),
this.state.data.readable.hits),
React.createElement("p",
null,
React.createElement("b", null, "number of misses:"),
this.state.data.readable.misses),
React.createElement("p",
null,
React.createElement("b", null, "blacklist misses:"),
this.state.data.readable.blacklist_miss),
React.createElement("p",
null,
React.createElement("b", null, "number of cached keys:"),
this.state.data.readable.num_cached_keys),
React.createElement("p",
null,
React.createElement("b", null, "max cached keys:"),
this.state.data.readable.max_cached_keys)
)
)
);
}
});
var GeneralInfo = React.createClass({
displayName: 'GeneralInfo',
getInitialState: function () {
return {
version: opstate.version,
start: opstate.overview.readable.start_time,
reset: opstate.overview.readable.last_restart_time
};
},
render: function () {
return (
React.createElement("table", null,
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)),
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)),
React.createElement("tr",
null,
React.createElement("td", null, "Start time"),
React.createElement("td", null, this.state.start)),
React.createElement("tr",
null,
React.createElement("td", null, "Last reset"),
React.createElement("td", null, this.state.reset))
)
)
);
}
});
var Directives = React.createClass({
displayName: 'Directives',
getInitialState: function () {
return {data: opstate.directives};
},
render: function () {
var directiveNodes = this.state.data.map(function (directive) {
var map = {'opcache.': '', '_': ' '};
var dShow = directive.k.replace(/opcache\.|_/gi, function (matched) {
return map[matched];
});
var vShow;
if (directive.v === true || directive.v === false) {
vShow = React.createElement('i', {}, directive.v.toString());
} else {
if (directive.v == '') {
vShow = React.createElement('i', {}, 'no value');
} else {
vShow = directive.v;
}
}
return (
React.createElement("tr", {key: directive.k},
React.createElement("td", {title: directive.k}, dShow),
React.createElement("td", null, vShow)
)
);
});
return (
React.createElement("table", null,
React.createElement("thead", null,
React.createElement("tr",
null,
React.createElement("th", {colSpan: "2"}, "Directives"))
),
React.createElement("tbody", null, directiveNodes)
)
);
}
});
var Files = React.createClass({
displayName: 'Files',
getInitialState: function () {
return {
data: opstate.files,
showing: null
};
},
handleInvalidate: function (e) {
e.preventDefault();
if (realtime) {
$.get('#',
{invalidate: e.currentTarget.getAttribute('data-file')},
function (data) {
console.log('success: ' + data.success);
},
'json');
} else {
window.location.href = e.currentTarget.href;
}
},
render: function () {
var fileNodes = this.state.data.map(function (file) {
var invalidate, invalidated;
if (file.timestamp == 0) {
invalidated = React.createElement("span",
null,
React.createElement("i",
{className: "invalid metainfo"},
"has been invalidated"));
}
if (canInvalidate) {
invalidate = React.createElement("span", null, ", ", React.createElement("a",
{
className: "metainfo",
href: '?invalidate='
+ file.full_path,
'data-file': file.full_path,
onClick: this.handleInvalidate
},
"force file invalidation"));
}
return (
React.createElement("tr", {key: file.full_path},
React.createElement("td", null,
React.createElement("div", null,
React.createElement("span",
{className: "pathname"},
file.full_path), React.createElement("br", null),
React.createElement(FilesMeta,
{
data: [
file.readable.hits,
file.readable.memory_consumption,
file.last_used
]
}),
invalidate,
invalidated
)
)
)
);
}.bind(this));
return (
React.createElement("div", null,
React.createElement(FilesListed, {showing: this.state.showing}),
React.createElement("table", null,
React.createElement("thead",
null,
React.createElement("tr",
null,
React.createElement("th", null, "Script"))),
React.createElement("tbody", null, fileNodes)
)
)
);
}
});
var FilesMeta = React.createClass({
displayName: 'FilesMeta',
render: function () {
return (
React.createElement("span",
{className: "metainfo"},
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])
)
);
}
});
var FilesListed = React.createClass({
displayName: 'FilesListed',
getInitialState: function () {
return {
formatted: opstate.overview.readable.num_cached_scripts,
total: opstate.overview.num_cached_scripts
};
},
render: function () {
var display = this.state.formatted +
' file' +
(this.state.total == 1 ? '' : 's') +
' cached';
if (this.props.showing !== null && this.props.showing != this.state.total) {
display += ', ' + this.props.showing + ' showing due to filter';
}
return (React.createElement("h3", null, display));
}
});
var overviewCountsObj = React.render(React.createElement(OverviewCounts, null),
document.getElementById('counts'));
var generalInfoObj = React.render(React.createElement(GeneralInfo, null),
document.getElementById('generalInfo'));
var filesObj = React.render(React.createElement(Files, null),
document.getElementById('filelist'));
React.render(React.createElement(Directives, null), document.getElementById('directives'));
</script>
</body>
</html>