'ABJ_404_Solution_Functions', 'ABJ_404_Solution_FunctionsPreg' => 'ABJ_404_Solution_Functions', ]; // only pay attention if it's for us. don't bother for other things. if (substr($class, 0, 16) == 'ABJ_404_Solution') { global $abj404_autoLoaderClassMap; if (empty($abj404_autoLoaderClassMap)) { foreach (array('includes/php/objs', 'includes/php/wordpress', 'includes/php', 'includes/php', 'includes/ajax', 'includes') as $dir) { $globInput = ABJ404_PATH . $dir . DIRECTORY_SEPARATOR . '*.php'; $files = glob($globInput); foreach ($files as $file) { // /Users/user..../php/Study.php becomes ABJ_FC\Study $pathParts = pathinfo($file); $classNameWhenLoading = 'ABJ_404_Solution_' . $pathParts['filename']; $abj404_autoLoaderClassMap[$classNameWhenLoading] = $file; } } } if (array_key_exists($class, $abj404_autoLoaderClassMap)) { // Ensure the parent class is loaded first if (array_key_exists($class, $childParentMap)) { $parentClass = $childParentMap[$class]; if (!class_exists($parentClass)) { require_once $abj404_autoLoaderClassMap[$parentClass]; } } require_once $abj404_autoLoaderClassMap[$class]; } } } spl_autoload_register('abj404_autoloader'); add_action('doing_it_wrong_run', function($function_name, $message, $version) { if (strpos($message, '404-solution') !== false && $function_name == '_load_textdomain_just_in_time') { try { $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); // Prepare the plugin path from ABJ404_FILE $pluginPath = trailingslashit(plugin_dir_path(ABJ404_FILE)); // e.g., /var/www/html/wp-content/plugins/404-solution/ $logMessage = ''; $isOurPlugin = false; foreach ($backtrace as $index => $frame) { $file = isset($frame['file']) ? $frame['file'] : '[internal function]'; $line = isset($frame['line']) ? $frame['line'] : ''; $func = isset($frame['function']) ? $frame['function'] : '[unknown function]'; if (!$isOurPlugin && is_string($file) && strpos($file, $pluginPath) !== false) { $isOurPlugin = true; } $logMessage .= "#$index $func at [$file:$line]\n"; } if ($isOurPlugin) { $header = "=== Detected Early Translation ===\n" . "Function: $function_name\n" . "Message: $message\n" . "Version: $version\n"; if (!isset($GLOBALS['abj404_pending_errors'])) { $GLOBALS['abj404_pending_errors'] = []; } $GLOBALS['abj404_pending_errors'][] = $header . $logMessage; } } catch (Throwable $e) { // error_log('Failed to log early translation stack trace: ' . $e->getMessage()); } } }, 10, 3); // shortcode add_shortcode(ABJ404_SHORTCODE_NAME, 'abj404_shortCodeListener'); function abj404_shortCodeListener($atts) { require_once(plugin_dir_path( __FILE__ ) . "includes/Loader.php"); return ABJ_404_Solution_ShortCode::shortcodePageSuggestions($atts); } // admin if (is_admin()) { require_once(plugin_dir_path( __FILE__ ) . "includes/Loader.php"); ABJ_404_Solution_WordPress_Connector::init(); ABJ_404_Solution_ViewUpdater::init(); } // ---- // get the plugin priority to use before adding the template_redirect action. $__abj404_options = get_option('abj404_settings'); $__abj404_template_redirect_priority = absint($__abj404_options['template_redirect_priority'] ?? 9); add_action('template_redirect', 'abj404_404listener', $__abj404_template_redirect_priority); unset($__abj404_options); unset($__abj404_template_redirect_priority); // --- // 404 function abj404_404listener() { // always ignore admin screens and login requests. $isLoginScreen = (false !== stripos(wp_login_url(), $_SERVER['SCRIPT_NAME'])); $isCurrentlyViewingAnAdminPage = is_admin(); if ($isCurrentlyViewingAnAdminPage || $isLoginScreen) { return; } if (!is_404()) { require_once(plugin_dir_path( __FILE__ ) . "includes/Loader.php"); // if we should redirect all requests then don't return. $options = get_option('abj404_settings'); $arrayKeyExists = is_array($options) && array_key_exists('redirect_all_requests', $options); if ($arrayKeyExists && $options['redirect_all_requests'] == 1) { require_once(plugin_dir_path( __FILE__ ) . "includes/Loader.php"); $connector = ABJ_404_Solution_WordPress_Connector::getInstance(); $connector->processRedirectAllRequests(); return; } /** If we're currently redirecting to a custom 404 page and we are about to show page * suggestions then update the URL displayed to the user. */ $cookieName = ABJ404_PP . '_REQUEST_URI'; $cookieName .= '_UPDATE_URL'; $queryParamName = ABJ404_PP . '_ref'; // Check cookie first, then query param fallback (for 301 redirects where cookies don't survive) $originalURL = null; if (isset($_COOKIE[$cookieName]) && !empty($_COOKIE[$cookieName])) { $originalURL = $_COOKIE[$cookieName]; } elseif (isset($_GET[$queryParamName]) && !empty($_GET[$queryParamName])) { $originalURL = urldecode($_GET[$queryParamName]); } if ($originalURL !== null) { $cookieName404 = ABJ404_PP . '_STATUS_404'; if (array_key_exists($cookieName404, $_COOKIE) && $_COOKIE[$cookieName404] == 'true') { // clear the cookie setcookie($cookieName404, 'false', time() - 5, "/"); // we're going to a custom 404 page so se the status to 404. status_header(404); } if (array_key_exists('update_suggest_url', $options) && isset($options['update_suggest_url']) && $options['update_suggest_url'] == 1) { // clear the cookie - sanitize before writing to $_REQUEST $_REQUEST[$cookieName] = sanitize_text_field($originalURL); setcookie($cookieName, '', time() - 5, "/"); require_once(plugin_dir_path( __FILE__ ) . "includes/Loader.php"); add_action('wp_head', 'ABJ_404_Solution_ShortCode::updateURLbarIfNecessary'); } } } if (!is_404() || is_admin()) { return; } require_once(plugin_dir_path( __FILE__ ) . "includes/Loader.php"); $connector = ABJ_404_Solution_WordPress_Connector::getInstance(); return $connector->process404(); } function abj404_dailyMaintenanceCronJobListener() { require_once(plugin_dir_path( __FILE__ ) . "includes/Loader.php"); $abj404dao = ABJ_404_Solution_DataAccess::getInstance(); $abj404dao->deleteOldRedirectsCron(); $dbUpgrades = ABJ_404_Solution_DatabaseUpgradesEtc::getInstance(); $dbUpgrades->runDatabaseMaintenanceTasks(); } function abj404_updateLogsHitsTableListener() { require_once(plugin_dir_path( __FILE__ ) . "includes/Loader.php"); $abj404dao = ABJ_404_Solution_DataAccess::getInstance(); $abj404dao->createRedirectsForViewHitsTable(); } function abj404_updatePermalinkCacheListener($maxExecutionTime, $executionCount = 1) { require_once(plugin_dir_path( __FILE__ ) . "includes/Loader.php"); $permalinkCache = ABJ_404_Solution_PermalinkCache::getInstance(); $permalinkCache->updatePermalinkCache($maxExecutionTime, $executionCount); } function abj404_rebuildNGramCacheListener($offset = 0) { require_once(plugin_dir_path( __FILE__ ) . "includes/Loader.php"); $dbUpgrades = ABJ_404_Solution_DatabaseUpgradesEtc::getInstance(); $dbUpgrades->rebuildNGramCacheAsync($offset); } function abj404_networkActivationListener() { require_once(plugin_dir_path( __FILE__ ) . "includes/Loader.php"); ABJ_404_Solution_PluginLogic::networkActivationCronHandler(); } function abj404_networkActivationBackgroundListener() { require_once(plugin_dir_path( __FILE__ ) . "includes/Loader.php"); $upgradesEtc = ABJ_404_Solution_DatabaseUpgradesEtc::getInstance(); $upgradesEtc->processMultisiteActivationBatch(); } add_action('abj404_cleanupCronAction', 'abj404_dailyMaintenanceCronJobListener'); add_action('abj404_updateLogsHitsTableAction', 'abj404_updateLogsHitsTableListener'); add_action('abj404_updatePermalinkCacheAction', 'abj404_updatePermalinkCacheListener', 10, 2); add_action('abj404_rebuild_ngram_cache_hook', 'abj404_rebuildNGramCacheListener', 10, 1); add_action('abj404_network_activation_hook', 'abj404_networkActivationListener'); add_action('abj404_network_activation_background', 'abj404_networkActivationBackgroundListener'); function abj404_getUploadsDir() { // figure out the temp directory location. $uploadsDirArray = wp_upload_dir(null, false); $uploadsDir = $uploadsDirArray['basedir']; $uploadsDir .= DIRECTORY_SEPARATOR . 'temp_' . ABJ404_PP . DIRECTORY_SEPARATOR; return $uploadsDir; } /** * Override the locale for this plugin if user has configured a language override. * This allows users to use a different language for the 404 Solution plugin * than their WordPress site language or user language preference. * * @param string $locale The current locale. * @param string $domain The text domain. * @return string The locale to use for translation loading. */ function abj404_override_plugin_locale($locale, $domain) { // Only override for our plugin's text domain if ($domain === '404-solution') { $options = get_option('abj404_settings'); // Check if language override is set and not empty if (is_array($options) && !empty($options['plugin_language_override'])) { return $options['plugin_language_override']; } } return $locale; } add_filter('plugin_locale', 'abj404_override_plugin_locale', 999, 2); /** This only runs after WordPress is done enqueuing scripts. */ function abj404_loadSomethingWhenWordPressIsReady() { /** Load the text domain for translation of the plugin. */ $options = get_option('abj404_settings'); $override_locale = (is_array($options) && !empty($options['plugin_language_override'])) ? $options['plugin_language_override'] : ''; if (!empty($override_locale)) { // Directly load the specific .mo file for the override locale $mo_file = ABJ404_PATH . 'languages/404-solution-' . $override_locale . '.mo'; if (file_exists($mo_file)) { load_textdomain('404-solution', $mo_file); } } else { // Use normal WordPress translation loading $lang_dir = dirname(plugin_basename(ABJ404_FILE)) . '/languages'; load_plugin_textdomain('404-solution', false, $lang_dir); } // make debugging easier on localhost etc $serverName = array_key_exists('SERVER_NAME', $_SERVER) ? $_SERVER['SERVER_NAME'] : (array_key_exists('HTTP_HOST', $_SERVER) ? $_SERVER['HTTP_HOST'] : '(not found)'); $serverNameIsInTheWhiteList = in_array($serverName, $GLOBALS['abj404_whitelist']); if ($serverNameIsInTheWhiteList && function_exists('wp_get_current_user')) { require_once(plugin_dir_path( __FILE__ ) . "includes/Loader.php"); $abj404logic = ABJ_404_Solution_PluginLogic::getInstance(); if ($abj404logic->userIsPluginAdmin()) { $GLOBALS['abj404_display_errors'] = true; } } $action = isset($_GET['action']) ? sanitize_text_field($_GET['action']) : (isset($_POST['action']) ? sanitize_text_field($_POST['action']) : null); if ($action === 'exportRedirects') { require_once(plugin_dir_path( __FILE__ ) . "includes/Loader.php"); $abj404logic = ABJ_404_Solution_PluginLogic::getInstance(); $abj404logic->handleActionExport(); } } add_action('init', 'abj404_loadSomethingWhenWordPressIsReady');