PluginProbe
Redirection / 5.9.0
Redirection v5.9.0
5.10.0 5.9.0 5.8.1 5.8.0 3.7.2 3.7.3 4.0 4.0.1 4.1 4.1.1 4.2 4.2.1 4.2.2 4.2.3 4.3 4.3.1 4.3.2 4.3.3 4.4 4.4.1 4.4.2 4.5 4.5.1 4.6.2 4.7.1 All 130 releases
redirection / redirection.php

redirection.php in Redirection 5.9.0, at redirection.php

216 lines 6.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Redirection
4 Plugin URI: https://redirection.me/
5 Description: Manage all your 301 redirects and monitor 404 errors
6 Version: 5.9.0
7 Author: John Godley
8 Text Domain: redirection
9 Requires PHP: 7.4
10 Requires at least: 6.6
11 ============================================================================================================
12 For full license details see license.txt
13 ============================================================================================================
14 */
15
16 define( 'REDIRECTION_DB_VERSION', '4.2' ); // DB schema version. Only change if DB needs changing
17 define( 'REDIRECTION_FILE', __FILE__ );
18
19 if ( ! defined( 'REDIRECTION_FLYING_SOLO' ) ) {
20 define( 'REDIRECTION_FLYING_SOLO', apply_filters( 'redirection_flying_solo', true ) );
21 }
22
23 // This file must support PHP < 7.4 so as not to crash
24 if ( version_compare( PHP_VERSION, '7.4' ) < 0 ) {
25 add_filter( 'plugin_action_links_' . basename( dirname( REDIRECTION_FILE ) ) . '/' . basename( REDIRECTION_FILE ), 'red_deprecated_php' );
26
27 /**
28 * @param array<string> $links
29 * @return array<string>
30 */
31 function red_deprecated_php( array $links ): array {
32 /* translators: 1: server PHP version. 2: required PHP version. */
33 array_unshift( $links, '<a href="https://redirection.me/support/problems/php-version/" style="color: red; text-decoration: underline">' . sprintf( __( 'Disabled! Detected PHP %1$s, need PHP %2$s+', 'redirection' ), phpversion(), '7.4' ) . '</a>' );
34 return $links;
35 }
36
37 return;
38 }
39
40 // Temporary compatibility for sites serving stale cached code during upgrades.
41 // Remove once the 5.8.x transition window has passed.
42 if ( file_exists( __DIR__ . '/build/redirection-version.php' ) ) {
43 require_once __DIR__ . '/build/redirection-version.php';
44 } else {
45 require_once __DIR__ . '/redirection-version.php';
46 }
47
48 require_once __DIR__ . '/redirection-settings.php';
49 require_once __DIR__ . '/models/options.php';
50 require_once __DIR__ . '/models/redirect/redirect.php';
51 require_once __DIR__ . '/models/url/url.php';
52 require_once __DIR__ . '/models/regex.php';
53 require_once __DIR__ . '/models/module.php';
54 require_once __DIR__ . '/models/log/log.php';
55 require_once __DIR__ . '/models/flusher.php';
56 require_once __DIR__ . '/models/match.php';
57 require_once __DIR__ . '/models/action.php';
58 require_once __DIR__ . '/models/request.php';
59 require_once __DIR__ . '/models/header.php';
60 require_once __DIR__ . '/models/group.php';
61
62 /**
63 * Autoload the migrated import/export classes only.
64 *
65 * This lets us adopt autoloading incrementally for admin/CLI-only paths
66 * without changing the rest of the plugin bootstrap in one step.
67 *
68 * @param string $requested_class Requested class name.
69 * @return void
70 */
71 function redirection_autoload_import_export( $requested_class ) {
72 redirection_autoload_namespace( $requested_class, 'Redirection\\ImportExport\\', __DIR__ . '/includes/import-export/' );
73 }
74
75 /**
76 * Autoload a namespaced class from a plugin directory.
77 *
78 * @param string $requested_class Requested class name.
79 * @param string $prefix Namespace prefix.
80 * @param string $base_dir Base directory.
81 * @return void
82 */
83 function redirection_autoload_namespace( $requested_class, $prefix, $base_dir ) {
84 if ( strncmp( $prefix, $requested_class, strlen( $prefix ) ) !== 0 ) {
85 return;
86 }
87
88 $relative_class = substr( $requested_class, strlen( $prefix ) );
89 if ( $relative_class === '' ) {
90 return;
91 }
92
93 $normalize = static function ( $value ) {
94 $value = preg_replace( '/(?<!^)[A-Z]/', '-$0', $value );
95
96 if ( ! is_string( $value ) ) {
97 return '';
98 }
99
100 return str_replace( '_', '-', strtolower( $value ) );
101 };
102
103 $segments = explode( '\\', $relative_class );
104 $class_name = array_pop( $segments );
105 if ( ! is_string( $class_name ) || $class_name === '' ) {
106 return;
107 }
108
109 if ( count( $segments ) > 0 ) {
110 $base_dir .= implode( '/', array_map( $normalize, $segments ) ) . '/';
111 }
112
113 $path = $base_dir . 'class-' . $normalize( $class_name ) . '.php';
114
115 if ( file_exists( $path ) ) {
116 require_once $path;
117 }
118 }
119
120 spl_autoload_register( 'redirection_autoload_import_export' );
121
122 /**
123 * Clear PHP opcache when plugin is updated. This is to help with mid-update errors.
124 *
125 * @param object $upgrader The upgrader object.
126 * @param array{action: string, type: string, plugins?: string[]} $options The upgrade options.
127 * @return void
128 */
129 function redirection_clear_opcache_on_upgrade( $upgrader, $options ) {
130 if ( $options['action'] !== 'update' || $options['type'] !== 'plugin' ) {
131 return;
132 }
133
134 $plugin_basename = plugin_basename( REDIRECTION_FILE );
135 $plugins = $options['plugins'] ?? [];
136
137 if ( ! in_array( $plugin_basename, $plugins, true ) ) {
138 return;
139 }
140
141 if ( function_exists( 'opcache_reset' ) ) {
142 // Suppress warnings if opcache_reset is restricted by server configuration
143 @opcache_reset(); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
144 }
145 }
146
147 add_action( 'upgrader_process_complete', 'redirection_clear_opcache_on_upgrade', 10, 2 );
148
149 /**
150 * @return bool
151 */
152 function red_is_wpcli() {
153 if ( defined( 'WP_CLI' ) && WP_CLI ) {
154 return true;
155 }
156
157 return false;
158 }
159
160 /**
161 * Detect a plain PHP CLI context (e.g., a cron script that loads wp-load.php
162 * directly). Distinct from red_is_wpcli(), which is only true under WP-CLI.
163 * Used to skip front-end redirect enforcement that would otherwise call die()
164 * and silently terminate the CLI process.
165 *
166 * @return bool
167 */
168 function red_is_cli() {
169 return PHP_SAPI === 'cli';
170 }
171
172 /**
173 * @return bool
174 */
175 function red_is_admin() {
176 if ( is_admin() ) {
177 return true;
178 }
179
180 return false;
181 }
182
183 /**
184 * @return void
185 */
186 function red_start_rest() {
187 require_once __DIR__ . '/redirection-admin.php';
188 require_once __DIR__ . '/api/api.php';
189
190 Redirection_Api::init();
191 Redirection_Admin::init();
192
193 remove_action( 'rest_api_init', 'red_start_rest' );
194 }
195
196 /**
197 * @return void
198 */
199 function redirection_locale() {
200 load_plugin_textdomain( 'redirection', false, dirname( plugin_basename( REDIRECTION_FILE ) ) . '/locale/' );
201 }
202
203 if ( red_is_admin() || red_is_wpcli() ) {
204 require_once __DIR__ . '/redirection-admin.php';
205 require_once __DIR__ . '/api/api.php';
206 } else {
207 require_once __DIR__ . '/redirection-front.php';
208 }
209
210 if ( red_is_wpcli() ) {
211 require_once __DIR__ . '/redirection-cli.php';
212 }
213
214 add_action( 'rest_api_init', 'red_start_rest' );
215 add_action( 'init', 'redirection_locale' );
216