Date/time updates

Added new config option to change the format of the date/time strings throughout the interface.

Added `last modified` date/time output to the file cache list, and added the last modified as a sorting option (fixes PR#82).
This commit is contained in:
Andrew Collington 2022-07-16 18:46:15 +01:00
parent d87d89121d
commit 17e8f6e708
4 changed files with 97 additions and 62 deletions

View file

@ -73,24 +73,25 @@ The default configuration for the interface looks like this:
```php ```php
$options = [ $options = [
'allow_filelist' => true, // show/hide the files tab 'allow_filelist' => true, // show/hide the files tab
'allow_invalidate' => true, // give a link to invalidate files 'allow_invalidate' => true, // give a link to invalidate files
'allow_reset' => true, // give option to reset the whole cache 'allow_reset' => true, // give option to reset the whole cache
'allow_realtime' => true, // give option to enable/disable real-time updates 'allow_realtime' => true, // give option to enable/disable real-time updates
'refresh_time' => 5, // how often the data will refresh, in seconds 'refresh_time' => 5, // how often the data will refresh, in seconds
'size_precision' => 2, // Digits after decimal point 'size_precision' => 2, // Digits after decimal point
'size_space' => false, // have '1MB' or '1 MB' when showing sizes 'size_space' => false, // have '1MB' or '1 MB' when showing sizes
'charts' => true, // show gauge chart or just big numbers 'charts' => true, // show gauge chart or just big numbers
'debounce_rate' => 250, // milliseconds after key press to send keyup event when filtering 'debounce_rate' => 250, // milliseconds after key press to send keyup event when filtering
'per_page' => 200, // How many results per page to show in the file list, false for no pagination 'per_page' => 200, // How many results per page to show in the file list, false for no pagination
'cookie_name' => 'opcachegui', // name of cookie 'cookie_name' => 'opcachegui', // name of cookie
'cookie_ttl' => 365, // days to store cookie 'cookie_ttl' => 365, // days to store cookie
'highlight' => [ 'datetime_format' => 'D, d M Y H:i:s O', // Show datetime in this format
'memory' => true, // show the memory chart/big number 'highlight' => [
'hits' => true, // show the hit rate chart/big number 'memory' => true, // show the memory chart/big number
'keys' => true, // show the keys used chart/big number 'hits' => true, // show the hit rate chart/big number
'jit' => true // show the jit buffer chart/big number 'keys' => true, // show the keys used chart/big number
] 'jit' => true // show the jit buffer chart/big number
]
]; ];
``` ```
@ -172,6 +173,11 @@ Also, if you choose to invalidate any files or reset the cache it will do this w
# Releases # Releases
**Version 3.4.0**\
* Added new `datetime_format` config option for flexible formatting of date/time values
* Added the cached file's `modified` date/time to the output (when the file was either added or updated)
* Added PR#83 from @Stevemoretz
**Version 3.3.1**\ **Version 3.3.1**\
Just a few minor tweaks: Just a few minor tweaks:
* Added more of an explanation to the JIT value * Added more of an explanation to the JIT value

View file

