PluginProbe
404 Solution / 4.3.0
404 Solution v4.3.0
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 4.3.0, at includes/admin/actions/AddRedirectHandler.php

129 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 $f = $this->parent->getFunctions();
66 $urlNormalization = $this->parent->getUrlNormalization();
67 $redirectsRepo = $this->parent->getRedirectsRepo();
68 $logger = $this->parent->getLogger();
69
70 if (!isset($_POST['manual_redirect_url']) || $_POST['manual_redirect_url'] == "") {
71 $message .= __('Error: URL is a required field.', '404-solution') . "<BR/>";
72 return $message;
73 }
74
75 $manualURL = isset($_POST['manual_redirect_url']) ? wp_unslash($_POST['manual_redirect_url']) : '';
76 $manualURL = $urlNormalization->normalizeUserProvidedPath($manualURL);
77 if ($f->substr($manualURL, 0, 1) != "/") {
78 $message .= __('Error: URL must start with /', '404-solution') . "<BR/>";
79 return $message;
80 }
81
82 $typeAndDest = $this->resolver->getRedirectTypeAndDest();
83
84 $tdMsg = is_string($typeAndDest['message']) ? $typeAndDest['message'] : '';
85 if ($tdMsg != "") {
86 return $tdMsg;
87 }
88
89 $tdType2 = is_scalar($typeAndDest['type']) ? (string)$typeAndDest['type'] : '';
90 $tdDest2 = is_scalar($typeAndDest['dest']) ? (string)$typeAndDest['dest'] : '';
91 $postedCodeForCheck2 = isset($_POST['code']) && is_scalar($_POST['code']) ? (string)$_POST['code'] : '';
92 $code410 = $postedCodeForCheck2 === '410' || $postedCodeForCheck2 === '451';
93 if ($tdType2 != "" && ($tdDest2 !== "" || $code410)) {
94 $statusType = ABJ404_STATUS_MANUAL;
95 if (isset($_POST['is_regex_url']) &&
96 $_POST['is_regex_url'] != '0') {
97
98 $statusType = ABJ404_STATUS_REGEX;
99 }
100
101 $code = isset($_POST['code']) && is_scalar($_POST['code']) && (string)$_POST['code'] !== '' ? (string)$_POST['code'] : '301';
102
103 $originalManualURL = $manualURL;
104 $autoPromoteAdd = $this->resolver->maybeAutoPromoteRegex($statusType, $manualURL);
105 $statusType = $autoPromoteAdd['statusType'];
106 $manualURL = $autoPromoteAdd['url'];
107
108 $newRedirectId = $redirectsRepo->setupRedirect(ABJ_404_Solution_RedirectSpec::fromArray(array(
109 'fromURL' => $manualURL,
110 'status' => (string)$statusType,
111 'type' => $tdType2,
112 'finalDest' => $tdDest2,
113 'code' => sanitize_text_field($code),
114 'disabled' => 0,
115 )));
116 if ($autoPromoteAdd['autoPromoted']) {
117 $this->resolver->saveRegexAutoPromoteNotice((int)$newRedirectId, $originalManualURL, $manualURL, $autoPromoteAdd['urlRewritten']);
118 }
119
120 } else {
121 $message .= __('Error: Data not formatted properly.', '404-solution') . "<BR/>";
122 $logger->errorMessage("Add redirect data issue. Type: " . esc_html($tdType2) . ", dest: " .
123 esc_html($tdDest2));
124 }
125
126 return $message;
127 }
128 }
129