PluginProbe
404 Solution / 4.3.3
404 Solution v4.3.3
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_OptionsPresenter.php

View_OptionsPresenter.php in 404 Solution 4.3.3, at includes/view/View_OptionsPresenter.php

199 lines 8.4 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 * Presents option values for admin settings views.
9 *
10 * Owns view-only defaults, checked-state helpers, safe string extraction, and
11 * the behavior-tile markup for the default 404 destination setting.
12 */
13 class ABJ_404_Solution_View_OptionsPresenter extends ABJ_404_Solution_ViewComponent {
14
15 /** Get the 'checked' attribute for a checkbox based on option value.
16 * @param array<string, mixed> $options The options array
17 * @param string $key The option key to check
18 * @return string Returns ' checked' if option is '1', empty string otherwise
19 */
20 public function getCheckedAttr($options, $key) {
21 return (array_key_exists($key, $options) && $options[$key] == '1') ? " checked" : "";
22 }
23
24 /** @return array<string, string> */
25 public function getFallbackOptionDefaults() {
26 return array(
27 'default_redirect' => '301',
28 'DB_VERSION' => defined('ABJ404_VERSION') ? ABJ404_VERSION : '',
29 'menuLocation' => 'optionsLevel',
30 'admin_theme' => 'default',
31 'capture_deletion' => '0',
32 'admin_notification' => '0',
33 'maximum_log_disk_usage' => '0',
34 'admin_notification_email' => '',
35 'suggest_cats' => '0',
36 'suggest_tags' => '0',
37 'update_suggest_url' => '0',
38 'suggest_max' => '5',
39 'suggest_title' => '',
40 'suggest_before' => '',
41 'suggest_after' => '',
42 'suggest_entrybefore' => '',
43 'suggest_entryafter' => '',
44 'suggest_noresults' => '',
45 'ignore_doprocess' => '',
46 'ignore_dontprocess' => '',
47 'recognized_post_types' => 'page',
48 'recognized_categories' => '',
49 'folders_files_ignore' => '',
50 'suggest_regex_exclusions' => '',
51 'plugin_admin_users' => '',
52 'auto_score' => '0',
53 'template_redirect_priority' => '9',
54 'days_wait_before_major_update' => '0',
55 'excludePages[]' => '',
56 // These are used by other option cards; harmless defaults.
57 'auto_deletion' => '0',
58 'manual_deletion' => '0',
59 );
60 }
61
62 /**
63 * @param array<string, mixed> $options
64 * @return array<string, mixed>
65 */
66 public function normalizeOptionsForView($options) {
67 return array_merge($this->getFallbackOptionDefaults(), $options);
68 }
69
70 /**
71 * Get plugin options merged with defaults.
72 *
73 * Some tests use partial/mocked PluginLogic instances; this method must not
74 * assume getDefaultOptions() is available or safe to call.
75 *
76 * @return array<string, mixed>
77 */
78 public function getOptionsWithDefaults() {
79 $options = abj_service('options_repository')->getOptions();
80 if (!is_array($options)) {
81 $options = array();
82 }
83
84 $defaults = array();
85 if (is_object($this->logic) && method_exists($this->logic, 'getDefaultOptions')) {
86 try {
87 $defaults = ABJ_404_Solution_PluginLogicDefaults::defaults();
88 } catch (Throwable $e) { // allow-silent-catch: getDefaultOptions() is best-effort; empty array merges with getFallbackOptionDefaults() below
89 $defaults = array();
90 }
91 }
92
93 $defaults = is_array($defaults) && !empty($defaults)
94 ? array_merge($this->getFallbackOptionDefaults(), $defaults)
95 : $this->getFallbackOptionDefaults();
96
97 return array_merge($defaults, $options);
98 }
99
100 /**
101 * Build the behavior tiles HTML for the 404 destination setting.
102 * Used by both simple and advanced mode.
103 *
104 * @param array<string, mixed> $options
105 * @return string
106 */
107 public function getBehaviorTilesHTML($options) {
108 $behavior = isset($options['dest404_behavior']) && is_string($options['dest404_behavior'])
109 ? $options['dest404_behavior'] : 'theme_default';
110
111 $userSelectedDefault404PageRaw = (array_key_exists('dest404page', $options) &&
112 isset($options['dest404page']) ? $options['dest404page'] : null);
113 $userSelectedDefault404Page = is_string($userSelectedDefault404PageRaw) ? $userSelectedDefault404PageRaw : '';
114 $urlDestinationRaw = (array_key_exists('dest404pageURL', $options) &&
115 isset($options['dest404pageURL']) ? $options['dest404pageURL'] : null);
116 $urlDestination = is_string($urlDestinationRaw) ? $urlDestinationRaw : '';
117
118 $pageTitle = $this->logic->pageOrdering()->getPageTitleFromIDAndType($userSelectedDefault404Page, $urlDestination);
119 $pageMissingWarning = "";
120 if ($behavior === 'custom' && $userSelectedDefault404Page !== '') {
121 $permalink = ABJ_404_Solution_PermalinkResolver::permalinkInfoToArray($userSelectedDefault404Page, 0);
122 if (!in_array($permalink['status'], array('publish', 'published'))) {
123 $pageMissingWarning = __("(The specified page doesn't exist. Please update this setting.)", '404-solution');
124 }
125 }
126
127 $customDropdown = ABJ_404_Solution_FileSystemService::readFileContents(dirname(__DIR__) .
128 "/html/addManualRedirectPageSearchDropdown.html");
129 $customDropdown = $this->f->str_replace('{redirect_to_label}', '', $customDropdown);
130 $customDropdown = $this->f->str_replace('{TOOLTIP_POPUP_EXPLANATION_EMPTY}',
131 __('(Type a page name or an external URL)', '404-solution'), $customDropdown);
132 $customDropdown = $this->f->str_replace('{TOOLTIP_POPUP_EXPLANATION_PAGE}',
133 __('(A page has been selected.)', '404-solution'), $customDropdown);
134 $customDropdown = $this->f->str_replace('{TOOLTIP_POPUP_EXPLANATION_CUSTOM_STRING}',
135 __('(A custom string has been entered.)', '404-solution'), $customDropdown);
136 $customDropdown = $this->f->str_replace('{TOOLTIP_POPUP_EXPLANATION_URL}',
137 __('(An external URL will be used.)', '404-solution'), $customDropdown);
138 $customDropdown = $this->f->str_replace('{REDIRECT_TO_USER_FIELD_WARNING}', $pageMissingWarning, $customDropdown);
139 $customDropdown = $this->f->str_replace('{redirectPageTitle}', esc_attr($pageTitle), $customDropdown);
140 $customDropdown = $this->f->str_replace('{pageIDAndType}', esc_attr($userSelectedDefault404Page), $customDropdown);
141 $customDropdown = $this->f->str_replace('{data-url}',
142 "admin-ajax.php?action=echoRedirectToPages&includeDefault404Page=true&includeSpecial=true&nonce=" . wp_create_nonce('abj404_ajax'), $customDropdown);
143 $customDropdown = $this->f->doNormalReplacements($customDropdown);
144
145 $html = ABJ_404_Solution_FileSystemService::readFileContents(dirname(__DIR__) . "/html/behaviorTiles.html");
146
147 $behaviors = array('suggest', 'homepage', 'custom', 'theme_default');
148 foreach ($behaviors as $b) {
149 $isSelected = ($behavior === $b);
150 $html = $this->f->str_replace('{tile_' . $b . '_selected}', $isSelected ? ' selected' : '', $html);
151 $html = $this->f->str_replace('{' . $b . '_aria_checked}', $isSelected ? 'true' : 'false', $html);
152 }
153
154 $html = $this->f->str_replace('{selected_behavior}', esc_attr($behavior), $html);
155 $html = $this->f->str_replace('{pageIDAndType}', esc_attr($userSelectedDefault404Page), $html);
156 $html = $this->f->str_replace('{custom_picker_display}', $behavior === 'custom' ? '' : 'none', $html);
157 $html = $this->f->str_replace('{customPageDropdown}', $customDropdown, $html);
158
159 $html = $this->f->str_replace('{Recommended}', __('Recommended', '404-solution'), $html);
160 $html = $this->f->str_replace('{Suggest similar pages}', __('Suggest similar pages', '404-solution'), $html);
161 $html = $this->f->str_replace('{Shows visitors a list of pages matching the URL they were looking for}',
162 __('Shows visitors a list of pages matching the URL they were looking for', '404-solution'), $html);
163 $html = $this->f->str_replace('{Redirect to homepage}', __('Redirect to homepage', '404-solution'), $html);
164 $html = $this->f->str_replace('{Sends all 404 visitors to the site front page}',
165 __('Sends all 404 visitors to the site front page', '404-solution'), $html);
166 $html = $this->f->str_replace('{Custom page}', __('Custom page', '404-solution'), $html);
167 $html = $this->f->str_replace('{Choose a specific page to show for all 404 errors}',
168 __('Choose a specific page to show for all 404 errors', '404-solution'), $html);
169 $html = $this->f->str_replace('{Theme default}', __('Theme default', '404-solution'), $html);
170 $html = $this->f->str_replace('{Uses the theme built-in 404 page, no redirect}',
171 __('Uses the theme built-in 404 page, no redirect', '404-solution'), $html);
172 $html = $this->f->str_replace('{Select a page}', __('Select a page', '404-solution'), $html);
173
174 return $html;
175 }
176
177 /**
178 * Safely extract a string value from an options array.
179 *
180 * @param array<string, mixed> $options
181 * @param string $key
182 * @param string $default
183 * @return string
184 */
185 public function optStr($options, $key, $default = '') {
186 if (!array_key_exists($key, $options)) {
187 return $default;
188 }
189 $val = $options[$key];
190 if (is_string($val)) {
191 return $val;
192 }
193 if (is_scalar($val)) {
194 return (string)$val;
195 }
196 return $default;
197 }
198 }
199