Version Description
(Aug. 26, 2014) = * Check if the global $wp_query is null before using get_query_var. Props cmmarslender * Unit tests * Making _x translatable text work. Props lucspe
Download this release
Release Info
Developer | tlovett1 |
Plugin | Safe Redirect Manager |
Version | 1.7.3 |
Comparing to | |
See all releases |
Code changes from version 1.7.2 to 1.7.3
- .gitignore +1 -0
- .travis.yml +21 -0
- bin/install-wp-tests.sh +78 -0
- phpunit.xml +14 -0
- readme.txt +6 -1
- safe-redirect-manager.php +944 -924
- tests/bootstrap.php +18 -0
- tests/test-core.php +259 -0
.gitignore
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
.svn
|
.travis.yml
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
language: php
|
2 |
+
|
3 |
+
php:
|
4 |
+
- 5.2
|
5 |
+
- 5.3
|
6 |
+
- 5.4
|
7 |
+
|
8 |
+
env:
|
9 |
+
- WP_VERSION=latest WP_MULTISITE=0
|
10 |
+
- WP_VERSION=latest WP_MULTISITE=1
|
11 |
+
- WP_VERSION=3.8 WP_MULTISITE=0
|
12 |
+
- WP_VERSION=3.8 WP_MULTISITE=1
|
13 |
+
- WP_VERSION=3.7 WP_MULTISITE=0
|
14 |
+
- WP_VERSION=3.7 WP_MULTISITE=1
|
15 |
+
- WP_VERSION=3.6 WP_MULTISITE=0
|
16 |
+
- WP_VERSION=3.6 WP_MULTISITE=1
|
17 |
+
|
18 |
+
before_script:
|
19 |
+
- bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION
|
20 |
+
|
21 |
+
script: phpunit
|
bin/install-wp-tests.sh
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env bash
|
2 |
+
|
3 |
+
if [ $# -lt 3 ]; then
|
4 |
+
echo "usage: $0 <db-name> <db-user> <db-pass> [db-host] [wp-version]"
|
5 |
+
exit 1
|
6 |
+
fi
|
7 |
+
|
8 |
+
DB_NAME=$1
|
9 |
+
DB_USER=$2
|
10 |
+
DB_PASS=$3
|
11 |
+
DB_HOST=${4-localhost}
|
12 |
+
WP_VERSION=${5-latest}
|
13 |
+
|
14 |
+
WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib}
|
15 |
+
WP_CORE_DIR=/tmp/wordpress/
|
16 |
+
|
17 |
+
set -ex
|
18 |
+
|
19 |
+
install_wp() {
|
20 |
+
mkdir -p $WP_CORE_DIR
|
21 |
+
|
22 |
+
if [ $WP_VERSION == 'latest' ]; then
|
23 |
+
local ARCHIVE_NAME='latest'
|
24 |
+
else
|
25 |
+
local ARCHIVE_NAME="wordpress-$WP_VERSION"
|
26 |
+
fi
|
27 |
+
|
28 |
+
wget -nv -O /tmp/wordpress.tar.gz http://wordpress.org/${ARCHIVE_NAME}.tar.gz
|
29 |
+
tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR
|
30 |
+
|
31 |
+
wget -nv -O $WP_CORE_DIR/wp-content/db.php https://raw.github.com/markoheijnen/wp-mysqli/master/db.php
|
32 |
+
}
|
33 |
+
|
34 |
+
install_test_suite() {
|
35 |
+
# portable in-place argument for both GNU sed and Mac OSX sed
|
36 |
+
if [[ $(uname -s) == 'Darwin' ]]; then
|
37 |
+
local ioption='-i .bak'
|
38 |
+
else
|
39 |
+
local ioption='-i'
|
40 |
+
fi
|
41 |
+
|
42 |
+
# set up testing suite
|
43 |
+
mkdir -p $WP_TESTS_DIR
|
44 |
+
cd $WP_TESTS_DIR
|
45 |
+
svn co --quiet http://develop.svn.wordpress.org/trunk/tests/phpunit/includes/
|
46 |
+
|
47 |
+
wget -nv -O wp-tests-config.php http://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php
|
48 |
+
sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" wp-tests-config.php
|
49 |
+
sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" wp-tests-config.php
|
50 |
+
sed $ioption "s/yourusernamehere/$DB_USER/" wp-tests-config.php
|
51 |
+
sed $ioption "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php
|
52 |
+
sed $ioption "s|localhost|${DB_HOST}|" wp-tests-config.php
|
53 |
+
}
|
54 |
+
|
55 |
+
install_db() {
|
56 |
+
# parse DB_HOST for port or socket references
|
57 |
+
local PARTS=(${DB_HOST//\:/ })
|
58 |
+
local DB_HOSTNAME=${PARTS[0]};
|
59 |
+
local DB_SOCK_OR_PORT=${PARTS[1]};
|
60 |
+
local EXTRA=""
|
61 |
+
|
62 |
+
if ! [ -z $DB_HOSTNAME ] ; then
|
63 |
+
if [[ "$DB_SOCK_OR_PORT" =~ ^[0-9]+$ ]] ; then
|
64 |
+
EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp"
|
65 |
+
elif ! [ -z $DB_SOCK_OR_PORT ] ; then
|
66 |
+
EXTRA=" --socket=$DB_SOCK_OR_PORT"
|
67 |
+
elif ! [ -z $DB_HOSTNAME ] ; then
|
68 |
+
EXTRA=" --host=$DB_HOSTNAME --protocol=tcp"
|
69 |
+
fi
|
70 |
+
fi
|
71 |
+
|
72 |
+
# create database
|
73 |
+
mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA
|
74 |
+
}
|
75 |
+
|
76 |
+
install_wp
|
77 |
+
install_test_suite
|
78 |
+
install_db
|
phpunit.xml
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<phpunit
|
2 |
+
bootstrap="tests/bootstrap.php"
|
3 |
+
backupGlobals="false"
|
4 |
+
colors="true"
|
5 |
+
convertErrorsToExceptions="true"
|
6 |
+
convertNoticesToExceptions="true"
|
7 |
+
convertWarningsToExceptions="true"
|
8 |
+
>
|
9 |
+
<testsuites>
|
10 |
+
<testsuite>
|
11 |
+
<directory prefix="test-" suffix=".php">./tests/</directory>
|
12 |
+
</testsuite>
|
13 |
+
</testsuites>
|
14 |
+
</phpunit>
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: tlovett1, tollmanz, taylorde, 10up, jakemgold, danielbachhuber, Ve
|
|
3 |
Tags: http redirects, redirect manager, url redirection, safe http redirection, multisite redirects
|
4 |
Requires at least: 3.1
|
5 |
Tested up to: 3.8
|
6 |
-
Stable tag: 1.7.
|
7 |
|
8 |
Safely and easily manage your website's HTTP redirects.
|
9 |
|
@@ -24,6 +24,11 @@ Extract the zip file and just drop the contents in the wp-content/plugins/ direc
|
|
24 |
|
25 |
== Changelog ==
|
26 |
|
|
|
|
|
|
|
|
|
|
|
27 |
= 1.7.2 (Feb. 10, 2014) =
|
28 |
* Added French translation. Props [jcbrebion](https://github.com/jcbrebion).
|
29 |
* Bug fix: Don't perform redirects in the admin. Props [joshbetz](https://github.com/joshbetz).
|
3 |
Tags: http redirects, redirect manager, url redirection, safe http redirection, multisite redirects
|
4 |
Requires at least: 3.1
|
5 |
Tested up to: 3.8
|
6 |
+
Stable tag: 1.7.3
|
7 |
|
8 |
Safely and easily manage your website's HTTP redirects.
|
9 |
|
24 |
|
25 |
== Changelog ==
|
26 |
|
27 |
+
= 1.7.3 (Aug. 26, 2014) =
|
28 |
+
* Check if the global $wp_query is null before using get_query_var. Props [cmmarslender](https://github.com/cmmarslender)
|
29 |
+
* Unit tests
|
30 |
+
* Making _x translatable text work. Props [lucspe](https://github.com/lucspe)
|
31 |
+
|
32 |
= 1.7.2 (Feb. 10, 2014) =
|
33 |
* Added French translation. Props [jcbrebion](https://github.com/jcbrebion).
|
34 |
* Bug fix: Don't perform redirects in the admin. Props [joshbetz](https://github.com/joshbetz).
|
safe-redirect-manager.php
CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Safe Redirect Manager
|
|
4 |
Plugin URI: http://www.10up.com
|
5 |
Description: Easily and safely manage HTTP redirects.
|
6 |
Author: Taylor Lovett (10up LLC), VentureBeat
|
7 |
-
Version: 1.7.
|
8 |
Author URI: http://www.10up.com
|
9 |
|
10 |
GNU General Public License, Free Software Foundation <http://creativecommons.org/licenses/GPL/2.0/>
|
@@ -26,932 +26,952 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
26 |
*/
|
27 |
|
28 |
if ( defined( 'WP_CLI' ) && WP_CLI )
|
29 |
-
|
30 |
|
31 |
class SRM_Safe_Redirect_Manager {
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
-
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
954 |
}
|
955 |
|
956 |
global $safe_redirect_manager;
|
957 |
-
$safe_redirect_manager = new SRM_Safe_Redirect_Manager();
|
4 |
Plugin URI: http://www.10up.com
|
5 |
Description: Easily and safely manage HTTP redirects.
|
6 |
Author: Taylor Lovett (10up LLC), VentureBeat
|
7 |
+
Version: 1.7.3
|
8 |
Author URI: http://www.10up.com
|
9 |
|
10 |
GNU General Public License, Free Software Foundation <http://creativecommons.org/licenses/GPL/2.0/>
|
26 |
*/
|
27 |
|
28 |
if ( defined( 'WP_CLI' ) && WP_CLI )
|
29 |
+
require_once dirname( __FILE__ ) . '/inc/wp-cli.php';
|
30 |
|
31 |
class SRM_Safe_Redirect_Manager {
|
32 |
|
33 |
+
public $redirect_post_type = 'redirect_rule';
|
34 |
+
private $redirect_nonce_name = 'srm_redirect_nonce';
|
35 |
+
private $redirect_nonce_action = 'srm-save-redirect-meta';
|
36 |
+
|
37 |
+
public $meta_key_redirect_from = '_redirect_rule_from';
|
38 |
+
public $meta_key_redirect_to = '_redirect_rule_to';
|
39 |
+
public $meta_key_redirect_status_code = '_redirect_rule_status_code';
|
40 |
+
public $meta_key_enable_redirect_from_regex = '_redirect_rule_from_regex';
|
41 |
+
|
42 |
+
public $cache_key_redirects = '_srm_redirects';
|
43 |
+
|
44 |
+
public $valid_status_codes = array( 301, 302, 303, 307, 403, 404 );
|
45 |
+
|
46 |
+
public $status_code_labels = array(
|
47 |
+
301 => 'Moved Permanently',
|
48 |
+
302 => 'Found',
|
49 |
+
303 => 'See Other',
|
50 |
+
307 => 'Temporary Redirect',
|
51 |
+
403 => 'Forbidden',
|
52 |
+
404 => 'Not Found',
|
53 |
+
);
|
54 |
+
|
55 |
+
private $whitelist_hosts = array();
|
56 |
+
|
57 |
+
public $default_max_redirects = 150;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Sets up redirect manager
|
61 |
+
*
|
62 |
+
* @since 1.0
|
63 |
+
* @uses add_action, add_filter
|
64 |
+
* @return object
|
65 |
+
*/
|
66 |
+
public function __construct() {
|
67 |
+
add_action( 'init', array( $this, 'action_init_load_textdomain' ), 9 );
|
68 |
+
add_action( 'init', array( $this, 'action_init' ) );
|
69 |
+
add_action( 'init', array( $this, 'action_register_post_types' ) );
|
70 |
+
add_action( 'parse_request', array( $this, 'action_parse_request' ), 0 );
|
71 |
+
add_action( 'save_post', array( $this, 'action_save_post' ) );
|
72 |
+
add_filter( 'manage_' . $this->redirect_post_type . '_posts_columns' , array( $this, 'filter_redirect_columns' ) );
|
73 |
+
add_action( 'manage_' . $this->redirect_post_type . '_posts_custom_column' , array( $this, 'action_custom_redirect_columns' ), 10, 2 );
|
74 |
+
add_action( 'transition_post_status', array( $this, 'action_transition_post_status' ), 10, 3 );
|
75 |
+
add_filter( 'post_updated_messages', array( $this, 'filter_redirect_updated_messages' ) );
|
76 |
+
add_action( 'admin_notices', array( $this, 'action_redirect_chain_alert' ) );
|
77 |
+
add_filter( 'the_title', array( $this, 'filter_admin_title' ), 100, 2 );
|
78 |
+
add_filter( 'bulk_actions-edit-' . $this->redirect_post_type, array( $this, 'filter_bulk_actions' ) );
|
79 |
+
add_action( 'admin_print_styles-edit.php', array( $this, 'action_print_logo_css' ), 10, 1 );
|
80 |
+
add_action( 'admin_print_styles-post.php', array( $this, 'action_print_logo_css' ), 10, 1 );
|
81 |
+
add_action( 'admin_print_styles-post-new.php', array( $this, 'action_print_logo_css' ), 10, 1 );
|
82 |
+
add_filter( 'post_type_link', array( $this, 'filter_post_type_link' ), 10, 2 );
|
83 |
+
|
84 |
+
// Search filters
|
85 |
+
add_filter( 'posts_join', array( $this, 'filter_search_join' ) );
|
86 |
+
add_filter( 'posts_where', array( $this, 'filter_search_where' ) );
|
87 |
+
add_filter( 'posts_distinct', array( $this, 'filter_search_distinct' ) );
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Localize plugin
|
92 |
+
*
|
93 |
+
* @since 1.7
|
94 |
+
* @uses load_plugin_textdomain
|
95 |
+
* @return void
|
96 |
+
*/
|
97 |
+
public function action_init_load_textdomain() {
|
98 |
+
load_plugin_textdomain( 'safe-redirect-manager', false, basename( dirname( __FILE__ ) ) . '/languages' );
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Join posts table with postmeta table on search
|
103 |
+
*
|
104 |
+
* @since 1.2
|
105 |
+
* @param string $join
|
106 |
+
* @uses get_query_var
|
107 |
+
* @return string
|
108 |
+
*/
|
109 |
+
public function filter_search_join( $join ) {
|
110 |
+
global $wp_query;
|
111 |
+
|
112 |
+
if ( empty( $wp_query ) || $this->redirect_post_type != get_query_var( 'post_type' ) )
|
113 |
+
return $join;
|
114 |
+
|
115 |
+
global $wpdb;
|
116 |
+
|
117 |
+
$s = get_query_var( 's' );
|
118 |
+
if ( ! empty( $s ) ) {
|
119 |
+
$join .= " LEFT JOIN $wpdb->postmeta AS m ON ($wpdb->posts.ID = m.post_id) ";
|
120 |
+
}
|
121 |
+
return $join;
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Return distinct search results
|
126 |
+
*
|
127 |
+
* @since 1.2
|
128 |
+
* @param string $distinct
|
129 |
+
* @uses get_query_var
|
130 |
+
* @return string
|
131 |
+
*/
|
132 |
+
public function filter_search_distinct( $distinct ) {
|
133 |
+
global $wp_query;
|
134 |
+
|
135 |
+
if ( empty( $wp_query ) || $this->redirect_post_type != get_query_var( 'post_type' ) )
|
136 |
+
return $distinct;
|
137 |
+
|
138 |
+
return 'DISTINCT';
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Join posts table with postmeta table on search
|
143 |
+
*
|
144 |
+
* @since 1.2
|
145 |
+
* @param string $where
|
146 |
+
* @uses is_search, get_query_var
|
147 |
+
* @return string
|
148 |
+
*/
|
149 |
+
public function filter_search_where( $where ) {
|
150 |
+
global $wp_query;
|
151 |
+
|
152 |
+
if ( empty( $wp_query ) || $this->redirect_post_type != get_query_var( 'post_type' ) || ! is_search() || empty( $where ) )
|
153 |
+
return $where;
|
154 |
+
|
155 |
+
$exact = get_query_var( 'exact' );
|
156 |
+
$n = ( ! empty( $exact ) ) ? '' : '%';
|
157 |
+
|
158 |
+
$search = '';
|
159 |
+
$seperator = '';
|
160 |
+
$terms = $this->get_search_terms();
|
161 |
+
$search .= '(';
|
162 |
+
|
163 |
+
// we check the meta values against each term in the search
|
164 |
+
foreach ( $terms as $term ) {
|
165 |
+
$search .= $seperator;
|
166 |
+
$search .= sprintf( "( ( m.meta_value LIKE '%s%s%s' AND m.meta_key = '%s') OR ( m.meta_value LIKE '%s%s%s' AND m.meta_key = '%s') )", $n, $term, $n, $this->meta_key_redirect_from, $n, $term, $n, $this->meta_key_redirect_to );
|
167 |
+
$seperator = ' OR ';
|
168 |
+
}
|
169 |
+
|
170 |
+
$search .= ')';
|
171 |
+
|
172 |
+
$where = preg_replace( '/\(\(\(.*?\)\)\)/is', '((' . $search . '))', $where );
|
173 |
+
|
174 |
+
return $where;
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Get an array of search terms
|
179 |
+
*
|
180 |
+
* @since 1.2
|
181 |
+
* @uses get_query_var
|
182 |
+
* @return array
|
183 |
+
*/
|
184 |
+
private function get_search_terms() {
|
185 |
+
$s = get_query_var( 's' );
|
186 |
+
|
187 |
+
if ( ! empty( $s ) ) {
|
188 |
+
preg_match_all( '/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', stripslashes( $s ), $matches );
|
189 |
+
$search_terms = array_map( create_function( '$a', 'return trim( $a, "\\"\'\\n\\r " );' ), $matches[0] );
|
190 |
+
}
|
191 |
+
return $search_terms;
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Swap tools logo for plugin logo
|
196 |
+
*
|
197 |
+
* @since 1.1
|
198 |
+
* @uses plugins_url
|
199 |
+
* @return void
|
200 |
+
*/
|
201 |
+
public function action_print_logo_css() {
|
202 |
+
if ( $this->is_plugin_page() ) {
|
203 |
+
?>
|
204 |
+
<style type="text/css">
|
205 |
+
#icon-tools {
|
206 |
+
background: url("<?php echo plugins_url( 'images/icon32x32.png', __FILE__ ); ?>") no-repeat top left !important;
|
207 |
+
margin-right: 0;
|
208 |
+
}
|
209 |
+
#visibility, .view-switch, .posts .inline-edit-col-left .inline-edit-group {
|
210 |
+
display: none;
|
211 |
+
}
|
212 |
+
#srm<?php echo $this->meta_key_redirect_from; ?> {
|
213 |
+
width: 60%;
|
214 |
+
}
|
215 |
+
</style>
|
216 |
+
<?php
|
217 |
+
}
|
218 |
+
}
|
219 |
+
|
220 |
+
/**
|
221 |
+
* Limit the bulk actions available in the Manage Redirects view
|
222 |
+
*
|
223 |
+
* @since 1.0
|
224 |
+
* @return array
|
225 |
+
*/
|
226 |
+
public function filter_bulk_actions( $actions ) {
|
227 |
+
|
228 |
+
// No bulk editing at this time
|
229 |
+
unset( $actions['edit'] );
|
230 |
+
|
231 |
+
return $actions;
|
232 |
+
}
|
233 |
+
|
234 |
+
/**
|
235 |
+
* Creates a redirect post, this function will be useful for import/exports scripts
|
236 |
+
*
|
237 |
+
* @param string $redirect_from
|
238 |
+
* @param string $redirect_to
|
239 |
+
* @param int $status_code
|
240 |
+
* @param bool $enable_regex
|
241 |
+
* @param string $post_status
|
242 |
+
* @since 1.3
|
243 |
+
* @uses wp_insert_post, update_post_meta
|
244 |
+
* @return int|WP_Error
|
245 |
+
*/
|
246 |
+
public function create_redirect( $redirect_from, $redirect_to, $status_code = 302, $enable_regex = false, $post_status = 'publish' ) {
|
247 |
+
global $wpdb;
|
248 |
+
|
249 |
+
$sanitized_redirect_from = $this->sanitize_redirect_from( $redirect_from );
|
250 |
+
$sanitized_redirect_to = $this->sanitize_redirect_to( $redirect_to );
|
251 |
+
$sanitized_status_code = absint( $status_code );
|
252 |
+
$sanitized_enable_regex = (bool)$enable_regex;
|
253 |
+
$sanitized_post_status = sanitize_key( $post_status );
|
254 |
+
|
255 |
+
// check and make sure no parameters are empty or invalid after sanitation
|
256 |
+
if ( empty( $sanitized_redirect_from ) || empty( $sanitized_redirect_to ) )
|
257 |
+
return new WP_Error( 'invalid-argument', __( 'Redirect from and/or redirect to arguments are invalid.', 'safe-redirect-manager' ) );
|
258 |
+
|
259 |
+
if ( ! in_array( $sanitized_status_code, $this->valid_status_codes ) )
|
260 |
+
return new WP_Error( 'invalid-argument', __( 'Invalid status code.', 'safe-redirect-manager' ) );
|
261 |
+
|
262 |
+
// Check to ensure this redirect doesn't already exist
|
263 |
+
if ( $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key=%s AND meta_value=%s", $this->meta_key_redirect_from, $sanitized_redirect_from ) ) )
|
264 |
+
return new WP_Error( 'duplicate-redirect', sprintf( __( 'Redirect already exists for %s', 'safe-redirect-manager' ), $sanitized_redirect_from ) );
|
265 |
+
|
266 |
+
// create the post
|
267 |
+
$post_args = array(
|
268 |
+
'post_type' => $this->redirect_post_type,
|
269 |
+
'post_status' => $sanitized_post_status,
|
270 |
+
'post_author' => 1
|
271 |
+
);
|
272 |
+
|
273 |
+
$post_id = wp_insert_post( $post_args );
|
274 |
+
|
275 |
+
if ( 0 >= $post_id )
|
276 |
+
return new WP_Error( 'error-creating', __( 'An error occurred creating the redirect.', 'safe-redirect-manager' ) );
|
277 |
+
|
278 |
+
// update the posts meta info
|
279 |
+
update_post_meta( $post_id, $this->meta_key_redirect_from, $sanitized_redirect_from );
|
280 |
+
update_post_meta( $post_id, $this->meta_key_redirect_to, $sanitized_redirect_to );
|
281 |
+
update_post_meta( $post_id, $this->meta_key_redirect_status_code, $sanitized_status_code );
|
282 |
+
update_post_meta( $post_id, $this->meta_key_enable_redirect_from_regex, $sanitized_enable_regex );
|
283 |
+
|
284 |
+
// We need to update the cache after creating this redirect
|
285 |
+
$this->update_redirect_cache();
|
286 |
+
|
287 |
+
return $post_id;
|
288 |
+
}
|
289 |
+
|
290 |
+
/**
|
291 |
+
* Whether or not this is an admin page specific to the plugin
|
292 |
+
*
|
293 |
+
* @since 1.1
|
294 |
+
* @uses get_post_type
|
295 |
+
* @return bool
|
296 |
+
*/
|
297 |
+
private function is_plugin_page() {
|
298 |
+
return (bool) ( get_post_type() == $this->redirect_post_type || ( isset( $_GET['post_type'] ) && $this->redirect_post_type == $_GET['post_type'] ) );
|
299 |
+
}
|
300 |
+
|
301 |
+
/**
|
302 |
+
* Echoes admin message if redirect chains exist
|
303 |
+
*
|
304 |
+
* @since 1.0
|
305 |
+
* @uses apply_filters
|
306 |
+
* @return void
|
307 |
+
*/
|
308 |
+
public function action_redirect_chain_alert() {
|
309 |
+
global $hook_suffix;
|
310 |
+
if ( $this->is_plugin_page() ) {
|
311 |
+
|
312 |
+
/**
|
313 |
+
* check_for_possible_redirect_loops() runs in best case Theta(n^2) so if you have 100 redirects, this method
|
314 |
+
* will be running slow. Let's disable it by default.
|
315 |
+
*/
|
316 |
+
if ( apply_filters( 'srm_check_for_possible_redirect_loops', false ) ) {
|
317 |
+
if ( $this->check_for_possible_redirect_loops() ) {
|
318 |
+
?>
|
319 |
+
<div class="updated">
|
320 |
+
<p><?php _e( 'Safe Redirect Manager Warning: Possible redirect loops and/or chains have been created.', 'safe-redirect-manager' ); ?></p>
|
321 |
+
</div>
|
322 |
+
<?php
|
323 |
+
}
|
324 |
+
} if ( $this->max_redirects_reached() ) {
|
325 |
+
?>
|
326 |
+
<?php if ( 'post-new.php' == $hook_suffix ) : ?><style type="text/css">#post { display: none; }</style><?php endif; ?>
|
327 |
+
<div class="error">
|
328 |
+
<p><?php _e( 'Safe Redirect Manager Error: You have reached the maximum allowable number of redirects', 'safe-redirect-manager' ); ?></p>
|
329 |
+
</div>
|
330 |
+
<?php
|
331 |
+
}
|
332 |
+
}
|
333 |
+
}
|
334 |
+
|
335 |
+
/**
|
336 |
+
* Returns true if max redirects have been reached
|
337 |
+
*
|
338 |
+
* @since 1.0
|
339 |
+
* @uses apply_filters, get_transient
|
340 |
+
* @return bool
|
341 |
+
*/
|
342 |
+
public function max_redirects_reached() {
|
343 |
+
if ( false === ( $redirects = get_transient( $this->cache_key_redirects ) ) ) {
|
344 |
+
$redirects = $this->update_redirect_cache();
|
345 |
+
}
|
346 |
+
|
347 |
+
return ( count( $redirects ) >= $this->default_max_redirects );
|
348 |
+
}
|
349 |
+
|
350 |
+
/**
|
351 |
+
* Check for potential redirect loops or chains
|
352 |
+
*
|
353 |
+
* @since 1.0
|
354 |
+
* @uses home_url, get_transient
|
355 |
+
* @return boolean
|
356 |
+
*/
|
357 |
+
public function check_for_possible_redirect_loops() {
|
358 |
+
if ( false === ( $redirects = get_transient( $this->cache_key_redirects ) ) ) {
|
359 |
+
$redirects = $this->update_redirect_cache();
|
360 |
+
}
|
361 |
+
|
362 |
+
$current_url = parse_url( home_url() );
|
363 |
+
$this_host = ( is_array( $current_url ) && ! empty( $current_url['host'] ) ) ? $current_url['host'] : '';
|
364 |
+
|
365 |
+
foreach ( $redirects as $redirect ) {
|
366 |
+
$redirect_from = $redirect['redirect_from'];
|
367 |
+
|
368 |
+
// check redirect from against all redirect to's
|
369 |
+
foreach ( $redirects as $compare_redirect ) {
|
370 |
+
$redirect_to = $compare_redirect['redirect_to'];
|
371 |
+
|
372 |
+
$redirect_url = parse_url( $redirect_to );
|
373 |
+
$redirect_host = ( is_array( $redirect_url ) && ! empty( $redirect_url['host'] ) ) ? $redirect_url['host'] : '';
|
374 |
+
|
375 |
+
// check if we are redirecting locally
|
376 |
+
if ( empty( $redirect_host ) || $redirect_host == $this_host ) {
|
377 |
+
$redirect_from_url = preg_replace( '/(http:\/\/|https:\/\/|www\.)/i', '', home_url() . $redirect_from );
|
378 |
+
$redirect_to_url = $redirect_to;
|
379 |
+
if ( ! preg_match( '/https?:\/\//i', $redirect_to_url ) )
|
380 |
+
$redirect_to_url = $this_host . $redirect_to_url;
|
381 |
+
else
|
382 |
+
$redirect_to_url = preg_replace( '/(http:\/\/|https:\/\/|www\.)/i', '', $redirect_to_url );
|
383 |
+
|
384 |
+
// possible loop/chain found
|
385 |
+
if ( $redirect_to_url == $redirect_from_url )
|
386 |
+
return true;
|
387 |
+
}
|
388 |
+
}
|
389 |
+
}
|
390 |
+
|
391 |
+
return false;
|
392 |
+
}
|
393 |
+
|
394 |
+
/**
|
395 |
+
* Filters title out for redirect from in post manager
|
396 |
+
*
|
397 |
+
* @since 1.0
|
398 |
+
* @param string $title
|
399 |
+
* @param int $post_id
|
400 |
+
* @uses is_admin, get_post_meta
|
401 |
+
* @return string
|
402 |
+
*/
|
403 |
+
public function filter_admin_title( $title, $post_id = 0 ) {
|
404 |
+
if ( ! is_admin() )
|
405 |
+
return $title;
|
406 |
+
|
407 |
+
$redirect = get_post( $post_id );
|
408 |
+
if ( empty( $redirect ) )
|
409 |
+
return $title;
|
410 |
+
|
411 |
+
if ( $redirect->post_type != $this->redirect_post_type )
|
412 |
+
return $title;
|
413 |
+
|
414 |
+
$redirect_from = get_post_meta( $post_id, $this->meta_key_redirect_from, true );
|
415 |
+
if ( ! empty( $redirect_from ) )
|
416 |
+
return $redirect_from;
|
417 |
+
|
418 |
+
return $title;
|
419 |
+
}
|
420 |
+
|
421 |
+
/**
|
422 |
+
* Customizes updated messages for redirects
|
423 |
+
*
|
424 |
+
* @since 1.0
|
425 |
+
* @param array $messages
|
426 |
+
* @uses esc_url, get_permalink, add_query_var, wp_post_revision_title
|
427 |
+
* @return array
|
428 |
+
*/
|
429 |
+
public function filter_redirect_updated_messages( $messages ) {
|
430 |
+
global $post, $post_ID;
|
431 |
+
|
432 |
+
$messages[$this->redirect_post_type] = array(
|
433 |
+
0 => '', // Unused. Messages start at index 1.
|
434 |
+
1 => sprintf( __( 'Redirect rule updated.', 'safe-redirect-manager' ), esc_url( get_permalink( $post_ID ) ) ),
|
435 |
+
2 => __( 'Custom field updated.', 'safe-redirect-manager' ),
|
436 |
+
3 => __( 'Custom field deleted.', 'safe-redirect-manager' ),
|
437 |
+
4 => __( 'Redirect rule updated.', 'safe-redirect-manager' ),
|
438 |
+
/* translators: %s: date and time of the revision */
|
439 |
+
5 => isset( $_GET['revision'] ) ? sprintf( __('Redirect rule restored to revision from %s', 'safe-redirect-manager' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
|
440 |
+
6 => sprintf( __( 'Redirect rule published.', 'safe-redirect-manager' ), esc_url( get_permalink( $post_ID ) ) ),
|
441 |
+
7 => __( 'Redirect rule saved.', 'safe-redirect-manager' ),
|
442 |
+
8 => sprintf( __( 'Redirect rule submitted.', 'safe-redirect-manager' ), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) ),
|
443 |
+
9 => sprintf( __( 'Redirect rule scheduled for: <strong>%1$s</strong>.', 'safe-redirect-manager' ),
|
444 |
+
// translators: Publish box date format, see http://php.net/date
|
445 |
+
date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink($post_ID) ) ),
|
446 |
+
10 => sprintf( __( 'Redirect rule draft updated.', 'safe-redirect-manager' ), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) ),
|
447 |
+
);
|
448 |
+
|
449 |
+
return $messages;
|
450 |
+
}
|
451 |
+
|
452 |
+
/**
|
453 |
+
* Clear redirect cache if appropriate post type is transitioned
|
454 |
+
*
|
455 |
+
* @since 1.0
|
456 |
+
* @param string $new_status
|
457 |
+
* @param string $old_status
|
458 |
+
* @param object $post
|
459 |
+
* @uses delete_transient
|
460 |
+
* @return void
|
461 |
+
*/
|
462 |
+
public function action_transition_post_status( $new_status, $old_status, $post ) {
|
463 |
+
if ( ! is_object( $post ) )
|
464 |
+
return;
|
465 |
+
|
466 |
+
// recreate redirect cache
|
467 |
+
if ( $this->redirect_post_type == $post->post_type ) {
|
468 |
+
delete_transient( $this->cache_key_redirects );
|
469 |
+
$this->update_redirect_cache();
|
470 |
+
}
|
471 |
+
}
|
472 |
+
|
473 |
+
/**
|
474 |
+
* Displays custom columns on redirect manager screen
|
475 |
+
*
|
476 |
+
* @since 1.0
|
477 |
+
* @param string $column
|
478 |
+
* @param int $post_id
|
479 |
+
* @uses get_post_meta, esc_html, admin_url
|
480 |
+
* @return void
|
481 |
+
*/
|
482 |
+
public function action_custom_redirect_columns( $column, $post_id ) {
|
483 |
+
if ( 'srm' . $this->meta_key_redirect_to == $column ) {
|
484 |
+
echo esc_html( get_post_meta( $post_id, $this->meta_key_redirect_to, true ) );
|
485 |
+
} elseif ( 'srm' . $this->meta_key_redirect_status_code == $column ) {
|
486 |
+
echo absint( get_post_meta( $post_id, $this->meta_key_redirect_status_code, true ) );
|
487 |
+
}
|
488 |
+
}
|
489 |
+
|
490 |
+
/**
|
491 |
+
* Add new columns to manage redirect screen
|
492 |
+
*
|
493 |
+
* @since 1.0
|
494 |
+
* @param array $columns
|
495 |
+
* @return array
|
496 |
+
*/
|
497 |
+
public function filter_redirect_columns( $columns ) {
|
498 |
+
$columns['srm' . $this->meta_key_redirect_to] = __( 'Redirect To', 'safe-redirect-manager' );
|
499 |
+
$columns['srm'. $this->meta_key_redirect_status_code] = __( 'HTTP Status Code', 'safe-redirect-manager' );
|
500 |
+
|
501 |
+
// Change the title column
|
502 |
+
$columns['title'] = __( 'Redirect From', 'safe-redirect-manager' );
|
503 |
+
|
504 |
+
// Move date column to the back
|
505 |
+
unset( $columns['date'] );
|
506 |
+
$columns['date'] = __( 'Date', 'safe-redirect-manager' );
|
507 |
+
|
508 |
+
return $columns;
|
509 |
+
}
|
510 |
+
|
511 |
+
/**
|
512 |
+
* Saves meta info for redirect rules
|
513 |
+
*
|
514 |
+
* @since 1.0
|
515 |
+
* @param int $post_id
|
516 |
+
* @uses current_user_can, get_post_type, wp_verify_nonce, update_post_meta, delete_post_meta
|
517 |
+
* @return void
|
518 |
+
*/
|
519 |
+
public function action_save_post( $post_id ) {
|
520 |
+
if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || ! current_user_can( 'edit_post', $post_id ) || 'revision' == get_post_type( $post_id ) )
|
521 |
+
return;
|
522 |
+
|
523 |
+
// Update post meta for redirect rules
|
524 |
+
if ( ! empty( $_POST[$this->redirect_nonce_name] ) && wp_verify_nonce( $_POST[$this->redirect_nonce_name], $this->redirect_nonce_action ) ) {
|
525 |
+
|
526 |
+
if ( ! empty( $_POST['srm' . $this->meta_key_enable_redirect_from_regex] ) ) {
|
527 |
+
$allow_regex = (bool) $_POST['srm' . $this->meta_key_enable_redirect_from_regex];
|
528 |
+
update_post_meta( $post_id, $this->meta_key_enable_redirect_from_regex, $allow_regex );
|
529 |
+
} else {
|
530 |
+
$allow_regex = false;
|
531 |
+
delete_post_meta( $post_id, $this->meta_key_enable_redirect_from_regex );
|
532 |
+
}
|
533 |
+
|
534 |
+
if ( ! empty( $_POST['srm' . $this->meta_key_redirect_from] ) ) {
|
535 |
+
update_post_meta( $post_id, $this->meta_key_redirect_from, $this->sanitize_redirect_from( $_POST['srm' . $this->meta_key_redirect_from], $allow_regex ) );
|
536 |
+
} else {
|
537 |
+
delete_post_meta( $post_id, $this->meta_key_redirect_from );
|
538 |
+
}
|
539 |
+
|
540 |
+
if ( ! empty( $_POST['srm' . $this->meta_key_redirect_to] ) ) {
|
541 |
+
update_post_meta( $post_id, $this->meta_key_redirect_to, $this->sanitize_redirect_to( $_POST['srm' . $this->meta_key_redirect_to] ) );
|
542 |
+
} else {
|
543 |
+
delete_post_meta( $post_id, $this->meta_key_redirect_to );
|
544 |
+
}
|
545 |
+
|
546 |
+
if ( ! empty( $_POST['srm' . $this->meta_key_redirect_status_code] ) ) {
|
547 |
+
update_post_meta( $post_id, $this->meta_key_redirect_status_code, absint( $_POST['srm' . $this->meta_key_redirect_status_code] ) );
|
548 |
+
} else {
|
549 |
+
delete_post_meta( $post_id, $this->meta_key_redirect_status_code );
|
550 |
+
}
|
551 |
+
|
552 |
+
/**
|
553 |
+
* This fixes an important bug where the redirect cache was not up-to-date. Previously the cache was only being
|
554 |
+
* updated on transition_post_status which gets called BEFORE save post. But since save_post is where all the important
|
555 |
+
* redirect info is saved, updating the cache before it is not sufficient.
|
556 |
+
*/
|
557 |
+
$this->update_redirect_cache();
|
558 |
+
}
|
559 |
+
}
|
560 |
+
|
561 |
+
/**
|
562 |
+
* Registers post types for plugin
|
563 |
+
*
|
564 |
+
* @since 1.0
|
565 |
+
* @uses register_post_type, _x, plugins_url, apply_filters
|
566 |
+
* @return void
|
567 |
+
*/
|
568 |
+
public function action_register_post_types() {
|
569 |
+
$redirect_labels = array(
|
570 |
+
'name' => _x( 'Safe Redirect Manager', 'post type general name', 'safe-redirect-manager' ),
|
571 |
+
'singular_name' => _x( 'Redirect', 'post type singular name', 'safe-redirect-manager' ),
|
572 |
+
'add_new' => _x( 'Create Redirect Rule', $this->redirect_post_type, 'safe-redirect-manager' ),
|
573 |
+
'add_new_item' => __( 'Safe Redirect Manager', 'safe-redirect-manager' ),
|
574 |
+
'edit_item' => __( 'Edit Redirect Rule', 'safe-redirect-manager' ),
|
575 |
+
'new_item' => __( 'New Redirect Rule', 'safe-redirect-manager' ),
|
576 |
+
'all_items' => __( 'Safe Redirect Manager', 'safe-redirect-manager' ),
|
577 |
+
'view_item' => __( 'View Redirect Rule', 'safe-redirect-manager' ),
|
578 |
+
'search_items' => __( 'Search Redirects', 'safe-redirect-manager' ),
|
579 |
+
'not_found' => __( 'No redirect rules found.', 'safe-redirect-manager' ),
|
580 |
+
'not_found_in_trash' => __( 'No redirect rules found in trash.', 'safe-redirect-manager' ),
|
581 |
+
'parent_item_colon' => '',
|
582 |
+
'menu_name' => __( 'Safe Redirect Manager', 'safe-redirect-manager' )
|
583 |
+
);
|
584 |
+
$redirect_capability = 'manage_options';
|
585 |
+
$redirect_capability = apply_filters( 'srm_restrict_to_capability', $redirect_capability );
|
586 |
+
$capabilities = array(
|
587 |
+
'edit_post' => $redirect_capability,
|
588 |
+
'read_post' => $redirect_capability,
|
589 |
+
'delete_post' => $redirect_capability,
|
590 |
+
'edit_posts' => $redirect_capability,
|
591 |
+
'edit_others_posts' => $redirect_capability,
|
592 |
+
'publish_posts' => $redirect_capability,
|
593 |
+
'read_private_posts' => $redirect_capability
|
594 |
+
);
|
595 |
+
|
596 |
+
$redirect_args = array(
|
597 |
+
'labels' => $redirect_labels,
|
598 |
+
'public' => false,
|
599 |
+
'publicly_queryable' => true,
|
600 |
+
'show_ui' => true,
|
601 |
+
'show_in_menu' => 'tools.php',
|
602 |
+
'query_var' => false,
|
603 |
+
'rewrite' => false,
|
604 |
+
'capability_type' => 'post',
|
605 |
+
'capabilities' => $capabilities,
|
606 |
+
'has_archive' => false,
|
607 |
+
'hierarchical' => false,
|
608 |
+
'register_meta_box_cb' => array( $this, 'action_redirect_rule_metabox' ),
|
609 |
+
'menu_position' => 80,
|
610 |
+
'supports' => array( '' )
|
611 |
+
);
|
612 |
+
register_post_type( $this->redirect_post_type, $redirect_args );
|
613 |
+
}
|
614 |
+
|
615 |
+
/**
|
616 |
+
* Registers meta boxes for redirect rule post type
|
617 |
+
*
|
618 |
+
* @since 1.0
|
619 |
+
* @uses add_meta_box
|
620 |
+
* @return void
|
621 |
+
*/
|
622 |
+
public function action_redirect_rule_metabox() {
|
623 |
+
add_meta_box( 'redirect_settings', __( 'Redirect Settings', 'safe-redirect-manager' ), array( $this, 'redirect_rule_metabox' ), $this->redirect_post_type, 'normal', 'core' );
|
624 |
+
}
|
625 |
+
|
626 |
+
/**
|
627 |
+
* Echoes HTML for redirect rule meta box
|
628 |
+
*
|
629 |
+
* @since 1.0
|
630 |
+
* @param object $post
|
631 |
+
* @uses wp_nonce_field, get_post_meta, esc_attr, selected
|
632 |
+
* @return void
|
633 |
+
*/
|
634 |
+
public function redirect_rule_metabox( $post ) {
|
635 |
+
wp_nonce_field( $this->redirect_nonce_action, $this->redirect_nonce_name );
|
636 |
+
|
637 |
+
$redirect_from = get_post_meta( $post->ID, $this->meta_key_redirect_from, true );
|
638 |
+
$redirect_to = get_post_meta( $post->ID, $this->meta_key_redirect_to, true );
|
639 |
+
$status_code = get_post_meta( $post->ID, $this->meta_key_redirect_status_code, true );
|
640 |
+
$enable_regex = get_post_meta( $post->ID, $this->meta_key_enable_redirect_from_regex, true );
|
641 |
+
if ( empty( $status_code ) )
|
642 |
+
$status_code = 302;
|
643 |
+
?>
|
644 |
+
<p>
|
645 |
+
<label for="srm<?php echo $this->meta_key_redirect_from; ?>"><?php _e( 'Redirect From:', 'safe-redirect-manager' ); ?></label><br />
|
646 |
+
<input type="text" name="srm<?php echo $this->meta_key_redirect_from; ?>" id="srm<?php echo $this->meta_key_redirect_from; ?>" value="<?php echo esc_attr( $redirect_from ); ?>" />
|
647 |
+
<input type="checkbox" name="srm<?php echo $this->meta_key_enable_redirect_from_regex; ?>" id="srm<?php echo $this->meta_key_enable_redirect_from_regex; ?>" <?php checked( true, (bool) $enable_regex ); ?> value="1" />
|
648 |
+
<label for="srm<?php echo $this->meta_key_enable_redirect_from_regex; ?>"><?php _e( 'Enable Regular Expressions (advanced)', 'safe-redirect-manager' ); ?></label><br />
|
649 |
+
<p class="description"><?php _e( "This path should be relative to the root of this WordPress installation (or the sub-site, if you are running a multi-site). Appending a (*) wildcard character will match all requests with the base. Warning: Enabling regular expressions will disable wildcards and completely change the way the * symbol is interpretted.", 'safe-redirect-manager' ); ?></p>
|
650 |
+
</p>
|
651 |
+
|
652 |
+
<p>
|
653 |
+
<label for="srm<?php echo $this->meta_key_redirect_to; ?>"><?php _e( 'Redirect To:', 'safe-redirect-manager' ); ?></label><br />
|
654 |
+
<input class="widefat" type="text" name="srm<?php echo $this->meta_key_redirect_to; ?>" id="srm<?php echo $this->meta_key_redirect_to; ?>" value="<?php echo esc_attr( $redirect_to ); ?>" /><br />
|
655 |
+
<p class="description"><?php _e( "This can be a URL or a path relative to the root of your website (not your WordPress installation). Ending with a (*) wildcard character will append the request match to the redirect.", 'safe-redirect-manager'); ?></p>
|
656 |
+
</p>
|
657 |
+
|
658 |
+
<p>
|
659 |
+
<label for="srm<?php echo $this->meta_key_redirect_status_code; ?>"><?php _e( 'HTTP Status Code:', 'safe-redirect-manager' ); ?></label>
|
660 |
+
<select name="srm<?php echo $this->meta_key_redirect_status_code; ?>" id="srm<?php echo $this->meta_key_redirect_status_code; ?>">
|
661 |
+
<?php foreach ( $this->valid_status_codes as $code ) : ?>
|
662 |
+
<option value="<?php echo esc_attr( $code ); ?>" <?php selected( $status_code, $code ); ?>><?php echo esc_html( $code . ' ' . $this->status_code_labels[$code] ); ?></option>
|
663 |
+
<?php endforeach; ?>
|
664 |
+
</select>
|
665 |
+
<em><?php _e( "If you don't know what this is, leave it as is.", 'safe-redirect-manager' ); ?></em>
|
666 |
+
</p>
|
667 |
+
<?php
|
668 |
+
}
|
669 |
+
|
670 |
+
/**
|
671 |
+
* Localize plugin
|
672 |
+
*
|
673 |
+
* @since 1.0
|
674 |
+
* @uses load_plugin_textdomain, plugin_basename
|
675 |
+
* @return void
|
676 |
+
*/
|
677 |
+
public function action_init() {
|
678 |
+
load_plugin_textdomain( 'safe-redirect-manager', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
|
679 |
+
|
680 |
+
$this->default_max_redirects = apply_filters( 'srm_max_redirects', $this->default_max_redirects );
|
681 |
+
}
|
682 |
+
|
683 |
+
/**
|
684 |
+
* Apply whitelisted hosts to allowed_redirect_hosts filter
|
685 |
+
*
|
686 |
+
* @since 1.0
|
687 |
+
* @param array $content
|
688 |
+
* @return array
|
689 |
+
*/
|
690 |
+
public function filter_allowed_redirect_hosts( $content ) {
|
691 |
+
|
692 |
+
foreach ( $this->whitelist_hosts as $host ) {
|
693 |
+
$without_www = preg_replace( '/^www\./i', '', $host );
|
694 |
+
$with_www = 'www.' . $without_www;
|
695 |
+
|
696 |
+
if ( ! in_array( $without_www, $content ) ) $content[] = $without_www;
|
697 |
+
if ( ! in_array( $with_www, $content ) ) $content[] = $with_www;
|
698 |
+
}
|
699 |
+
|
700 |
+
return $content;
|
701 |
+
}
|
702 |
+
|
703 |
+
/**
|
704 |
+
* Get redirects from the database
|
705 |
+
*
|
706 |
+
* @since 1.6
|
707 |
+
* @param array $args Any arguments to filter by
|
708 |
+
* @return array $redirects An array of redirects
|
709 |
+
*/
|
710 |
+
public function get_redirects( $args = array() ) {
|
711 |
+
|
712 |
+
$redirects = array();
|
713 |
+
|
714 |
+
if ( $this->default_max_redirects > 50 )
|
715 |
+
$posts_per_page = 50;
|
716 |
+
else
|
717 |
+
$posts_per_page = $this->default_max_redirects;
|
718 |
+
|
719 |
+
$i = 1;
|
720 |
+
do {
|
721 |
+
|
722 |
+
$defaults = array(
|
723 |
+
'posts_per_page' => $posts_per_page,
|
724 |
+
'post_status' => 'publish',
|
725 |
+
'paged' => $i,
|
726 |
+
);
|
727 |
+
|
728 |
+
$query_args = array_merge( $defaults, $args );
|
729 |
+
|
730 |
+
// Some arguments that don't need to be configurable
|
731 |
+
$query_args['post_type'] = $this->redirect_post_type;
|
732 |
+
$query_args['no_found_rows'] = false;
|
733 |
+
$query_args['update_term_cache'] = false;
|
734 |
+
|
735 |
+
$redirect_query = new WP_Query( $query_args );
|
736 |
+
|
737 |
+
foreach( $redirect_query->posts as $redirect ) {
|
738 |
+
$redirects[] = array(
|
739 |
+
'ID' => $redirect->ID,
|
740 |
+
'post_status' => $redirect->post_status,
|
741 |
+
'redirect_from' => get_post_meta( $redirect->ID, $this->meta_key_redirect_from, true ),
|
742 |
+
'redirect_to' => get_post_meta( $redirect->ID, $this->meta_key_redirect_to, true ),
|
743 |
+
'status_code' => (int)get_post_meta( $redirect->ID, $this->meta_key_redirect_status_code, true ),
|
744 |
+
'enable_regex' => (bool)get_post_meta( $redirect->ID, $this->meta_key_enable_redirect_from_regex, true ),
|
745 |
+
);
|
746 |
+
}
|
747 |
+
|
748 |
+
if ( count( $redirects ) == $this->default_max_redirects
|
749 |
+
|| count( $redirect_query->posts ) < $posts_per_page )
|
750 |
+
$build = false;
|
751 |
+
else
|
752 |
+
$build = true;
|
753 |
+
|
754 |
+
$i++;
|
755 |
+
|
756 |
+
} while ( $build );
|
757 |
+
|
758 |
+
return $redirects;
|
759 |
+
}
|
760 |
+
|
761 |
+
/**
|
762 |
+
* Force update on the redirect cache and return cache
|
763 |
+
*
|
764 |
+
* @since 1.0
|
765 |
+
* @uses set_transient, get_post_meta, the_post, have_posts, get_the_ID
|
766 |
+
* @return array
|
767 |
+
*/
|
768 |
+
public function update_redirect_cache() {
|
769 |
+
|
770 |
+
$redirect_cache = $this->get_redirects();
|
771 |
+
|
772 |
+
set_transient( $this->cache_key_redirects, $redirect_cache );
|
773 |
+
|
774 |
+
return $redirect_cache;
|
775 |
+
}
|
776 |
+
|
777 |
+
/**
|
778 |
+
* Check current url against redirects
|
779 |
+
*
|
780 |
+
* @since 1.0
|
781 |
+
* @uses esc_url_raw, wp_safe_redirect, untrailingslashit, get_transient, add_filter
|
782 |
+
* @return void
|
783 |
+
*/
|
784 |
+
public function action_parse_request() {
|
785 |
+
|
786 |
+
// Don't redirect from wp-admin
|
787 |
+
if ( is_admin() )
|
788 |
+
return;
|
789 |
+
|
790 |
+
// get redirects from cache or recreate it
|
791 |
+
if ( false === ( $redirects = get_transient( $this->cache_key_redirects ) ) ) {
|
792 |
+
$redirects = $this->update_redirect_cache();
|
793 |
+
}
|
794 |
+
|
795 |
+
// If we have no redirects, there is no need to continue
|
796 |
+
if ( empty( $redirects ) )
|
797 |
+
return;
|
798 |
+
|
799 |
+
// get requested path and add a / before it
|
800 |
+
$requested_path = esc_url_raw( $_SERVER['REQUEST_URI'] );
|
801 |
+
$requested_path = stripslashes( $requested_path );
|
802 |
+
|
803 |
+
$unslashed_requested_path = untrailingslashit( $requested_path );
|
804 |
+
if ( empty( $unslashed_requested_path ) ){
|
805 |
+
$unslashed_requested_path = '/';
|
806 |
+
}
|
807 |
+
|
808 |
+
/**
|
809 |
+
* If WordPress resides in a directory that is not the public root, we have to chop
|
810 |
+
* the pre-WP path off the requested path.
|
811 |
+
*/
|
812 |
+
$parsed_site_url = parse_url( site_url() );
|
813 |
+
if ( isset( $parsed_site_url['path'] ) && '/' != $parsed_site_url['path'] ) {
|
814 |
+
$requested_path = preg_replace( '@' . $parsed_site_url['path'] . '@i', '', $requested_path, 1 );
|
815 |
+
}
|
816 |
+
|
817 |
+
// Allow redirects to be filtered
|
818 |
+
$redirects = apply_filters( 'srm_registered_redirects', $redirects, $requested_path );
|
819 |
+
|
820 |
+
foreach ( (array)$redirects as $redirect ) {
|
821 |
+
|
822 |
+
$redirect_from = untrailingslashit( $redirect['redirect_from'] );
|
823 |
+
if ( empty( $redirect_from ) )
|
824 |
+
$redirect_from = '/'; // this only happens in the case where there is a redirect on the root
|
825 |
+
|
826 |
+
$redirect_to = $redirect['redirect_to'];
|
827 |
+
$status_code = $redirect['status_code'];
|
828 |
+
$enable_regex = ( isset( $redirect['enable_regex'] ) ) ? $redirect['enable_regex'] : false;
|
829 |
+
|
830 |
+
if ( apply_filters( 'srm_case_insensitive_redirects', true ) ) {
|
831 |
+
$requested_path = strtolower( $requested_path );
|
832 |
+
$redirect_from = strtolower( $redirect_from );
|
833 |
+
}
|
834 |
+
|
835 |
+
// check if requested path is the same as the redirect from path
|
836 |
+
if ( $enable_regex ) {
|
837 |
+
$matched_path = preg_match( '@' . $redirect_from . '@', $requested_path );
|
838 |
+
} else {
|
839 |
+
$matched_path = ( $unslashed_requested_path == $redirect_from );
|
840 |
+
|
841 |
+
// check if the redirect_from ends in a wildcard
|
842 |
+
if ( !$matched_path && (strrpos( $redirect_from, '*' ) === strlen( $redirect_from ) - 1) ) {
|
843 |
+
$wildcard_base = substr( $redirect_from, 0, strlen( $redirect_from ) - 1 );
|
844 |
+
|
845 |
+
// mark as match if requested path matches the base of the redirect from
|
846 |
+
$matched_path = (substr( $requested_path, 0, strlen( $wildcard_base ) ) == $wildcard_base);
|
847 |
+
if ( (strrpos( $redirect_to, '*' ) == strlen( $redirect_to ) - 1 ) ) {
|
848 |
+
$redirect_to = rtrim( $redirect_to, '*' ) . ltrim( substr( $requested_path, strlen( $wildcard_base ) ), '/' );
|
849 |
+
}
|
850 |
+
}
|
851 |
+
}
|
852 |
+
|
853 |
+
if ( $matched_path ) {
|
854 |
+
// whitelist redirect to host if necessary
|
855 |
+
$parsed_redirect = parse_url( $redirect_to );
|
856 |
+
if ( is_array( $parsed_redirect ) && ! empty( $parsed_redirect['host'] ) ) {
|
857 |
+
$this->whitelist_hosts[] = $parsed_redirect['host'];
|
858 |
+
add_filter( 'allowed_redirect_hosts' , array( $this, 'filter_allowed_redirect_hosts' ) );
|
859 |
+
}
|
860 |
+
|
861 |
+
// Allow for regex replacement in $redirect_to
|
862 |
+
if ( $enable_regex ) {
|
863 |
+
$redirect_to = preg_replace( '@' . $redirect_from . '@', $redirect_to, $requested_path );
|
864 |
+
}
|
865 |
+
|
866 |
+
$sanitized_redirect_to = esc_url_raw( $redirect_to );
|
867 |
+
|
868 |
+
do_action( 'srm_do_redirect', $requested_path, $sanitized_redirect_to, $status_code );
|
869 |
+
|
870 |
+
if ( defined( 'PHPUNIT_SRM_TESTSUITE' ) && PHPUNIT_SRM_TESTSUITE ) {
|
871 |
+
// Don't actually redirect if we are testing
|
872 |
+
return;
|
873 |
+
}
|
874 |
+
|
875 |
+
header( 'X-Safe-Redirect-Manager: true' );
|
876 |
+
|
877 |
+
// if we have a valid status code, then redirect with it
|
878 |
+
if ( in_array( $status_code, $this->valid_status_codes ) )
|
879 |
+
wp_safe_redirect( $sanitized_redirect_to, $status_code );
|
880 |
+
else
|
881 |
+
wp_safe_redirect( $sanitized_redirect_to );
|
882 |
+
exit;
|
883 |
+
}
|
884 |
+
}
|
885 |
+
}
|
886 |
+
|
887 |
+
/**
|
888 |
+
* Sanitize redirect to path
|
889 |
+
*
|
890 |
+
* The only difference between this function and just calling esc_url_raw is
|
891 |
+
* esc_url_raw( 'test' ) == 'http://test', whereas sanitize_redirect_path( 'test' ) == '/test'
|
892 |
+
*
|
893 |
+
* @since 1.0
|
894 |
+
* @param string $path
|
895 |
+
* @uses esc_url_raw
|
896 |
+
* @return string
|
897 |
+
*/
|
898 |
+
public function sanitize_redirect_to( $path ) {
|
899 |
+
$path = trim( $path );
|
900 |
+
|
901 |
+
if ( preg_match( '/^www\./i', $path ) )
|
902 |
+
$path = 'http://' . $path;
|
903 |
+
|
904 |
+
if ( ! preg_match( '/^https?:\/\//i', $path ) )
|
905 |
+
if ( strpos( $path, '/' ) !== 0 )
|
906 |
+
$path = '/' . $path;
|
907 |
+
|
908 |
+
return esc_url_raw( $path );
|
909 |
+
}
|
910 |
+
|
911 |
+
/**
|
912 |
+
* Sanitize redirect from path
|
913 |
+
*
|
914 |
+
* @since 1.0
|
915 |
+
* @param string $path
|
916 |
+
* @param boolean $allow_regex
|
917 |
+
* @uses esc_url_raw
|
918 |
+
* @return string
|
919 |
+
*/
|
920 |
+
public function sanitize_redirect_from( $path, $allow_regex = false ) {
|
921 |
+
|
922 |
+
$path = trim( $path );
|
923 |
+
|
924 |
+
if ( empty( $path ) )
|
925 |
+
return '';
|
926 |
+
|
927 |
+
// dont accept paths starting with a .
|
928 |
+
if ( ! $allow_regex && strpos( $path, '.' ) === 0 )
|
929 |
+
return '';
|
930 |
+
|
931 |
+
// turn path in to absolute
|
932 |
+
if ( preg_match( '/https?:\/\//i', $path ) )
|
933 |
+
$path = preg_replace( '/^(http:\/\/|https:\/\/)(www\.)?[^\/?]+\/?(.*)/i', '/$3', $path );
|
934 |
+
elseif ( ! $allow_regex && strpos( $path, '/' ) !== 0 )
|
935 |
+
$path = '/' . $path;
|
936 |
+
|
937 |
+
// the @ symbol will break our regex engine
|
938 |
+
$path = str_replace( '@', '', $path );
|
939 |
+
|
940 |
+
return $path;
|
941 |
+
}
|
942 |
+
|
943 |
+
/**
|
944 |
+
* Return a permalink for a redirect post, which is the "redirect from"
|
945 |
+
* URL for that redirect.
|
946 |
+
*
|
947 |
+
* @since 1.7
|
948 |
+
* @param string $permalink The permalink
|
949 |
+
* @param object $post A Post object
|
950 |
+
* @uses home_url, get_post_meta
|
951 |
+
* @return string The permalink
|
952 |
+
*/
|
953 |
+
public function filter_post_type_link( $permalink, $post ) {
|
954 |
+
if ( $this->redirect_post_type != $post->post_type )
|
955 |
+
return $permalink;
|
956 |
+
|
957 |
+
// We can't do anything to provide a permalink
|
958 |
+
// for regex enabled redirects.
|
959 |
+
if ( get_post_meta( $post->ID, $this->meta_key_enable_redirect_from_regex, true ) )
|
960 |
+
return $permalink;
|
961 |
+
|
962 |
+
// We can't do anything if there is a wildcard in the redirect from
|
963 |
+
$redirect_from = get_post_meta( $post->ID, $this->meta_key_redirect_from, true );
|
964 |
+
if ( false !== strpos( $redirect_from, '*' ) )
|
965 |
+
return $permalink;
|
966 |
+
|
967 |
+
// Use default permalink if no $redirect_from exists - this prevents duplicate GUIDs
|
968 |
+
if ( empty( $redirect_from ) ) {
|
969 |
+
return $permalink;
|
970 |
+
}
|
971 |
+
|
972 |
+
return home_url( $redirect_from );
|
973 |
+
}
|
974 |
}
|
975 |
|
976 |
global $safe_redirect_manager;
|
977 |
+
$safe_redirect_manager = new SRM_Safe_Redirect_Manager();
|
tests/bootstrap.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
$_tests_dir = getenv( 'WP_TESTS_DIR' );
|
4 |
+
if ( ! $_tests_dir ) {
|
5 |
+
$_tests_dir = '/tmp/wordpress-tests-lib';
|
6 |
+
}
|
7 |
+
|
8 |
+
define( 'PHPUNIT_SRM_TESTSUITE', 1 );
|
9 |
+
|
10 |
+
require_once ( $_tests_dir . '/includes/functions.php' );
|
11 |
+
|
12 |
+
function _manually_load_plugin() {
|
13 |
+
require dirname( __FILE__ ) . '/../safe-redirect-manager.php';
|
14 |
+
}
|
15 |
+
tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );
|
16 |
+
|
17 |
+
require( $_tests_dir . '/includes/bootstrap.php' );
|
18 |
+
|
tests/test-core.php
ADDED
@@ -0,0 +1,259 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class SRMTestCore extends WP_UnitTestCase {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Test root redirect
|
7 |
+
*
|
8 |
+
* @since 1.8
|
9 |
+
*/
|
10 |
+
public function testRootRedirect() {
|
11 |
+
global $safe_redirect_manager;
|
12 |
+
|
13 |
+
$_SERVER['REQUEST_URI'] = '/';
|
14 |
+
$redirected = false;
|
15 |
+
$redirect_to = '/gohere';
|
16 |
+
$safe_redirect_manager->create_redirect( '/', $redirect_to );
|
17 |
+
|
18 |
+
add_action( 'srm_do_redirect', function( $requested_path, $redirected_to, $status_code ) use ( &$redirect_to, &$redirected ) {
|
19 |
+
if ( $redirected_to === $redirect_to ) {
|
20 |
+
$redirected = true;
|
21 |
+
}
|
22 |
+
}, 10, 3 );
|
23 |
+
|
24 |
+
$safe_redirect_manager->action_parse_request();
|
25 |
+
|
26 |
+
$this->assertTrue( $redirected );
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Test lots of permutations of URL trailing slashes with and without regex
|
31 |
+
*
|
32 |
+
* @since 1.8
|
33 |
+
*/
|
34 |
+
public function testTrailingSlashes() {
|
35 |
+
/**
|
36 |
+
* First without regex
|
37 |
+
*/
|
38 |
+
|
39 |
+
global $safe_redirect_manager;
|
40 |
+
|
41 |
+
$_SERVER['REQUEST_URI'] = '/one';
|
42 |
+
$redirected = false;
|
43 |
+
$redirect_to = '/gohere';
|
44 |
+
$safe_redirect_manager->create_redirect( '/one/', $redirect_to );
|
45 |
+
|
46 |
+
add_action( 'srm_do_redirect', function( $requested_path, $redirected_to, $status_code ) use ( &$redirect_to, &$redirected ) {
|
47 |
+
if ( $redirected_to === $redirect_to ) {
|
48 |
+
$redirected = true;
|
49 |
+
}
|
50 |
+
}, 10, 3 );
|
51 |
+
|
52 |
+
$safe_redirect_manager->action_parse_request();
|
53 |
+
|
54 |
+
$this->assertTrue( $redirected );
|
55 |
+
|
56 |
+
$_SERVER['REQUEST_URI'] = '/one/';
|
57 |
+
$redirected = false;
|
58 |
+
$redirect_to = '/gohere';
|
59 |
+
$safe_redirect_manager->create_redirect( '/one', $redirect_to );
|
60 |
+
|
61 |
+
add_action( 'srm_do_redirect', function( $requested_path, $redirected_to, $status_code ) use ( &$redirect_to, &$redirected ) {
|
62 |
+
if ( $redirected_to === $redirect_to ) {
|
63 |
+
$redirected = true;
|
64 |
+
}
|
65 |
+
}, 10, 3 );
|
66 |
+
|
67 |
+
$safe_redirect_manager->action_parse_request();
|
68 |
+
|
69 |
+
$this->assertTrue( $redirected );
|
70 |
+
|
71 |
+
$_SERVER['REQUEST_URI'] = '/one/two';
|
72 |
+
$redirected = false;
|
73 |
+
$redirect_to = '/gohere';
|
74 |
+
$safe_redirect_manager->create_redirect( '/one/two/', $redirect_to );
|
75 |
+
|
76 |
+
add_action( 'srm_do_redirect', function( $requested_path, $redirected_to, $status_code ) use ( &$redirect_to, &$redirected ) {
|
77 |
+
if ( $redirected_to === $redirect_to ) {
|
78 |
+
$redirected = true;
|
79 |
+
}
|
80 |
+
}, 10, 3 );
|
81 |
+
|
82 |
+
$safe_redirect_manager->action_parse_request();
|
83 |
+
|
84 |
+
$this->assertTrue( $redirected );
|
85 |
+
|
86 |
+
$_SERVER['REQUEST_URI'] = '/one/two/';
|
87 |
+
$redirected = false;
|
88 |
+
$redirect_to = '/gohere';
|
89 |
+
$safe_redirect_manager->create_redirect( '/one/two', $redirect_to );
|
90 |
+
|
91 |
+
add_action( 'srm_do_redirect', function( $requested_path, $redirected_to, $status_code ) use ( &$redirect_to, &$redirected ) {
|
92 |
+
if ( $redirected_to === $redirect_to ) {
|
93 |
+
$redirected = true;
|
94 |
+
}
|
95 |
+
}, 10, 3 );
|
96 |
+
|
97 |
+
$safe_redirect_manager->action_parse_request();
|
98 |
+
|
99 |
+
$this->assertTrue( $redirected );
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Now with regex
|
103 |
+
*/
|
104 |
+
|
105 |
+
$_SERVER['REQUEST_URI'] = '/one/two';
|
106 |
+
$redirected = false;
|
107 |
+
$redirect_to = '/gohere';
|
108 |
+
$safe_redirect_manager->create_redirect( '/.*/', $redirect_to, 301, true );
|
109 |
+
|
110 |
+
add_action( 'srm_do_redirect', function( $requested_path, $redirected_to, $status_code ) use ( &$redirect_to, &$redirected ) {
|
111 |
+
if ( $redirected_to === $redirect_to ) {
|
112 |
+
$redirected = true;
|
113 |
+
}
|
114 |
+
}, 10, 3 );
|
115 |
+
|
116 |
+
$safe_redirect_manager->action_parse_request();
|
117 |
+
|
118 |
+
$this->assertTrue( $redirected );
|
119 |
+
|
120 |
+
$_SERVER['REQUEST_URI'] = '/one/two/';
|
121 |
+
$redirected = false;
|
122 |
+
$redirect_to = '/gohere';
|
123 |
+
$safe_redirect_manager->create_redirect( '/.*', $redirect_to, 301, true );
|
124 |
+
|
125 |
+
add_action( 'srm_do_redirect', function( $requested_path, $redirected_to, $status_code ) use ( &$redirect_to, &$redirected ) {
|
126 |
+
if ( $redirected_to === $redirect_to ) {
|
127 |
+
$redirected = true;
|
128 |
+
}
|
129 |
+
}, 10, 3 );
|
130 |
+
|
131 |
+
$safe_redirect_manager->action_parse_request();
|
132 |
+
|
133 |
+
$this->assertTrue( $redirected );
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Test some simple redirections
|
138 |
+
*
|
139 |
+
* @since 1.8
|
140 |
+
*/
|
141 |
+
public function testSimplePath() {
|
142 |
+
global $safe_redirect_manager;
|
143 |
+
|
144 |
+
$_SERVER['REQUEST_URI'] = '/test';
|
145 |
+
$redirected = false;
|
146 |
+
$redirect_to = '/gohere';
|
147 |
+
$safe_redirect_manager->create_redirect( '/test', $redirect_to );
|
148 |
+
|
149 |
+
add_action( 'srm_do_redirect', function( $requested_path, $redirected_to, $status_code ) use ( &$redirect_to, &$redirected ) {
|
150 |
+
if ( $redirected_to === $redirect_to ) {
|
151 |
+
$redirected = true;
|
152 |
+
}
|
153 |
+
}, 10, 3 );
|
154 |
+
|
155 |
+
$safe_redirect_manager->action_parse_request();
|
156 |
+
|
157 |
+
$this->assertTrue( $redirected );
|
158 |
+
|
159 |
+
/**
|
160 |
+
* Test longer path with no trailing slash
|
161 |
+
*/
|
162 |
+
|
163 |
+
$_SERVER['REQUEST_URI'] = '/test/this/path';
|
164 |
+
$redirected = false;
|
165 |
+
$redirect_to = '/gohere';
|
166 |
+
$safe_redirect_manager->create_redirect( '/test/this/path/', $redirect_to );
|
167 |
+
|
168 |
+
add_action( 'srm_do_redirect', function( $requested_path, $redirected_to, $status_code ) use ( &$redirect_to, &$redirected ) {
|
169 |
+
if ( $redirected_to === $redirect_to ) {
|
170 |
+
$redirected = true;
|
171 |
+
}
|
172 |
+
}, 10, 3 );
|
173 |
+
|
174 |
+
$safe_redirect_manager->action_parse_request();
|
175 |
+
|
176 |
+
$this->assertTrue( $redirected );
|
177 |
+
|
178 |
+
/**
|
179 |
+
* Test a redirect miss
|
180 |
+
*/
|
181 |
+
|
182 |
+
$_SERVER['REQUEST_URI'] = '/test/wrong/path';
|
183 |
+
$redirected = false;
|
184 |
+
$redirect_to = '/gohere';
|
185 |
+
$safe_redirect_manager->create_redirect( '/test/right/path/', $redirect_to );
|
186 |
+
|
187 |
+
add_action( 'srm_do_redirect', function( $requested_path, $redirected_to, $status_code ) use ( &$redirect_to, &$redirected ) {
|
188 |
+
if ( $redirected_to === $redirect_to ) {
|
189 |
+
$redirected = true;
|
190 |
+
}
|
191 |
+
}, 10, 3 );
|
192 |
+
|
193 |
+
$safe_redirect_manager->action_parse_request();
|
194 |
+
|
195 |
+
$this->assertTrue( ! $redirected );
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* Test regex redirections
|
200 |
+
*
|
201 |
+
* @since 1.8
|
202 |
+
*/
|
203 |
+
public function testSimplePathRegex() {
|
204 |
+
global $safe_redirect_manager;
|
205 |
+
|
206 |
+
$_SERVER['REQUEST_URI'] = '/tet/555/path/sdfsfsdf';
|
207 |
+
$redirected = false;
|
208 |
+
$redirect_to = '/gohere';
|
209 |
+
$safe_redirect_manager->create_redirect( '/tes?t/[0-9]+/path/[^/]+/?', $redirect_to, 301, true );
|
210 |
+
|
211 |
+
add_action( 'srm_do_redirect', function( $requested_path, $redirected_to, $status_code ) use ( &$redirect_to, &$redirected ) {
|
212 |
+
if ( $redirected_to === $redirect_to ) {
|
213 |
+
$redirected = true;
|
214 |
+
}
|
215 |
+
}, 10, 3 );
|
216 |
+
|
217 |
+
$safe_redirect_manager->action_parse_request();
|
218 |
+
|
219 |
+
$this->assertTrue( $redirected );
|
220 |
+
|
221 |
+
/**
|
222 |
+
* Test regex replacement
|
223 |
+
*/
|
224 |
+
|
225 |
+
$_SERVER['REQUEST_URI'] = '/well/everything-else/strip';
|
226 |
+
$redirected = false;
|
227 |
+
$redirect_to = '/$1';
|
228 |
+
$safe_redirect_manager->create_redirect( '/([a-z]+)/.*', $redirect_to, 301, true );
|
229 |
+
|
230 |
+
add_action( 'srm_do_redirect', function( $requested_path, $redirected_to, $status_code ) use ( &$redirect_to, &$redirected ) {
|
231 |
+
if ( $redirected_to === '/well' ) {
|
232 |
+
$redirected = true;
|
233 |
+
}
|
234 |
+
}, 10, 3 );
|
235 |
+
|
236 |
+
$safe_redirect_manager->action_parse_request();
|
237 |
+
|
238 |
+
$this->assertTrue( $redirected );
|
239 |
+
|
240 |
+
/**
|
241 |
+
* Test regex miss
|
242 |
+
*/
|
243 |
+
|
244 |
+
$_SERVER['REQUEST_URI'] = '/another/test';
|
245 |
+
$redirected = false;
|
246 |
+
$redirect_to = '/gohere';
|
247 |
+
$safe_redirect_manager->create_redirect( '/[0-9]+', $redirect_to, 301, true );
|
248 |
+
|
249 |
+
add_action( 'srm_do_redirect', function( $requested_path, $redirected_to, $status_code ) use ( &$redirect_to, &$redirected ) {
|
250 |
+
if ( $redirected_to === $redirect_to ) {
|
251 |
+
$redirected = true;
|
252 |
+
}
|
253 |
+
}, 10, 3 );
|
254 |
+
|
255 |
+
$safe_redirect_manager->action_parse_request();
|
256 |
+
|
257 |
+
$this->assertTrue( ! $redirected );
|
258 |
+
}
|
259 |
+
}
|