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 / admin / actions / AddRedirectHandler.php

AddRedirectHandler.php in 404 Solution trunk, at includes/admin/actions/AddRedirectHandler.php

133 lines 4.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('ABSPATH')) {
4 exit;
5 }
6
7 /**
8 * Handles action 'addRedirect': processes the Add Redirect form POST.
9 *
10 * Validates the manually entered URL, normalizes it, resolves the destination
11 * via the shared RedirectFormResolver, applies regex auto-promotion, then
12 * writes through to redirectsRepo->setupRedirect(). Returns the framed
13 * success/error message to the dispatcher.
14 *
15 * The form-validation logic previously lived on
16 * PluginLogicAdminActions::addAdminRedirect() (M201, design-audit-2026-06-02).
17 * That parent method is now a thin shim that calls addAdminRedirect() here
18 * so existing tests/callers do not break.
19 */
20 class ABJ_404_Solution_AddRedirectHandler implements ABJ_404_Solution_AdminActionHandlerInterface {
21
22 /** @var ABJ_404_Solution_PluginLogicAdminActions */
23 private $parent;
24
25 /** @var ABJ_404_Solution_RedirectFormResolver */
26 private $resolver;
27
28 public function __construct(
29 ABJ_404_Solution_PluginLogicAdminActions $parent,
30 ?ABJ_404_Solution_RedirectFormResolver $resolver = null
31 ) {
32 $this->parent = $parent;
33 $this->resolver = $resolver !== null ? $resolver : $parent->redirectFormResolver();
34 }
35
36 public function nonceAction(): string {
37 return 'abj404addRedirect';
38 }
39
40 public function nonceArg(): string {
41 return '_wpnonce';
42 }
43
44 public function useCheckAdminReferer(): bool {
45 return true;
46 }
47
48 public function handle(string $action, string &$sub): string {
49 $message = $this->addAdminRedirect();
50 if ($message == '') {
51 return __('New Redirect Added Successfully!', '404-solution');
52 }
53 return $message . __('Error: unable to add new redirect.', '404-solution');
54 }
55
56 /**
57 * Run the add-redirect work. Public so the legacy
58 * PluginLogicAdminActions::addAdminRedirect() shim and existing tests can
59 * call it directly.
60 *
61 * @return string error message, '' on success
62 */
63 public function addAdminRedirect(): string {
64 $message = "";
65 $urlNormalization = $this->parent->getUrlNormalization();
66 $redirectsRepo = $this->parent->getRedirectsRepo();
67 $logger = $this->parent->getLogger();
68
69 if (!isset($_POST['manual_redirect_url']) || $_POST['manual_redirect_url'] == "") {
70 $message .= __('Error: URL is a required field.', '404-solution') . "<BR/>";
71 return $message;
72 }
73
74 $statusType = ABJ404_STATUS_MANUAL;
75 if (isset($_POST['is_regex_url']) && $_POST['is_regex_url'] != '0') {
76 $statusType = ABJ404_STATUS_REGEX;
77 }
78
79 $postedManualURL = $this->postedManualUrl();
80 $originalManualURL = $urlNormalization->sanitizeRedirectSource($postedManualURL);
81 $autoPromoteAdd = $this->resolver->resolveSource($statusType, $originalManualURL);
82 $statusType = $autoPromoteAdd['statusType'];
83 $manualURL = $autoPromoteAdd['url'];
84
85 $typeAndDest = $this->resolver->getRedirectTypeAndDest(array(
86 'isRegex' => $statusType === ABJ404_STATUS_REGEX,
87 'sourcePattern' => $manualURL,
88 ));
89
90 $tdMsg = is_string($typeAndDest['message']) ? $typeAndDest['message'] : '';
91 if ($tdMsg != "") {
92 return $tdMsg;
93 }
94
95 $tdType2 = is_scalar($typeAndDest['type']) ? (string)$typeAndDest['type'] : '';
96 $tdDest2 = is_scalar($typeAndDest['dest']) ? (string)$typeAndDest['dest'] : '';
97 $postedCodeForCheck2 = ABJ_404_Solution_RequestInputNormalizer::readText(
98 $_POST, array('name' => 'code'));
99 $code410 = $postedCodeForCheck2 === '410' || $postedCodeForCheck2 === '451';
100 if ($tdType2 != "" && ($tdDest2 !== "" || $code410)) {
101 $code = $postedCodeForCheck2 !== '' ? $postedCodeForCheck2 : '301';
102
103 $newRedirectId = $redirectsRepo->setupRedirect(ABJ_404_Solution_RedirectSpec::fromArray(array(
104 'fromURL' => $manualURL,
105 'status' => (string)$statusType,
106 'type' => $tdType2,
107 'finalDest' => $tdDest2,
108 'code' => $code,
109 'disabled' => 0,
110 )));
111 if ($autoPromoteAdd['autoPromoted']) {
112 $this->resolver->saveRegexAutoPromoteNotice((int)$newRedirectId, $originalManualURL, $manualURL, $autoPromoteAdd['urlRewritten']);
113 }
114
115 } else {
116 $message .= __('Error: Data not formatted properly.', '404-solution') . "<BR/>";
117 $logger->errorMessage("Add redirect data issue. Type: " . esc_html($tdType2) . ", dest: " .
118 esc_html($tdDest2));
119 }
120
121 return $message;
122 }
123
124 private function postedManualUrl(): string {
125 if (!isset($_POST['manual_redirect_url']) || !is_scalar($_POST['manual_redirect_url'])) {
126 return '';
127 }
128
129 $unslashed = wp_unslash((string)$_POST['manual_redirect_url']);
130 return is_string($unslashed) ? $unslashed : '';
131 }
132 }
133