| 1 |
<?php |
| 2 |
/* |
| 3 |
Plugin Name: WP-Memory-Usage |
| 4 |
Plugin URI: https://www.json-content-importer.com |
| 5 |
Description: Show up memory limits, current memory usage, IP-Address, PHP-Version in the dashboard and admin footer |
| 6 |
Author: Bernhard Kux |
| 7 |
Version: 2.1.1 |
| 8 |
Author URI: https://www.json-content-importer.com |
| 9 |
Text Domain: wp-memory-usage |
| 10 |
Domain Path: /languages/ |
| 11 |
License: GPLv3 |
| 12 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html |
| 13 |
|
| 14 |
Copyright Bernhard Kux |
| 15 |
*/ |
| 16 |
|
| 17 |
/* block direct requests */ |
| 18 |
if ( !function_exists( 'add_action' ) ) { |
| 19 |
echo 'Hello, this is a plugin: You must not call me directly.'; |
| 20 |
exit; |
| 21 |
} |
| 22 |
defined('ABSPATH') OR exit; |
| 23 |
|
| 24 |
// Load translations early for both admin and frontend. |
| 25 |
function wpmu_load_textdomain() { |
| 26 |
$mofile = plugin_dir_path( __FILE__ ) . 'languages/wp-memory-usage-' . get_locale() . '.mo'; |
| 27 |
load_textdomain( 'wp-memory-usage', $mofile ); |
| 28 |
/* |
| 29 |
error_log( 'wpmu mo-file path: ' . $mofile ); |
| 30 |
error_log( 'wpmu mo-file exists: ' . ( file_exists( $mofile ) ? 'YES' : 'NO' ) ); |
| 31 |
error_log( 'wpmu locale: ' . get_locale() ); |
| 32 |
$mo = new MO(); |
| 33 |
if ( $mo->import_from_file( $mofile) ) { |
| 34 |
error_log( 'MO loaded OK, entries: ' . count( $mo->entries ) ); |
| 35 |
} else { |
| 36 |
error_log( 'MO load FAILED' ); |
| 37 |
} |
| 38 |
#load_plugin_textdomain( 'wp-memory-usage', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' ); |
| 39 |
*/ |
| 40 |
} |
| 41 |
add_action( 'plugins_loaded', 'wpmu_load_textdomain', 1 ); |
| 42 |
|
| 43 |
const WPMU_LOG_FILE = "wpmu-log.cgi"; |
| 44 |
const WPMU_LOG_PATH = ABSPATH. '../logs/wpmu/'; |
| 45 |
|
| 46 |
class wp_memory_usage { |
| 47 |
public $ipadr = ""; |
| 48 |
public $servername = ""; |
| 49 |
public $servernameout = ""; |
| 50 |
public $memory = array(); |
| 51 |
|
| 52 |
|
| 53 |
public function __construct() { |
| 54 |
$this->get_ip_address(); |
| 55 |
#$this->load_textdomain(); |
| 56 |
#add_action( 'init', array( $this, 'load_textdomain' ) ); |
| 57 |
add_action( 'init', array ($this, 'check_limit') ); |
| 58 |
add_action( 'wp_dashboard_setup', array ($this, 'add_dashboard') ); |
| 59 |
if ( is_multisite() ) { |
| 60 |
add_action( 'wp_network_dashboard_setup', array ($this, 'add_dashboard') ); |
| 61 |
} |
| 62 |
add_filter( 'admin_footer_text', array ($this, 'add_footer') ); |
| 63 |
} |
| 64 |
|
| 65 |
private function getinput($fieldkey, $default="") { |
| 66 |
#var_Dump($_GET); |
| 67 |
if ( |
| 68 |
! isset($_GET['_wpnonce']) || |
| 69 |
! wp_verify_nonce( sanitize_text_field(wp_unslash($_GET['_wpnonce'])), 'memusage' ) |
| 70 |
) { |
| 71 |
#echo "NONCE FAILED for GET $fieldkey<hr>"; |
| 72 |
return ""; #wp_die('Ung�ltiger Nonce � Sicherheits�berpr�fung fehlgeschlagen.'); |
| 73 |
} |
| 74 |
#echo "NONCE OK for GET $fieldkey<hr>"; |
| 75 |
return sanitize_text_field(wp_unslash(($_GET[$fieldkey] ?? $default))); |
| 76 |
} |
| 77 |
|
| 78 |
private function getserverinput($fieldkey, $default="") { |
| 79 |
return sanitize_text_field(wp_unslash(($_SERVER[$fieldkey] ?? $default))); |
| 80 |
} |
| 81 |
|
| 82 |
#public function load_textdomain() { |
| 83 |
# load_plugin_textdomain( 'wp-memory-usage', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' ); |
| 84 |
#} |
| 85 |
|
| 86 |
public function check_limit() { |
| 87 |
$this->memory['phplimit'] = ""; |
| 88 |
$this->memory['phplimitunity'] = 'MB'; |
| 89 |
if (!is_null(ini_get('memory_limit'))) { |
| 90 |
$phplimit_memory = ini_get('memory_limit'); |
| 91 |
if (preg_match("/G$/i", $phplimit_memory)) { |
| 92 |
# set in gigabyte |
| 93 |
$phplimit_memory = 1024 * preg_replace("/G$/i", "", $phplimit_memory); |
| 94 |
} |
| 95 |
$this->memory['phplimit'] = (int) $phplimit_memory; |
| 96 |
} |
| 97 |
$ret = $this->formatWP_MEMORY_LIMIT(WP_MEMORY_LIMIT); |
| 98 |
$this->memory["wpmb"] = $ret["mb"] ?? ''; |
| 99 |
$this->memory["wpunity"] = $ret["unity"] ?? ''; |
| 100 |
|
| 101 |
$ret = $this->formatWP_MEMORY_LIMIT(WP_MAX_MEMORY_LIMIT); |
| 102 |
$this->memory["wpmaxmb"] = $ret["mb"] ?? ''; |
| 103 |
$this->memory["wpmaxunity"] = $ret["unity"] ?? ''; |
| 104 |
} |
| 105 |
|
| 106 |
public function check_memory_usage() { |
| 107 |
$this->memory['usage'] = function_exists('memory_get_peak_usage') ? round(memory_get_peak_usage(true) / 1024 / 1024, 2) : 0; |
| 108 |
if ( !empty($this->memory['usage'])) { |
| 109 |
$this->memory['percent'] = -1; |
| 110 |
if (!empty($this->memory['wpmb']) && ($this->memory['wpmb']!=0)) { |
| 111 |
$this->memory['percent'] = round($this->memory['usage'] /$this->memory["wpmb"] * 100, 0); |
| 112 |
} |
| 113 |
|
| 114 |
$this->memory['percentphp'] = -1; |
| 115 |
if (!empty($this->memory['phplimit']) && ($this->memory['phplimit']!=0)) { |
| 116 |
$this->memory['percentphp'] = round ($this->memory['usage'] / $this->memory["phplimit"] * 100, 0); |
| 117 |
} |
| 118 |
|
| 119 |
//If the bar is too small we move the text outside |
| 120 |
$this->memory['percent_pos'] = ''; |
| 121 |
//In case we are in our limits take the admin color |
| 122 |
$this->memory['color'] = ''; |
| 123 |
if ($this->memory['percent'] > 80) $this->memory['color'] = 'background: #E66F00;'; |
| 124 |
if ($this->memory['percent'] > 95) $this->memory['color'] = 'background: red;'; |
| 125 |
if ($this->memory['percent'] < 10) $this->memory['percent_pos'] = 'margin-right: -30px; color: #444;'; |
| 126 |
$this->memory['percentwidth'] = $this->memory['percent']; |
| 127 |
if ($this->memory['percent']>100) { |
| 128 |
$this->memory['percentwidth'] = 100; |
| 129 |
} |
| 130 |
} |
| 131 |
} |
| 132 |
|
| 133 |
public function dashboard_output() { |
| 134 |
$this->check_memory_usage(); |
| 135 |
?> |
| 136 |
<ul> |
| 137 |
<li><strong><?php echo esc_html(__('PHP Version', 'wp-memory-usage')); ?>:</strong> <span><?php |
| 138 |
echo esc_html(PHP_VERSION); ?> / <?php echo esc_html((PHP_INT_SIZE * 8) . __('Bit OS', 'wp-memory-usage')); |
| 139 |
|
| 140 |
if (!is_null(ini_get('max_execution_time'))) { |
| 141 |
$max_execution_time = (int) ini_get('max_execution_time'). __('sec', 'wp-memory-usage'); |
| 142 |
echo " / ".esc_html(__('Max execution time: ', 'wp-memory-usage')).' '.esc_html($max_execution_time); |
| 143 |
} |
| 144 |
|
| 145 |
|
| 146 |
?></span></li> |
| 147 |
<li><strong><?php echo esc_html(__('Memory limits', 'wp-memory-usage')); ?>:</strong> <span> |
| 148 |
<?php |
| 149 |
if (!empty($this->memory["wpmb"])) { |
| 150 |
echo esc_html(__('Wordpress', 'wp-memory-usage').' '.$this->memory["wpmb"]. $this->memory["wpunity"])." / "; |
| 151 |
} |
| 152 |
if ($this->memory["wpmaxmb"]!="" && ($this->memory["wpmb"]!=$this->memory["wpmaxmb"])) { |
| 153 |
echo esc_html(__('Wordpress-Admin', 'wp-memory-usage').' '.$this->memory["wpmaxmb"]. $this->memory["wpmaxunity"])." / "; |
| 154 |
} |
| 155 |
if ($this->memory['phplimit']!="") { |
| 156 |
echo esc_html(__('PHP ', 'wp-memory-usage').' '.$this->memory['phplimit'].$this->memory['phplimitunity']); |
| 157 |
} |
| 158 |
?> |
| 159 |
</span></li> |
| 160 |
<li><strong><?php |
| 161 |
$mem = $this->memory['usage'] ?? 0; |
| 162 |
echo esc_html(__('Current Memory usage', 'wp-memory-usage')); ?>:</strong> <span><?php echo esc_html($mem.__('MB', 'wp-memory-usage')); ?> </span><br> |
| 163 |
|
| 164 |
<?php |
| 165 |
if ($this->memory['percent']>=0) { |
| 166 |
?> |
| 167 |
<div class="progressbar"> |
| 168 |
<div style="border:1px solid #DDDDDD; background-color:#F9F9F9; border-color: rgb(223, 223, 223); box-shadow: 0px 1px 0px rgb(255, 255, 255) inset; border-radius: 3px;"> |
| 169 |
<div class="button-primary" style="width: <?php echo esc_html($this->memory['percentwidth']); ?>%;<?php echo esc_html($this->memory['color']);?>padding: 0px;border-width:0px; color:#FFFFFF;text-align:right; border-color: rgb(223, 223, 223); box-shadow: 0px 1px 0px rgb(255, 255, 255) inset; border-radius: 3px; margin-top: -1px;"> |
| 170 |
<div style="padding:2px;<?php echo esc_html($this->memory['percent_pos']); ?>"><?php echo esc_html($this->memory['percent']); ?>%</div> |
| 171 |
</div> |
| 172 |
</div> |
| 173 |
</div> |
| 174 |
<?php } |
| 175 |
|
| 176 |
$settings_url = admin_url( 'options-general.php?page=wpmu-memory-alerts' ); |
| 177 |
echo '<a href="' . esc_url( $settings_url ) . '">' . esc_html__( 'Settings & Monitor', 'wp-memory-usage' ) . '</a>'; |
| 178 |
#echo $settings_link; |
| 179 |
|
| 180 |
// ── Neuester Digest ──────────────────────────────────────────── |
| 181 |
if ( class_exists( 'WPMU_Threshold_Alerts' ) ) { |
| 182 |
$digest_files = glob( ABSPATH . '../logs/wpmu/digest_*.cgibak' ) ?: array(); |
| 183 |
if ( ! empty( $digest_files ) ) { |
| 184 |
// neueste Datei |
| 185 |
usort( $digest_files, fn( $a, $b ) => filemtime( $b ) - filemtime( $a ) ); |
| 186 |
$latest = $digest_files[0]; |
| 187 |
// phpcs:disable WordPress.WP.AlternativeFunctions |
| 188 |
$fh = @fopen( $latest, 'rb' ); |
| 189 |
$digest_data = null; |
| 190 |
if ( $fh ) { |
| 191 |
flock( $fh, LOCK_SH ); |
| 192 |
$digest_data = json_decode( fgets( $fh ), true ); |
| 193 |
flock( $fh, LOCK_UN ); |
| 194 |
fclose( $fh ); |
| 195 |
} |
| 196 |
// phpcs:enable WordPress.WP.AlternativeFunctions |
| 197 |
if ( is_array( $digest_data ) && isset( $digest_data['status'] ) ) { |
| 198 |
$dw = (int) ( $digest_data['status']['warn'] ?? 0 ); |
| 199 |
$dd = (int) ( $digest_data['status']['danger'] ?? 0 ); |
| 200 |
$dc = (int) ( $digest_data['status']['critical'] ?? 0 ); |
| 201 |
$fn_label = basename( $latest ); |
| 202 |
$raw_ts = str_replace( array( 'digest_', '.cgibak' ), '', $fn_label ); |
| 203 |
$dt_obj = DateTime::createFromFormat( 'Y-m-d-H-i-s', $raw_ts ); |
| 204 |
$ts_label = $dt_obj ? wp_date( get_option('date_format') . ', ' . get_option('time_format'), $dt_obj->getTimestamp() ) : $fn_label; |
| 205 |
echo '<hr style="margin:8px 0;">'; |
| 206 |
echo '<strong>' . esc_html__( 'Latest Digest', 'wp-memory-usage' ) . ':</strong> <span style="font-size:11px;color:#888;">' . esc_html( $ts_label ) . '</span><br>'; |
| 207 |
#$any_alert = ( $dw + $dd + $dc ) > 0; |
| 208 |
echo '<span style="display:inline-flex;gap:6px;margin-top:4px;flex-wrap:wrap;">'; |
| 209 |
echo '<span style="background:' . esc_attr( $dw > 0 ? '#f0ad4e' : '#e8e8e8' ) . ';color:' . esc_attr( $dw > 0 ? '#3d2b00' : '#888' ) . ';padding:2px 8px;border-radius:10px;font-size:12px;font-weight:700;">âš ' . esc_html($dw) . '</span>'; |
| 210 |
echo '<span style="background:' . esc_attr( $dd > 0 ? '#d9534f' : '#e8e8e8' ) . ';color:' . esc_attr( $dd > 0 ? '#fff' : '#888' ) . ';padding:2px 8px;border-radius:10px;font-size:12px;font-weight:700;">🔴 ' . esc_html($dd) . '</span>'; |
| 211 |
echo '<span style="background:' . esc_attr( $dc > 0 ? '#8B0000' : '#e8e8e8' ) . ';color:' . esc_attr( $dc > 0 ? '#fff' : '#888' ) . ';padding:2px 8px;border-radius:10px;font-size:12px;font-weight:700;">🆘 ' . esc_html($dc) . '</span>'; |
| 212 |
echo '</span>'; |
| 213 |
$digest_url = admin_url( 'options-general.php?page=wpmu-memory-alerts&tab=digest' ); |
| 214 |
echo ' <a href="' . esc_url( $digest_url ) . '" style="font-size:11px;">' . esc_html__( '→ Digest', 'wp-memory-usage' ) . '</a>'; |
| 215 |
} |
| 216 |
} |
| 217 |
} |
| 218 |
?> |
| 219 |
|
| 220 |
|
| 221 |
|
| 222 |
</li> |
| 223 |
</ul> |
| 224 |
<?php |
| 225 |
} |
| 226 |
|
| 227 |
public function add_dashboard() { |
| 228 |
#$servertime = gmdate(__('d.m.Y, H:i:s', 'wp-memory-usage')); |
| 229 |
$servertime = wp_date( get_option('date_format') . ', ' . get_option('time_format') ); |
| 230 |
wp_add_dashboard_widget( 'wp_memory_dashboard', __('Memory Overview', 'wp-memory-usage')."<br>".__('Servertime', 'wp-memory-usage').": ".$servertime, array ($this, 'dashboard_output') ); |
| 231 |
} |
| 232 |
|
| 233 |
private function formatWP_MEMORY_LIMIT($valin) { #WP_MEMORY_LIMIT and WP_MAX_MEMORY_LIMIT come with size and unity |
| 234 |
$valin = $valin ?? ''; |
| 235 |
if (empty($valin)) { |
| 236 |
return $valin; |
| 237 |
} |
| 238 |
if (preg_match("/G$/i", $valin)) { |
| 239 |
# set in gigabyte |
| 240 |
$valinTmp = preg_replace("/G$/i", "", $valin); |
| 241 |
$valinNo = 1024 * $valinTmp; |
| 242 |
$valin = $valinNo."M"; |
| 243 |
} |
| 244 |
$size = strtolower(substr($valin, -1)); |
| 245 |
$number = (int) substr($valin, 0, -1); |
| 246 |
$ret = array(); |
| 247 |
if ($size=="k") { $ret["mb"] = ($number/1024); $ret["unity"] = "kB"; } |
| 248 |
if ($size=="m") { $ret["mb"] = $number; $ret["unity"] = "MB"; } |
| 249 |
if ($size=="g") { $ret["mb"] = ($number*1024); $ret["unity"] = "GB"; } |
| 250 |
if ($size=="t") { $ret["mb"] = ($number*(1024*1024)); $ret["unity"] = "TB"; } |
| 251 |
if ($size=="p") { $ret["mb"] = ($number*(1024*1024*1024)); $ret["unity"] = "PB"; } |
| 252 |
return $ret; |
| 253 |
} |
| 254 |
|
| 255 |
private function get_ip_address() { |
| 256 |
$get_SERVER_ADDR = $this->getserverinput('SERVER_ADDR'); |
| 257 |
#if (isset($_SERVER[ 'SERVER_ADDR' ]) && !empty($_SERVER[ 'SERVER_ADDR' ])) { |
| 258 |
if (!empty($get_SERVER_ADDR)) { |
| 259 |
$this->ipadr = $get_SERVER_ADDR; |
| 260 |
#$this->ipadr = $_SERVER[ 'SERVER_ADDR' ]; |
| 261 |
} |
| 262 |
$get_LOCAL_ADDR = $this->getserverinput('LOCAL_ADDR'); |
| 263 |
if (empty($this->ipadr) && !empty($get_LOCAL_ADDR)) { |
| 264 |
#if (empty($this->ipadr) && isset($_SERVER[ 'LOCAL_ADDR' ]) && !empty($_SERVER[ 'LOCAL_ADDR' ])) { |
| 265 |
$this->ipadr = $get_LOCAL_ADDR; |
| 266 |
#$this->ipadr = $_SERVER[ 'LOCAL_ADDR' ]; |
| 267 |
} |
| 268 |
|
| 269 |
$get_SERVER_NAME = $this->getserverinput('SERVER_NAME'); |
| 270 |
if (!empty($get_SERVER_NAME)) { |
| 271 |
$this->servername = $get_SERVER_NAME; |
| 272 |
$this->servernameout = " (".$get_SERVER_NAME.")"; |
| 273 |
} |
| 274 |
} |
| 275 |
|
| 276 |
public function add_footer($content) { |
| 277 |
$this->check_memory_usage(); |
| 278 |
$content .= ' | '. __( 'WP Memory Limit:', 'wp-memory-usage'). ' ' . esc_html($this->memory['usage']) . ' ' . __( 'of', 'wp-memory-usage') . ' ' . esc_html($this->memory["wpmb"]).esc_html($this->memory["wpunity"]). " (".esc_html($this->memory['percent'])."%)"; |
| 279 |
$content .= ' | '. __( 'PHP Memory Limit:', 'wp-memory-usage'). ' ' . esc_html($this->memory['usage']) . ' ' . __( 'of', 'wp-memory-usage') . ' ' . esc_html($this->memory['phplimit']).esc_html($this->memory['phplimitunity']). " (".esc_html($this->memory['percentphp'])."%)"; |
| 280 |
$content .= ' | '. __( 'IP-Address', 'wp-memory-usage') . " " . esc_html($this->servernameout). ': '.esc_html($this->ipadr); |
| 281 |
$content .= ' | '. __( 'PHP', 'wp-memory-usage') . ": " . esc_html(PHP_VERSION); |
| 282 |
return $content; |
| 283 |
} |
| 284 |
|
| 285 |
} |
| 286 |
|
| 287 |
// Start this plugin once all other plugins are fully loaded |
| 288 |
|
| 289 |
|
| 290 |
|
| 291 |
if ( file_exists( plugin_dir_path( __FILE__ ) . 'includes/threshold-alerts.php' ) ) { #load WPMU_Threshold_Alerts |
| 292 |
require_once plugin_dir_path( __FILE__ ) . 'includes/threshold-alerts.php'; |
| 293 |
if ( class_exists( 'WPMU_Threshold_Alerts' ) ) { |
| 294 |
add_action( 'plugins_loaded', function() { |
| 295 |
WPMU_Threshold_Alerts::init(25, 100, WPMU_LOG_PATH); |
| 296 |
}, 2 ); // Priority 2: nach wpmu_load_textdomain (Priority 1) |
| 297 |
} |
| 298 |
} |
| 299 |
|
| 300 |
if ( is_admin() ) { |
| 301 |
function WP_Memory_Usage_action_plugins_loaded( $array ) { |
| 302 |
return new wp_memory_usage(); |
| 303 |
}; |
| 304 |
add_action( 'plugins_loaded', 'WP_Memory_Usage_action_plugins_loaded', 10, 1 ); |
| 305 |
} |
| 306 |
|
| 307 |
// Add Settings link in Plugins list |
| 308 |
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), function( $links ) { # insert link in plugin list |
| 309 |
$settings_url = admin_url( 'options-general.php?page=wpmu-memory-alerts' ); |
| 310 |
$settings_link = '<a href="' . esc_url( $settings_url ) . '">' . esc_html__( 'Settings & Monitor', 'wp-memory-usage' ) . '</a>'; |
| 311 |
$links[] = $settings_link; |
| 312 |
return $links; |
| 313 |
} ); |