PluginProbe
404 Solution / trunk
404 Solution vtrunk
4.3.5 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 4.2.0 4.1.19 4.1.18 4.1.17 4.1.16 4.1.15 4.1.13 4.1.12 4.1.11 4.1.10 4.1.9 4.1.8 4.1.7 4.1.6 4.1.5 4.1.4 4.1.3 trunk 2.30.0 All 109 releases
404-solution / includes / root-boot / AdminInitHandlers.php

AdminInitHandlers.php in 404 Solution trunk, at includes/root-boot/AdminInitHandlers.php

160 lines 6.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH')) {
3 exit;
4 }
5
6 /**
7 * admin_init readiness handlers and the lazy textdomain loader.
8 *
9 * abj404_load_textdomain_if_needed() loads plugin translations once, lazily,
10 * honoring the optional locale override. abj404_maybe_refresh_runtime_integrity_cache()
11 * refreshes the missing-files cache at most once per TTL window.
12 * abj404_loadSomethingWhenWordPressIsReady() is the admin_init callback that runs
13 * after WordPress finishes enqueuing: it loads translations, enables localhost
14 * debug output, refreshes the integrity cache, and handles the export action.
15 *
16 * The add_action('admin_init', ...) registration stays in 404-solution.php;
17 * this file only defines the callbacks. The lazy Loader.php requires use
18 * ABJ404_FILE so they resolve to the plugin root.
19 */
20 // allow-no-test-found: boot-time admin_init global callbacks wired via add_action in 404-solution.php; no same-named unit file. abj404_loadSomethingWhenWordPressIsReady is exercised in integration boot coverage.
21
22 if (!function_exists('abj404_load_textdomain_if_needed')) {
23 /**
24 * Load plugin translations once, lazily.
25 *
26 * @return void
27 */
28 function abj404_load_textdomain_if_needed() {
29 static $loaded = false;
30 if ($loaded) {
31 return;
32 }
33
34 $override_locale = '';
35 if (isset($GLOBALS['abj404_plugin_language_override']) && is_scalar($GLOBALS['abj404_plugin_language_override'])
36 && (string)$GLOBALS['abj404_plugin_language_override'] !== '') {
37 $override_locale = (string)$GLOBALS['abj404_plugin_language_override'];
38 } else {
39 $options = abj404_get_settings_options();
40 if (isset($options['plugin_language_override']) && is_scalar($options['plugin_language_override'])) {
41 $override_locale = (string)$options['plugin_language_override'];
42 }
43 }
44
45 if ($override_locale !== '') {
46 $mo_file = ABJ404_PATH . 'languages/404-solution-' . $override_locale . '.mo';
47 if (file_exists($mo_file)) {
48 load_textdomain('404-solution', $mo_file);
49 }
50 } else {
51 $lang_dir = dirname(plugin_basename(ABJ404_FILE)) . '/languages';
52 load_plugin_textdomain('404-solution', false, $lang_dir);
53 }
54
55 $loaded = true;
56 }
57 }
58
59 if (!function_exists('abj404_maybe_refresh_runtime_integrity_cache')) {
60 /**
61 * Refresh runtime integrity cache at most once per TTL window.
62 *
63 * @param int $ttlSeconds
64 * @return void
65 */
66 function abj404_maybe_refresh_runtime_integrity_cache($ttlSeconds = 43200) {
67 if (!is_admin()) {
68 return;
69 }
70
71 $checkedRecently = get_transient('abj404_runtime_integrity_checked');
72 if ($checkedRecently) {
73 return;
74 }
75
76 $missingRuntimeFiles = abj404_verify_runtime_integrity();
77 if (count($missingRuntimeFiles) > 0) {
78 set_transient('abj404_runtime_missing_files', $missingRuntimeFiles, $ttlSeconds);
79 } else {
80 delete_transient('abj404_runtime_missing_files');
81 }
82
83 set_transient('abj404_runtime_integrity_checked', 1, $ttlSeconds);
84 }
85 }
86
87 /** This only runs after WordPress is done enqueuing scripts. */
88 if (!function_exists('abj404_loadSomethingWhenWordPressIsReady')) {
89 /** @return void */
90 function abj404_loadSomethingWhenWordPressIsReady() {
91 // If boot failed (missing files), skip all init that depends on plugin classes.
92 if (!$GLOBALS['abj404_boot_ok']) {
93 return;
94 }
95
96 $isAdminRequest = is_admin();
97 if ($isAdminRequest) {
98 abj404_load_textdomain_if_needed();
99 }
100
101 // make debugging easier on localhost etc
102 if ($isAdminRequest) {
103 $serverNameRaw = array_key_exists('SERVER_NAME', $_SERVER) ? $_SERVER['SERVER_NAME'] : (array_key_exists('HTTP_HOST', $_SERVER) ? $_SERVER['HTTP_HOST'] : '(not found)');
104 $serverName = is_scalar($serverNameRaw) ? (string)$serverNameRaw : '(not found)';
105 $whitelist = isset($GLOBALS['abj404_whitelist']) && is_array($GLOBALS['abj404_whitelist']) ? $GLOBALS['abj404_whitelist'] : array();
106 $serverNameIsInTheWhiteList = in_array($serverName, $whitelist);
107
108 // Keep localhost debug helper on admin screens only; frontend requests stay lean.
109 if ($serverNameIsInTheWhiteList && function_exists('wp_get_current_user')) {
110 require_once(plugin_dir_path( ABJ404_FILE ) . "includes/Loader.php");
111 if (abj_service('admin_access_policy')->isPluginAdmin()) {
112 $GLOBALS['abj404_display_errors'] = true;
113 }
114 }
115 }
116
117 $action = null;
118 if ($isAdminRequest) {
119 $actionGet = ABJ_404_Solution_RequestInputNormalizer::readText($_GET, array('name' => 'action'));
120 $actionPost = ABJ_404_Solution_RequestInputNormalizer::readText($_POST, array('name' => 'action'));
121 if ($actionGet !== '') {
122 $action = $actionGet;
123 } else if ($actionPost !== '') {
124 $action = $actionPost;
125 } else {
126 $action = null;
127 }
128 }
129 if ($isAdminRequest && abj404_is_local_debug_host() && abj404_current_user_is_plugin_admin() && isset($_GET['abj404_set_sim_db_ms'])) {
130 $nonce = isset($_GET['_wpnonce']) && is_string($_GET['_wpnonce']) ? $_GET['_wpnonce'] : '';
131 $nonceOk = $nonce !== '' ? wp_verify_nonce($nonce, 'abj404_set_sim_db_ms') : false;
132 if ($nonceOk) {
133 $simMsRaw = $_GET['abj404_set_sim_db_ms'];
134 $newMs = max(0, min(5000, absint(is_scalar($simMsRaw) ? $simMsRaw : 0)));
135 update_option('abj404_simulated_db_latency_ms', $newMs, false);
136 }
137 }
138
139 // An admin-only link on the front-end suggestions page can ask to open a
140 // field that only exists in Advanced Mode. Honour it before the page
141 // renders, so the field is there when the browser jumps to the anchor.
142 // The literal must stay in step with SettingsModeDeepLink::QUERY_ARG; it is
143 // spelled out here so the guard costs nothing on requests that do not
144 // carry it (the class is not loaded until it is).
145 if ($isAdminRequest && isset($_GET['abj404_show_advanced'])) {
146 require_once(plugin_dir_path( ABJ404_FILE ) . "includes/Loader.php");
147 ABJ_404_Solution_SettingsModeDeepLink::applyIfRequested();
148 }
149
150 $ttl = defined('HOUR_IN_SECONDS') ? (12 * HOUR_IN_SECONDS) : 43200;
151 abj404_maybe_refresh_runtime_integrity_cache($ttl);
152
153 if ($isAdminRequest && $action === 'exportRedirects' && abj404_current_user_is_plugin_admin()) {
154 require_once(plugin_dir_path( ABJ404_FILE ) . "includes/Loader.php");
155 $abj404logic = ABJ_404_Solution_PluginLogic::getInstance();
156 $abj404logic->adminActions()->handleActionExport();
157 }
158 }
159 }
160