| 1 |
<?php |
| 2 |
/** |
| 3 |
* OPcache Reset Admin functionality. |
| 4 |
* |
| 5 |
* Handles admin notices and file invalidation in the plugin/theme editors. |
| 6 |
* |
| 7 |
* @package opcache-reset |
| 8 |
*/ |
| 9 |
|
| 10 |
// Prevent direct access. |
| 11 |
if ( ! defined( 'ABSPATH' ) ) { |
| 12 |
exit; |
| 13 |
} |
| 14 |
|
| 15 |
/** |
| 16 |
* Get the Linux distribution name. |
| 17 |
* |
| 18 |
* @return string|null The distribution name or null if not found. |
| 19 |
*/ |
| 20 |
function gps_opcache_get_linux_distro() { |
| 21 |
// Declare Linux distros (extensible list). |
| 22 |
$distros = array( |
| 23 |
'Arch' => 'arch-release', |
| 24 |
'Debian' => 'debian_version', |
| 25 |
'Fedora' => 'fedora-release', |
| 26 |
'Ubuntu' => 'lsb-release', |
| 27 |
'Redhat' => 'redhat-release', |
| 28 |
'CentOS' => 'centos-release', |
| 29 |
); |
| 30 |
|
| 31 |
// Get everything from /etc directory. |
| 32 |
$etc_list = scandir( '/etc' ); |
| 33 |
|
| 34 |
// Loop through /etc results. |
| 35 |
$os_distro = null; |
| 36 |
foreach ( $etc_list as $entry ) { |
| 37 |
// Loop through list of distros. |
| 38 |
foreach ( $distros as $distro_release_file ) { |
| 39 |
// Match was found. |
| 40 |
if ( $distro_release_file === $entry ) { |
| 41 |
// Find distros array key (i.e. Distro name) by value (i.e. distro release file). |
| 42 |
$os_distro = array_search( $distro_release_file, $distros, true ); |
| 43 |
break 2; // Break inner and outer loop. |
| 44 |
} |
| 45 |
} |
| 46 |
} |
| 47 |
|
| 48 |
return $os_distro; |
| 49 |
} |
| 50 |
|
| 51 |
/** |
| 52 |
* Display success notice for OPcache invalidation. |
| 53 |
*/ |
| 54 |
function gps_opcache_edit_success() { |
| 55 |
?> |
| 56 |
<style>.updated.notice { display: none; }</style> |
| 57 |
<div class="notice notice-success is-dismissible"> |
| 58 |
<p><?php esc_html_e( 'File edited successfully and invalidated in bytecode cache.', 'opcache-reset' ); ?></p> |
| 59 |
</div> |
| 60 |
<?php |
| 61 |
} |
| 62 |
|
| 63 |
/** |
| 64 |
* Display warning notice when OPcache had nothing to invalidate. |
| 65 |
*/ |
| 66 |
function gps_opcache_edit_warning() { |
| 67 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verified in calling function. |
| 68 |
$file = isset( $_REQUEST['file'] ) ? sanitize_file_name( wp_unslash( $_REQUEST['file'] ) ) : ''; |
| 69 |
?> |
| 70 |
<div class="notice notice-warning is-dismissible"> |
| 71 |
<p> |
| 72 |
<?php |
| 73 |
printf( |
| 74 |
/* translators: %s: file path */ |
| 75 |
esc_html__( 'OPcache had nothing to invalidate for %s.', 'opcache-reset' ), |
| 76 |
esc_html( WP_PLUGIN_DIR . '/' . $file ) |
| 77 |
); |
| 78 |
?> |
| 79 |
</p> |
| 80 |
</div> |
| 81 |
<?php |
| 82 |
} |
| 83 |
|
| 84 |
/** |
| 85 |
* Hook into plugin editor to invalidate OPcache for edited files. |
| 86 |
*/ |
| 87 |
function gps_opcache_plugin_editor() { |
| 88 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This runs after WordPress core has already verified the nonce. |
| 89 |
if ( isset( $_GET['a'] ) && isset( $_REQUEST['file'] ) ) { |
| 90 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 91 |
$file = sanitize_file_name( wp_unslash( $_REQUEST['file'] ) ); |
| 92 |
// File was edited successfully and we know the filename. |
| 93 |
if ( opcache_invalidate( WP_PLUGIN_DIR . '/' . $file ) ) { |
| 94 |
add_action( 'admin_notices', 'gps_opcache_edit_success', 999 ); |
| 95 |
} else { |
| 96 |
add_action( 'admin_notices', 'gps_opcache_edit_warning', 999 ); |
| 97 |
} |
| 98 |
} |
| 99 |
} |
| 100 |
add_action( 'load-plugin-editor.php', 'gps_opcache_plugin_editor' ); |
| 101 |
|
| 102 |
/** |
| 103 |
* Handle OPcache invalidation on admin init for file edits. |
| 104 |
*/ |
| 105 |
function gps_opcache_admin_init() { |
| 106 |
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated |
| 107 |
if ( isset( $_SERVER['REQUEST_METHOD'] ) && 'POST' === $_SERVER['REQUEST_METHOD'] && ( current_user_can( 'edit_themes' ) || current_user_can( 'edit_plugins' ) ) ) { |
| 108 |
// phpcs:disable WordPress.Security.NonceVerification.Recommended -- This runs after WordPress core has already verified the nonce for file editing. |
| 109 |
if ( isset( $_REQUEST['file'] ) ) { |
| 110 |
$file = sanitize_text_field( wp_unslash( $_REQUEST['file'] ) ); |
| 111 |
opcache_invalidate( $file ); |
| 112 |
} elseif ( isset( $_REQUEST['action'] ) && isset( $_REQUEST['filename'] ) ) { |
| 113 |
$filename = sanitize_text_field( wp_unslash( $_REQUEST['filename'] ) ); |
| 114 |
// phpcs:enable WordPress.Security.NonceVerification.Recommended |
| 115 |
opcache_invalidate( $filename ); |
| 116 |
} |
| 117 |
} |
| 118 |
} |
| 119 |
add_action( 'init', 'gps_opcache_admin_init', 1 ); |
| 120 |
|