@ -777,6 +777,7 @@ class CachedFiles extends React.Component {
<nav className="filter" aria-label="Sort order"> <nav className="filter" aria-label="Sort order">
<select name="sortBy" onChange={this.changeSort} value={this.state.sortBy}> <select name="sortBy" onChange={this.changeSort} value={this.state.sortBy}>
<option value="last_used_timestamp">Last used</option> <option value="last_used_timestamp">Last used</option>
<option value="last_modified">Last modified</option>
<option value="full_path">Path</option> <option value="full_path">Path</option>
<option value="hits">Number of hits</option> <option value="hits">Number of hits</option>
<option value="memory_consumption">Memory consumption</option> <option value="memory_consumption">Memory consumption</option>
@ -832,6 +833,7 @@ class CachedFile extends React.Component {
<span className="file-metainfo"> <span className="file-metainfo">
<b>hits: </b><span>{this.props.readable.hits}, </span> <b>hits: </b><span>{this.props.readable.hits}, </span>
<b>memory: </b><span>{this.props.readable.memory_consumption}, </span> <b>memory: </b><span>{this.props.readable.memory_consumption}, </span>
{ this.props.last_modified && <span><b>last modified: </b><span>{this.props.last_modified}, </span></span> }
<b>last used: </b><span>{this.props.last_used}</span> <b>last used: </b><span>{this.props.last_used}</span>
</span> </span>
{ !this.props.timestamp && <span className="invalid file-metainfo"> - has been invalidated</span> } { !this.props.timestamp && <span className="invalid file-metainfo"> - has been invalidated</span> }

View file

@ -64,27 +64,29 @@ class Service
{ {
public const VERSION = '3.4.0'; public const VERSION = '3.4.0';
protected $tz;
protected $data; protected $data;
protected $options; protected $options;
protected $optimizationLevels; protected $optimizationLevels;
protected $defaults = [ protected $defaults = [
'allow_filelist' => true, // show/hide the files tab 'allow_filelist' => true, // show/hide the files tab
'allow_invalidate' => true, // give a link to invalidate files 'allow_invalidate' => true, // give a link to invalidate files
'allow_reset' => true, // give option to reset the whole cache 'allow_reset' => true, // give option to reset the whole cache
'allow_realtime' => true, // give option to enable/disable real-time updates 'allow_realtime' => true, // give option to enable/disable real-time updates
'refresh_time' => 5, // how often the data will refresh, in seconds 'refresh_time' => 5, // how often the data will refresh, in seconds
'size_precision' => 2, // Digits after decimal point 'size_precision' => 2, // Digits after decimal point
'size_space' => false, // have '1MB' or '1 MB' when showing sizes 'size_space' => false, // have '1MB' or '1 MB' when showing sizes
'charts' => true, // show gauge chart or just big numbers 'charts' => true, // show gauge chart or just big numbers
'debounce_rate' => 250, // milliseconds after key press to send keyup event when filtering 'debounce_rate' => 250, // milliseconds after key press to send keyup event when filtering
'per_page' => 200, // How many results per page to show in the file list, false for no pagination 'per_page' => 200, // How many results per page to show in the file list, false for no pagination
'cookie_name' => 'opcachegui', // name of cookie 'cookie_name' => 'opcachegui', // name of cookie
'cookie_ttl' => 365, // days to store cookie 'cookie_ttl' => 365, // days to store cookie
'datetime_format' => 'D, d M Y H:i:s O', // Show datetime in this format
'highlight' => [ 'highlight' => [
'memory' => true, // show the memory chart/big number 'memory' => true, // show the memory chart/big number
'hits' => true, // show the hit rate chart/big number 'hits' => true, // show the hit rate chart/big number
'keys' => true, // show the keys used chart/big number 'keys' => true, // show the keys used chart/big number
'jit' => true // show the jit buffer chart/big number 'jit' => true // show the jit buffer chart/big number
] ]
]; ];
protected $jitModes = [ protected $jitModes = [
@ -158,6 +160,7 @@ class Service
1 << 15 => 'Inline functions' 1 << 15 => 'Inline functions'
]; ];
$this->options = array_merge($this->defaults, $options); $this->options = array_merge($this->defaults, $options);
$this->tz = new DateTimeZone(date_default_timezone_get());
$this->data = $this->compileState(); $this->data = $this->compileState();
} }
@ -321,6 +324,15 @@ class Service
'hits' => number_format($file['hits']), 'hits' => number_format($file['hits']),
'memory_consumption' => $this->size($file['memory_consumption']) 'memory_consumption' => $this->size($file['memory_consumption'])
]; ];
$file['last_used'] = (new DateTimeImmutable("@{$file['last_used_timestamp']}"))
->setTimezone($this->tz)
->format($this->getOption('datetime_format'));
$file['last_modified'] = "";
if (!empty($file['timestamp'])) {
$file['last_modified'] = (new DateTimeImmutable("@{$file['timestamp']}"))
->setTimezone($this->tz)
->format($this->getOption('datetime_format'));
}
} }
$files = array_values($status['scripts']); $files = array_values($status['scripts']);
} }
@ -353,13 +365,13 @@ class Service
'max_cached_keys' => number_format($status['opcache_statistics']['max_cached_keys']), 'max_cached_keys' => number_format($status['opcache_statistics']['max_cached_keys']),
'interned' => null, 'interned' => null,
'start_time' => (new DateTimeImmutable("@{$status['opcache_statistics']['start_time']}")) 'start_time' => (new DateTimeImmutable("@{$status['opcache_statistics']['start_time']}"))
->setTimezone(new DateTimeZone(date_default_timezone_get())) ->setTimezone($this->tz)
->format('Y-m-d H:i:s'), ->format($this->getOption('datetime_format')),
'last_restart_time' => ($status['opcache_statistics']['last_restart_time'] === 0 'last_restart_time' => ($status['opcache_statistics']['last_restart_time'] === 0
? 'never' ? 'never'
: (new DateTimeImmutable("@{$status['opcache_statistics']['last_restart_time']}")) : (new DateTimeImmutable("@{$status['opcache_statistics']['last_restart_time']}"))
->setTimezone(new DateTimeZone(date_default_timezone_get())) ->setTimezone($this->tz)
->format('Y-m-d H:i:s') ->format($this->getOption('datetime_format'))
) )
] ]
] ]
@ -434,7 +446,7 @@ class Service
$version = array_merge( $version = array_merge(
$config['version'], $config['version'],
[ [
'php' => phpversion(), 'php' => PHP_VERSION,
'server' => $_SERVER['SERVER_SOFTWARE'] ?: '', 'server' => $_SERVER['SERVER_SOFTWARE'] ?: '',
'host' => (function_exists('gethostname') 'host' => (function_exists('gethostname')
? gethostname() ? gethostname()
@ -1283,6 +1295,8 @@ class CachedFiles extends React.Component {
}, /*#__PURE__*/React.createElement("option", { }, /*#__PURE__*/React.createElement("option", {
value: "last_used_timestamp" value: "last_used_timestamp"
}, "Last used"), /*#__PURE__*/React.createElement("option", { }, "Last used"), /*#__PURE__*/React.createElement("option", {
value: "last_modified"
}, "Last modified"), /*#__PURE__*/React.createElement("option", {
value: "full_path" value: "full_path"
}, "Path"), /*#__PURE__*/React.createElement("option", { }, "Path"), /*#__PURE__*/React.createElement("option", {
value: "hits" value: "hits"
@ -1337,7 +1351,7 @@ class CachedFile extends React.Component {
className: "file-pathname" className: "file-pathname"
}, this.props.full_path), /*#__PURE__*/React.createElement("span", { }, this.props.full_path), /*#__PURE__*/React.createElement("span", {
className: "file-metainfo" className: "file-metainfo"
}, /*#__PURE__*/React.createElement("b", null, "hits: "), /*#__PURE__*/React.createElement("span", null, this.props.readable.hits, ", "), /*#__PURE__*/React.createElement("b", null, "memory: "), /*#__PURE__*/React.createElement("span", null, this.props.readable.memory_consumption, ", "), /*#__PURE__*/React.createElement("b", null, "last used: "), /*#__PURE__*/React.createElement("span", null, this.props.last_used)), !this.props.timestamp && /*#__PURE__*/React.createElement("span", { }, /*#__PURE__*/React.createElement("b", null, "hits: "), /*#__PURE__*/React.createElement("span", null, this.props.readable.hits, ", "), /*#__PURE__*/React.createElement("b", null, "memory: "), /*#__PURE__*/React.createElement("span", null, this.props.readable.memory_consumption, ", "), this.props.last_modified && /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("b", null, "last modified: "), /*#__PURE__*/React.createElement("span", null, this.props.last_modified, ", ")), /*#__PURE__*/React.createElement("b", null, "last used: "), /*#__PURE__*/React.createElement("span", null, this.props.last_used)), !this.props.timestamp && /*#__PURE__*/React.createElement("span", {
className: "invalid file-metainfo" className: "invalid file-metainfo"
}, " - has been invalidated"), this.props.canInvalidate && /*#__PURE__*/React.createElement("span", null, ",\xA0", /*#__PURE__*/React.createElement("a", { }, " - has been invalidated"), this.props.canInvalidate && /*#__PURE__*/React.createElement("span", null, ",\xA0", /*#__PURE__*/React.createElement("a", {
className: "file-metainfo", className: "file-metainfo",

View file

@ -10,27 +10,29 @@ class Service
{ {
public const VERSION = '3.4.0'; public const VERSION = '3.4.0';
protected $tz;
protected $data; protected $data;
protected $options; protected $options;
protected $optimizationLevels; protected $optimizationLevels;
protected $defaults = [ protected $defaults = [
'allow_filelist' => true, // show/hide the files tab 'allow_filelist' => true, // show/hide the files tab
'allow_invalidate' => true, // give a link to invalidate files 'allow_invalidate' => true, // give a link to invalidate files
'allow_reset' => true, // give option to reset the whole cache 'allow_reset' => true, // give option to reset the whole cache
'allow_realtime' => true, // give option to enable/disable real-time updates 'allow_realtime' => true, // give option to enable/disable real-time updates
'refresh_time' => 5, // how often the data will refresh, in seconds 'refresh_time' => 5, // how often the data will refresh, in seconds
'size_precision' => 2, // Digits after decimal point 'size_precision' => 2, // Digits after decimal point
'size_space' => false, // have '1MB' or '1 MB' when showing sizes 'size_space' => false, // have '1MB' or '1 MB' when showing sizes
'charts' => true, // show gauge chart or just big numbers 'charts' => true, // show gauge chart or just big numbers
'debounce_rate' => 250, // milliseconds after key press to send keyup event when filtering 'debounce_rate' => 250, // milliseconds after key press to send keyup event when filtering
'per_page' => 200, // How many results per page to show in the file list, false for no pagination 'per_page' => 200, // How many results per page to show in the file list, false for no pagination
'cookie_name' => 'opcachegui', // name of cookie 'cookie_name' => 'opcachegui', // name of cookie
'cookie_ttl' => 365, // days to store cookie 'cookie_ttl' => 365, // days to store cookie
'datetime_format' => 'D, d M Y H:i:s O', // Show datetime in this format
'highlight' => [ 'highlight' => [
'memory' => true, // show the memory chart/big number 'memory' => true, // show the memory chart/big number
'hits' => true, // show the hit rate chart/big number 'hits' => true, // show the hit rate chart/big number
'keys' => true, // show the keys used chart/big number 'keys' => true, // show the keys used chart/big number
'jit' => true // show the jit buffer chart/big number 'jit' => true // show the jit buffer chart/big number
] ]
]; ];
protected $jitModes = [ protected $jitModes = [
@ -81,6 +83,7 @@ class Service
/** /**
* Service constructor. * Service constructor.
* @param array $options * @param array $options
* @throws Exception
*/ */
public function __construct(array $options = []) public function __construct(array $options = [])
{ {
@ -103,6 +106,7 @@ class Service
1 << 15 => 'Inline functions' 1 << 15 => 'Inline functions'
]; ];
$this->options = array_merge($this->defaults, $options); $this->options = array_merge($this->defaults, $options);
$this->tz = new DateTimeZone(date_default_timezone_get());
$this->data = $this->compileState(); $this->data = $this->compileState();
} }
@ -266,6 +270,15 @@ class Service
'hits' => number_format($file['hits']), 'hits' => number_format($file['hits']),
'memory_consumption' => $this->size($file['memory_consumption']) 'memory_consumption' => $this->size($file['memory_consumption'])
]; ];
$file['last_used'] = (new DateTimeImmutable("@{$file['last_used_timestamp']}"))
->setTimezone($this->tz)
->format($this->getOption('datetime_format'));
$file['last_modified'] = "";
if (!empty($file['timestamp'])) {
$file['last_modified'] = (new DateTimeImmutable("@{$file['timestamp']}"))
->setTimezone($this->tz)
->format($this->getOption('datetime_format'));
}
} }
$files = array_values($status['scripts']); $files = array_values($status['scripts']);
} }
@ -298,13 +311,13 @@ class Service
'max_cached_keys' => number_format($status['opcache_statistics']['max_cached_keys']), 'max_cached_keys' => number_format($status['opcache_statistics']['max_cached_keys']),
'interned' => null, 'interned' => null,
'start_time' => (new DateTimeImmutable("@{$status['opcache_statistics']['start_time']}")) 'start_time' => (new DateTimeImmutable("@{$status['opcache_statistics']['start_time']}"))
->setTimezone(new DateTimeZone(date_default_timezone_get())) ->setTimezone($this->tz)
->format('Y-m-d H:i:s'), ->format($this->getOption('datetime_format')),
'last_restart_time' => ($status['opcache_statistics']['last_restart_time'] == 0 'last_restart_time' => ($status['opcache_statistics']['last_restart_time'] === 0
? 'never' ? 'never'
: (new DateTimeImmutable("@{$status['opcache_statistics']['last_restart_time']}")) : (new DateTimeImmutable("@{$status['opcache_statistics']['last_restart_time']}"))
->setTimezone(new DateTimeZone(date_default_timezone_get())) ->setTimezone($this->tz)
->format('Y-m-d H:i:s') ->format($this->getOption('datetime_format'))
) )
] ]
] ]
@ -379,7 +392,7 @@ class Service
$version = array_merge( $version = array_merge(
$config['version'], $config['version'],
[ [
'php' => phpversion(), 'php' => PHP_VERSION,
'server' => $_SERVER['SERVER_SOFTWARE'] ?: '', 'server' => $_SERVER['SERVER_SOFTWARE'] ?: '',
'host' => (function_exists('gethostname') 'host' => (function_exists('gethostname')
? gethostname() ? gethostname()