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 / view / View_RedirectForms.php

View_RedirectForms.php in 404 Solution trunk, at includes/view/View_RedirectForms.php

207 lines 9.5 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 * Standalone Add/Edit redirect form rendering. Owns the legacy
9 * "Add Manual Redirect" form, the Edit Redirect form (active-from/until +
10 * conditions + cancel/submit row), and the default destination <optgroup>
11 * shared by the redirect-to dropdowns. The modern Add Redirect modal lives
12 * on View_RedirectsTable (it is rendered as part of the Redirects page).
13 *
14 * Outside callers (via the View facade __call dispatch):
15 * - PluginLogic admin edit flow (echoEditRedirect)
16 * - Legacy add-redirect paths (echoAddManualRedirect)
17 * - Redirect-to dropdown builders (echoRedirectDestinationOptionsDefaults)
18 */
19 class ABJ_404_Solution_View_RedirectForms extends ABJ_404_Solution_ViewComponent {
20
21 /** @var ABJ_404_Solution_RedirectEditFormPresenter|null */
22 private $editFormPresenter = null;
23
24 /**
25 * The builder that owns the shape of this screen's own links.
26 *
27 * @return ABJ_404_Solution_RedirectEditFormPresenter
28 */
29 private function editFormPresenter(): ABJ_404_Solution_RedirectEditFormPresenter {
30 if ($this->editFormPresenter === null) {
31 $this->editFormPresenter = new ABJ_404_Solution_RedirectEditFormPresenter(
32 $this->f, new ABJ_404_Solution_RedirectEngineLabeler());
33 }
34 return $this->editFormPresenter;
35 }
36
37 private function tpl(string $name): string {
38 $raw = ABJ_404_Solution_FileSystemService::readFileContents(dirname(__DIR__) . '/html/' . $name, false);
39 return rtrim((string)$raw, "\n");
40 }
41
42 /** @param array<string,string> $vars */
43 private function fillTpl(string $name, array $vars): string {
44 return (string)$this->f->str_replace(array_keys($vars), array_values($vars), $this->tpl($name));
45 }
46
47 /**
48 * @param array<string, mixed> $tableOptions
49 * @return void
50 */
51 public function echoAddManualRedirect($tableOptions) {
52
53 $options = $this->optionsPresenter->getOptionsWithDefaults();
54
55 $url = "?page=" . ABJ404_PP . "&subpage=abj404_redirects";
56 $orderby = array_key_exists('orderby', $tableOptions) && is_string($tableOptions['orderby']) ? $tableOptions['orderby'] : 'url';
57 $order = array_key_exists('order', $tableOptions) && is_string($tableOptions['order']) ? $tableOptions['order'] : 'ASC';
58 if (!($orderby == "url" && $order == "ASC")) {
59 $url .= "&orderby=" . sanitize_text_field($orderby) . "&order=" . sanitize_text_field($order);
60 }
61 $filter = array_key_exists('filter', $tableOptions) && is_scalar($tableOptions['filter']) ? $tableOptions['filter'] : 0;
62 if ($filter != 0) {
63 $url .= "&filter=" . $filter;
64 }
65 $link = wp_nonce_url($url, "abj404addRedirect");
66
67 $urlPlaceholder = parse_url(get_home_url(), PHP_URL_PATH) . "/example";
68 if (isset($_POST['url']) && $_POST['url'] != '') {
69 $postedURL = esc_url(ABJ_404_Solution_RequestInputNormalizer::normalizeScalar($_POST['url']));
70 } else {
71 $postedURL = $urlPlaceholder;
72 }
73
74 $selected301 = ($options['default_redirect'] == '301') ? ' selected ' : '';
75 $selected302 = ($options['default_redirect'] == '302') ? ' selected ' : '';
76 $selected307 = ($options['default_redirect'] == '307') ? ' selected ' : '';
77 $selected308 = ($options['default_redirect'] == '308') ? ' selected ' : '';
78 $selected410 = '';
79 $selected451 = '';
80 $selected0 = '';
81
82 // read the html content.
83 $html = ABJ_404_Solution_FileSystemService::readFileContents(dirname(__DIR__) . "/html/addManualRedirectTop.html");
84 $html .= ABJ_404_Solution_FileSystemService::readFileContents(dirname(__DIR__) .
85 "/html/addManualRedirectPageSearchDropdown.html");
86
87 $html = $this->f->str_replace(
88 array('{redirect_to_label}', '{TOOLTIP_POPUP_EXPLANATION_EMPTY}', '{TOOLTIP_POPUP_EXPLANATION_PAGE}',
89 '{TOOLTIP_POPUP_EXPLANATION_CUSTOM_STRING}', '{TOOLTIP_POPUP_EXPLANATION_URL}',
90 '{REDIRECT_TO_USER_FIELD_WARNING}', '{redirectPageTitle}', '{pageIDAndType}', '{data-url}'),
91 array(__('Redirect to', '404-solution'),
92 __('(Type a page name or an external URL)', '404-solution'),
93 __('(A page has been selected.)', '404-solution'),
94 __('(A custom string has been entered.)', '404-solution'),
95 __('(An external URL will be used.)', '404-solution'),
96 '', '', '',
97 "admin-ajax.php?action=echoRedirectToPages&includeDefault404Page=true&includeSpecial=true&nonce=" . wp_create_nonce('abj404_ajax')),
98 $html
99 );
100
101 $html .= ABJ_404_Solution_FileSystemService::readFileContents(dirname(__DIR__) . "/html/addManualRedirectBottom.html");
102 $html = $this->f->str_replace(
103 array('{addManualRedirectAction}', '{urlPlaceholder}', '{postedURL}',
104 '{301selected}', '{302selected}', '{307selected}', '{308selected}',
105 '{410selected}', '{451selected}', '{0selected}'),
106 array($link, esc_attr($urlPlaceholder), esc_attr($postedURL),
107 $selected301, $selected302, $selected307, $selected308,
108 $selected410, $selected451, $selected0),
109 $html
110 );
111
112 // constants and translations.
113 $html = $this->f->doNormalReplacements($html);
114
115 echo $html;
116 }
117
118 /** This is used both to add and to edit a redirect.
119 * @param ABJ_404_Solution_EditRedirectFormContext $ctx
120 * @return void
121 */
122 public function echoEditRedirect(ABJ_404_Solution_EditRedirectFormContext $ctx) {
123 $codeselected = $ctx->codeSelected;
124 $label = $ctx->label;
125 $source_page = $ctx->sourcePage;
126 $filter = $ctx->filter;
127 $orderby = $ctx->orderby;
128 $order = $ctx->order;
129 $startDate = $ctx->startDate;
130 $endDate = $ctx->endDate;
131 // allow-em-dash: comment-only context describing button grid section
132 // Redirect type button grid with hidden input
133 $this->redirectTypeUI->echoRedirectTypeButtonGrid((string)$codeselected);
134
135 // Advanced Options: Active From/Until + Conditions (collapsed by default)
136 $redirectId = 0;
137 $getRedirectId = $_GET['id'] ?? null;
138 $postRedirectId = $_POST['id'] ?? null;
139 if (is_scalar($getRedirectId) && $this->f->regexMatch('[0-9]+', (string)$getRedirectId)) {
140 $redirectId = absint($getRedirectId);
141 } elseif (is_scalar($postRedirectId) && $this->f->regexMatch('[0-9]+', (string)$postRedirectId)) {
142 $redirectId = absint($postRedirectId);
143 }
144 $hasExistingConditions = ($redirectId > 0) && !empty($this->redirectsRepository->getRedirectConditions($redirectId));
145 $hasAdvancedValues = ($startDate !== '' || $endDate !== '' || $hasExistingConditions);
146 $openAttr = $hasAdvancedValues ? ' open' : '';
147
148 ob_start();
149 $this->redirectConditions->echoRedirectConditionsSection();
150 $conditionsSection = (string)ob_get_clean();
151
152 echo $this->fillTpl('viewRedirectsTableAdvancedOptions.html', array(
153 '{open_attr}' => $openAttr,
154 '{advanced_options_label}' => esc_html__('Advanced Options', '404-solution'),
155 '{active_from_label}' => esc_html__('Active From (optional)', '404-solution'),
156 '{start_date_value}' => esc_attr($startDate),
157 '{active_from_help}' => esc_html__('Leave blank to activate immediately', '404-solution'),
158 '{active_until_label}' => esc_html__('Active Until (optional)', '404-solution'),
159 '{end_date_value}' => esc_attr($endDate),
160 '{active_until_help}' => esc_html__('Leave blank to never expire', '404-solution'),
161 '{conditions_section}' => $conditionsSection,
162 ));
163
164 // Cancel button URL, through the one builder that owns this link's
165 // shape. This was a second copy that encoded the same four values a
166 // different (and also wrong) way -- esc_attr here, nothing at all
167 // there -- which is how the two came to disagree about whether an '&'
168 // in a filter starts a new parameter.
169 $cancelUrl = $this->editFormPresenter()->buildCancelUrl(
170 (string)$source_page, (string)$filter, (string)$orderby, (string)$order);
171
172 echo $this->f->str_replace(
173 array('{cancel_url}', '{cancel_label}', '{submit_label}'),
174 array(esc_url($cancelUrl), esc_html__('Cancel', '404-solution'), esc_html($label)),
175 $this->tpl('viewRedirectsTableEditButtonGroup.html')
176 );
177 }
178
179 /**
180 * @param string $currentlySelected
181 * @return string
182 */
183 public function echoRedirectDestinationOptionsDefaults($currentlySelected) {
184 $content = "";
185 $content .= "\n" . '<optgroup label="' . __('Special', '404-solution') . '">' . "\n";
186
187 $selected = "";
188 if ($currentlySelected == ABJ404_TYPE_EXTERNAL) {
189 $selected = " selected";
190 }
191 $content .= "\n<option value=\"" . ABJ404_TYPE_EXTERNAL . "|" . ABJ404_TYPE_EXTERNAL . "\"" . $selected . ">" .
192 __('External Page', '404-solution') . "</option>";
193
194 if ($currentlySelected == ABJ404_TYPE_HOME) {
195 $selected = " selected";
196 } else {
197 $selected = "";
198 }
199 $content .= "\n<option value=\"" . ABJ404_TYPE_HOME . "|" . ABJ404_TYPE_HOME . "\"" . $selected . ">" .
200 __('Home Page', '404-solution') . "</option>";
201
202 $content .= "\n" . '</optgroup>' . "\n";
203
204 return $content;
205 }
206 }
207