PluginProbe
Photonic Gallery & Lightbox for Flickr, SmugMug & Others / 3.36
Photonic Gallery & Lightbox for Flickr, SmugMug & Others v3.36
3.36 3.35 3.34 3.33 2.19 2.20 2.21 2.22 2.23 2.24 2.25 2.26 2.27 2.28 2.29 2.30 2.31 2.32 2.33 2.34 2.40 2.41 2.42 2.43 2.44 All 141 releases
← All changes | Admin/Options_Manager.php +324 -480 2.413.36 View file →
@@ -1,10 +1,16 @@
1 1 <?php
2 +
2 3 namespace Photonic_Plugin\Admin;
3 4
5 +if (!current_user_can('edit_theme_options')) {
6 + wp_die(esc_html__('You are not authorized to use this capability.', 'photonic'));
7 +}
8 +
4 9 use Photonic_Plugin\Core\Photonic;
5 10
6 11 use Photonic_Plugin\Options\Defaults;
12 +use Photonic_Plugin\Options\DeviantArt;
7 13 use Photonic_Plugin\Options\Flickr;
8 14 use Photonic_Plugin\Options\Generic;
9 15 use Photonic_Plugin\Options\Google;
10 16 use Photonic_Plugin\Options\Instagram;
@@ -11,55 +17,70 @@
11 17 use Photonic_Plugin\Options\Lightbox;
12 18 use Photonic_Plugin\Options\SmugMug;
13 19 use Photonic_Plugin\Options\Zenfolio;
14 20
15 -require_once('Admin_Page.php');
21 +require_once 'Admin_Page.php';
16 22
17 23 class Options_Manager extends Admin_Page {
18 - var $options, $tab, $tab_options, $reverse_options, $shown_options, $option_defaults, $allowed_values, $hidden_options, $nested_options, $displayed_sections;
19 - var $option_structure, $previous_displayed_section, $file, $tab_name, $core;
24 + private string $tab;
25 + private array $tab_options;
26 + private array $reverse_options;
27 + private array $option_defaults;
28 + private array $allowed_values;
29 + private $hidden_options;
30 + private array $nested_options;
31 + private int $displayed_sections;
32 + private $option_structure;
33 + private string $previous_displayed_section;
34 + private string $file;
35 + private $tab_name;
36 + private $core;
20 37
21 38 /**
22 39 * Options_Manager constructor.
40 + *
23 41 * @param $file
24 42 * @param Photonic $core
25 43 */
26 - function __construct($file, $core) {
44 + public function __construct($file, $core) {
27 45 global $photonic_setup_options;
28 46 $options_page_array = [
29 - 'Generic.php' => Generic::get_instance()->get_options(),
30 - 'Flickr.php' => Flickr::get_instance()->get_options(),
31 - 'Google.php' => Google::get_instance()->get_options(),
32 - 'SmugMug.php' => SmugMug::get_instance()->get_options(),
33 - 'Zenfolio.php' => Zenfolio::get_instance()->get_options(),
34 - 'Instagram.php' => Instagram::get_instance()->get_options(),
35 - 'Lightbox.php' => Lightbox::get_instance()->get_options(),
47 + 'Generic.php' => Generic::get_instance()->get_options(),
48 + 'Flickr.php' => Flickr::get_instance()->get_options(),
49 + // 'Google.php' => Google::get_instance()->get_options(),
50 + 'SmugMug.php' => SmugMug::get_instance()->get_options(),
51 + 'Zenfolio.php' => Zenfolio::get_instance()->get_options(),
52 + // 'Instagram.php' => Instagram::get_instance()->get_options(),
53 + 'DeviantArt.php' => DeviantArt::get_instance()->get_options(),
54 + 'Lightbox.php' => Lightbox::get_instance()->get_options(),
36 55 ];
37 56
38 57 $tab_name_array = [
39 - 'Generic.php' => 'Generic Options',
40 - 'Flickr.php' => 'Flickr Options',
41 - 'Google.php' => 'Google Photos Options',
42 - 'SmugMug.php' => 'SmugMug Options',
43 - 'Zenfolio.php' => 'Zenfolio Options',
44 - 'Instagram.php' => 'Instagram Options',
45 - 'Lightbox.php' => 'Lightbox Options',
58 + 'Generic.php' => 'Generic Options',
59 + 'Flickr.php' => 'Flickr Options',
60 + // 'Google.php' => 'Google Photos Options',
61 + 'SmugMug.php' => 'SmugMug Options',
62 + 'Zenfolio.php' => 'Zenfolio Options',
63 + // 'Instagram.php' => 'Instagram Options',
64 + 'DeviantArt.php' => 'DeviantArt Options',
65 + 'Lightbox.php' => 'Lightbox Options',
46 66 ];
47 67
48 68 $this->core = $core;
49 69 $this->file = $file;
50 70 $this->tab = 'Generic.php';
51 - if (isset($_REQUEST['tab']) && array_key_exists($_REQUEST['tab'], $tab_name_array)) {
52 - $this->tab = $_REQUEST['tab'];
71 + if (isset($_REQUEST['tab']) && array_key_exists($_REQUEST['tab'], $tab_name_array)) { // phpcs:ignore WordPress.Security.NonceVerification
72 + $this->tab = sanitize_text_field($_REQUEST['tab']); // phpcs:ignore WordPress.Security.NonceVerification
53 73 }
54 74
55 75 $this->tab_options = $options_page_array[$this->tab];
56 76 $this->tab_name = $tab_name_array[$this->tab];
57 - $this->options = $photonic_setup_options;
58 77 $this->reverse_options = [];
59 78 $this->nested_options = [];
60 79 $this->displayed_sections = 0;
61 80 $this->option_structure = $this->get_option_structure();
81 + $this->option_defaults = [];
82 + $this->allowed_values = [];
62 83
63 84 $all_options = get_option('photonic_options');
64 85 if (!isset($all_options)) {
65 86 $this->hidden_options = [];
@@ -69,10 +90,11 @@
69 90 }
70 91
71 92 foreach ($this->tab_options as $option) {
72 93 if (isset($option['id'])) {
73 - $this->shown_options[] = $option['id'];
74 - if (isset($this->hidden_options[$option['id']])) unset($this->hidden_options[$option['id']]);
94 + if (isset($this->hidden_options[$option['id']])) {
95 + unset($this->hidden_options[$option['id']]);
96 + }
75 97 }
76 98 }
77 99
78 100 $defaults = Defaults::get_options();
@@ -87,10 +109,19 @@
87 109 $this->option_defaults[$option['id']] = $defaults[$option['id']];
88 110 $option['std'] = $defaults[$option['id']];
89 111
90 112 if (isset($option['options'])) {
91 - $this->allowed_values[$option['id']] = $option['options'];
113 + if ('radio-group' !== $option['type']) {
114 + $this->allowed_values[$option['id']] = $option['options'];
115 + }
116 + else {
117 + $this->allowed_values[$option['id']] = [];
118 + foreach ($option['options'] as $radio_group) {
119 + $this->allowed_values[$option['id']] = array_merge($this->allowed_values[$option['id']], $radio_group['options']);
120 + }
121 + }
92 122 }
123 +
93 124 if (isset($option['grouping'])) {
94 125 if (!isset($this->nested_options[$option['grouping']])) {
95 126 $this->nested_options[$option['grouping']] = [];
96 127 }
@@ -99,11 +130,11 @@
99 130 }
100 131 }
101 132 }
102 133
103 - function render_content() {
134 + public function render_content() {
104 135 $saved_options = get_option('photonic_options');
105 - if (isset($saved_options) && !empty($saved_options)) {
136 + if (!empty($saved_options) && current_user_can('edit_theme_options')) {
106 137 $generated_css = $this->core->generate_css(false);
107 138 update_option('photonic_css', $generated_css);
108 139 if (!empty($saved_options['css_in_file'])) {
109 140 $this->save_css_to_file($generated_css);
@@ -115,15 +146,29 @@
115 146 <div class="photonic-header-nav-top fix">
116 147 </div>
117 148 <div class="photonic-options-header-bar fix">
118 149 <h2 class='nav-tab-wrapper'>
119 - <a class='nav-tab <?php if ($this->tab == 'Generic.php') echo 'nav-tab-active'; ?>' id='photonic-options-generic' href='?page=photonic-options-manager&amp;tab=Generic.php'><span class="icon">&nbsp;</span> Generic Options</a>
120 - <a class='nav-tab <?php if ($this->tab == 'Flickr.php') echo 'nav-tab-active'; ?>' id='photonic-options-flickr' href='?page=photonic-options-manager&amp;tab=Flickr.php'><span class="icon">&nbsp;</span> Flickr</a>
121 - <a class='nav-tab <?php if ($this->tab == 'SmugMug.php') echo 'nav-tab-active'; ?>' id='photonic-options-smugmug' href='?page=photonic-options-manager&amp;tab=SmugMug.php'><span class="icon">&nbsp;</span> SmugMug</a>
122 - <a class='nav-tab <?php if ($this->tab == 'Google.php') echo 'nav-tab-active'; ?>' id='photonic-options-google' href='?page=photonic-options-manager&amp;tab=Google.php'><span class="icon">&nbsp;</span> Google Photos</a>
123 - <a class='nav-tab <?php if ($this->tab == 'Zenfolio.php') echo 'nav-tab-active'; ?>' id='photonic-options-zenfolio' href='?page=photonic-options-manager&amp;tab=Zenfolio.php'><span class="icon">&nbsp;</span> Zenfolio</a>
124 - <a class='nav-tab <?php if ($this->tab == 'Instagram.php') echo 'nav-tab-active'; ?>' id='photonic-options-instagram' href='?page=photonic-options-manager&amp;tab=Instagram.php'><span class="icon">&nbsp;</span> Instagram</a>
125 - <a class='nav-tab <?php if ($this->tab == 'Lightbox.php') echo 'nav-tab-active'; ?>' id='photonic-options-lightbox' href='?page=photonic-options-manager&amp;tab=Lightbox.php'><span class="icon">&nbsp;</span> Lightboxes</a>
150 + <a class='nav-tab <?php echo ('Generic.php' === $this->tab) ? 'nav-tab-active' : ''; ?>'
151 + id='photonic-options-generic' href='?page=photonic-options-manager&amp;tab=Generic.php'><span
152 + class="icon">&nbsp;</span> Generic Options</a>
153 + <a class='nav-tab <?php echo ('Flickr.php' === $this->tab) ? 'nav-tab-active' : ''; ?>'
154 + id='photonic-options-flickr' href='?page=photonic-options-manager&amp;tab=Flickr.php'><span
155 + class="icon">&nbsp;</span> Flickr</a>
156 + <a class='nav-tab <?php echo ('SmugMug.php' === $this->tab) ? 'nav-tab-active' : ''; ?>'
157 + id='photonic-options-smugmug' href='?page=photonic-options-manager&amp;tab=SmugMug.php'><span
158 + class="icon">&nbsp;</span> SmugMug</a>
159 + <a class='nav-tab <?php echo ('Zenfolio.php' === $this->tab) ? 'nav-tab-active' : ''; ?>'
160 + id='photonic-options-zenfolio'
161 + href='?page=photonic-options-manager&amp;tab=Zenfolio.php'><span class="icon">&nbsp;</span>
162 + Zenfolio</a>
163 +<!-- <a class='nav-tab <?php /*echo ('DeviantArt.php' === $this->tab) ? 'nav-tab-active' : ''; */ ?>'
164 + id='photonic-options-deviantart'
165 + href='?page=photonic-options-manager&amp;tab=DeviantArt.php'><span class="icon">&nbsp;</span>
166 + DeviantArt</a>
167 +--> <a class='nav-tab <?php echo ('Lightbox.php' === $this->tab) ? 'nav-tab-active' : ''; ?>'
168 + id='photonic-options-lightbox'
169 + href='?page=photonic-options-manager&amp;tab=Lightbox.php'><span class="icon">&nbsp;</span>
170 + Lightboxes</a>
126 171 </h2>
127 172 </div>
128 173 </div>
129 174 <?php
@@ -129,12 +174,12 @@
129 174 <?php
130 175 $option_structure = $this->get_option_structure();
131 176 $group = substr($this->tab, 0, stripos($this->tab, '.'));
132 177
133 - echo "<div class='photonic-options photonic-options-$group' id='photonic-options'>";
178 + echo "<div class='photonic-options photonic-options-" . esc_attr($group) . "' id='photonic-options'>";
134 179 echo "<ul class='photonic-section-tabs'>";
135 180 foreach ($option_structure as $l1_slug => $l1) {
136 - echo "<li><a href='#$l1_slug'>" . $l1['name'] . "</a></li>\n";
181 + echo wp_kses_post("<li><a href='#$l1_slug'>" . $l1['name'] . "</a></li>\n");
137 182 }
138 183 echo "</ul>";
139 184
140 185 do_settings_sections($this->file);
@@ -151,26 +196,26 @@
151 196 </div><!-- /#photonic-tabbed-options -->
152 197 <?php
153 198 }
154 199
155 - function show_buttons($slug, $option) {
156 - if (!isset($option['buttons']) || ($option['buttons'] != 'no-buttons' && $option['buttons'] != 'special-buttons')) {
157 - echo "<div class=\"photonic-button-bar photonic-button-bar-{$slug}\">\n";
158 - echo "<input name=\"photonic_options[submit-{$slug}]\" type='submit' value=\"Save page &ldquo;".esc_attr($option['name'])."&rdquo;\" class=\"button button-primary\" />\n";
159 - echo "<input name=\"photonic_options[submit-{$slug}]\" type='submit' value=\"Reset page &ldquo;".esc_attr($option['name'])."&rdquo;\" class=\"button\" />\n";
160 - echo "<input name=\"photonic_options[submit-{$slug}]\" type='submit' value=\"Delete all options\" class=\"button\" />\n";
200 + public function show_buttons($slug, $option) {
201 + if (!isset($option['buttons']) || ('no-buttons' !== $option['buttons'] && 'special-buttons' !== $option['buttons'])) {
202 + echo "<div class=\"photonic-button-bar photonic-button-bar-" . esc_attr($slug) . "\">\n";
203 + echo "<input name=\"photonic_options[submit-" . esc_attr($slug) . "]\" type='submit' value=\"Save page &ldquo;" . esc_attr($option['name']) . "&rdquo;\" class=\"button button-primary\" />\n";
204 + echo "<input name=\"photonic_options[submit-" . esc_attr($slug) . "]\" type='submit' value=\"Reset page &ldquo;" . esc_attr($option['name']) . "&rdquo;\" class=\"button\" />\n";
205 + echo "<input name=\"photonic_options[submit-" . esc_attr($slug) . "]\" type='submit' value=\"Delete all options\" class=\"button\" />\n";
161 206 echo "</div><!-- photonic-button-bar -->\n";
162 207 }
163 208 }
164 209
165 - function init() {
210 + public function init() {
166 211 foreach ($this->option_structure as $slug => $option) {
167 - if (!in_array($slug, Defaults::get_options_pages())) {
168 - wp_die("Invalid option section: $slug");
212 + if (!in_array($slug, Defaults::get_options_pages(), true)) {
213 + wp_die(esc_html("Invalid option section: $slug"));
169 214 }
170 215 // Since we are not including this file on all admin pages due to the size and associated load, register_setting cannot be done here.
171 216 // It is instead done via Admin_Menu, which is loaded for all admin pages.
172 - //register_setting('photonic_options-'.$slug, 'photonic_options', [&$this, 'validate_options']);
217 + // register_setting('photonic_options-'.$slug, 'photonic_options', [&$this, 'validate_options']);
173 218
174 219 add_settings_section($slug, "", [&$this, "create_settings_section"], $this->file);
175 220 $this->add_settings_fields($this->file);
176 221 }
@@ -175,30 +220,33 @@
175 220 $this->add_settings_fields($this->file);
176 221 }
177 222 }
178 223
179 - function validate_options($options) {
224 + public function validate_options($options): array {
180 225 foreach ($options as $option => $option_value) {
181 226 if (isset($this->reverse_options[$option])) {
182 - //Sanitize options
227 + // Sanitize options
183 228 switch ($this->reverse_options[$option]) {
184 229 // For all text type of options make sure that the eventual text is properly escaped.
185 230 case "text":
186 - case "textarea":
187 - case "color-picker":
188 231 case "background":
189 232 case "border":
190 - $options[$option] = esc_attr($option_value);
233 + $options[$option] = sanitize_text_field($option_value);
191 234 break;
192 235
236 + case "textarea":
237 + $options[$option] = sanitize_textarea_field($option_value);
238 + break;
239 +
193 240 case "select":
194 241 case "radio":
242 + case "radio-group":
195 243 if (isset($this->allowed_values[$option])) {
196 244 if (!array_key_exists($option_value, $this->allowed_values[$option])) {
197 245 $options[$option] = $this->option_defaults[$option];
198 246 }
199 247 }
200 - break;
248 + break;
201 249
202 250 case "multi-select":
203 251 $selections = explode(',', $option_value);
204 252 $final_selections = [];
@@ -209,22 +257,10 @@
209 257 }
210 258 $options[$option] = implode(',', $final_selections);
211 259 break;
212 260
213 - case "sortable-list":
214 - $selections = explode(',', $option_value);
215 - $final_selections = [];
216 - $master_list = $this->option_defaults[$option]; // Sortable lists don't have their values in ['options']
217 - foreach ($selections as $selection) {
218 - if (array_key_exists($selection, $master_list)) {
219 - $final_selections[] = $selection;
220 - }
221 - }
222 - $options[$option] = implode(',', $final_selections);
223 - break;
224 -
225 261 case "checkbox":
226 - if (!in_array($option_value, ['on', 'off', 'true', 'false']) && isset($this->option_defaults[$option])) {
262 + if (!in_array($option_value, ['on', 'off', 'true', 'false'], true) && isset($this->option_defaults[$option])) {
227 263 $options[$option] = $this->option_defaults[$option];
228 264 }
229 265 break;
230 266 }
@@ -230,9 +266,10 @@
230 266 }
231 267 }
232 268 }
233 269
234 - /* The Settings API does an update_option($option, $value), overwriting the $photonic_options array with the values on THIS page
270 + /*
271 + * The Settings API does an update_option($option, $value), overwriting the $photonic_options array with the values on THIS page
235 272 * This is problematic because all options are stored in a single array, but are displayed on different options pages.
236 273 * Hence the overwrite kills the options from the other pages.
237 274 * So this is a workaround to include the options from other pages as hidden fields on this page, so that the array gets properly updated.
238 275 * The alternative would be to separate options for each page, but that would cause a migration headache for current users.
@@ -239,9 +276,9 @@
239 276 */
240 277 $current_options = array_keys($options);
241 278 if (isset($this->hidden_options) && is_array($this->hidden_options)) {
242 279 foreach ($this->hidden_options as $hidden_option => $hidden_value) {
243 - if (strlen($hidden_option) >= 7 && (substr($hidden_option, 0, 7) == 'submit-' || substr($hidden_option, 0, 6) == 'reset-') || in_array($hidden_option, $current_options)) {
280 + if (strlen($hidden_option) >= 7 && ('submit-' === substr($hidden_option, 0, 7) || 'reset-' === substr($hidden_option, 0, 6)) || in_array($hidden_option, $current_options, true)) {
244 281 continue;
245 282 }
246 283 $options[$hidden_option] = esc_attr($hidden_value);
247 284 }
@@ -247,16 +284,16 @@
247 284 }
248 285 }
249 286
250 287 foreach ($this->nested_options as $section => $children) {
251 - if (isset($options['submit-'.$section])) {
288 + if (isset($options['submit-' . $section])) {
252 289 $options['last-set-section'] = $section;
253 - if (substr($options['submit-'.$section], 0, 9) == 'Save page' || substr($options['submit-'.$section], 0, 10) == 'Reset page') {
290 + if ('Save page' === substr($options['submit-' . $section], 0, 9) || 'Reset page' === substr($options['submit-' . $section], 0, 10)) {
254 291 global $photonic_options;
255 292 foreach ($this->nested_options as $inner_section => $inner_children) {
256 - if ($inner_section != $section) {
293 + if ($section !== $inner_section) {
257 294 foreach ($inner_children as $inner_child) {
258 - if (isset($photonic_options[$inner_child]) && !in_array($inner_child, $current_options)) {
295 + if (isset($photonic_options[$inner_child]) && !in_array($inner_child, $current_options, true)) {
259 296 $options[$inner_child] = $photonic_options[$inner_child];
260 297 }
261 298 }
262 299 }
@@ -261,19 +298,19 @@
261 298 }
262 299 }
263 300 }
264 301
265 - if (substr($options['submit-'.$section], 0, 10) == 'Reset page') {
266 - unset($options['submit-'.$section]);
302 + if ('Reset page' === substr($options['submit-' . $section], 0, 10)) {
303 + unset($options['submit-' . $section]);
267 304 // This is a reset for an individual section. So we will unset the child fields.
268 305 foreach ($children as $child) {
269 306 unset($options[$child]);
270 307 }
271 308 }
272 - unset($options['submit-'.$section]);
309 + unset($options['submit-' . $section]);
273 310 }
274 - else if (substr($options['submit-'.$section], 0, 6) == 'Delete') {
275 - return;
311 + elseif ('Delete' === substr($options['submit-' . $section], 0, 6)) {
312 + return [];
276 313 }
277 314 break;
278 315 }
279 316 }
@@ -279,9 +316,9 @@
279 316 }
280 317 return $options;
281 318 }
282 319
283 - function get_option_structure() {
320 + public function get_option_structure() {
284 321 if (isset($this->option_structure)) {
285 322 return $this->option_structure;
286 323 }
287 324 $options = $this->tab_options;
@@ -294,11 +331,19 @@
294 331 $option_structure[$value['category']]['slug'] = $value['category'];
295 332 $option_structure[$value['category']]['name'] = $value['name'];
296 333 $option_structure[$value['category']]['children'] = [];
297 334
298 - if (isset($value['help'])) $option_structure[$value['category']]['help'] = $value['help'];
299 - if (isset($value['buttons'])) $option_structure[$value['category']]['buttons'] = $value['buttons'];
335 + if (isset($value['help'])) {
336 + $option_structure[$value['category']]['help'] = $value['help'];
337 + }
338 + if (isset($value['buttons'])) {
339 + $option_structure[$value['category']]['buttons'] = $value['buttons'];
340 + }
341 + if (isset($value['preface'])) {
342 + $option_structure[$value['category']]['preface'] = $value['preface'];
343 + }
300 344 break;
345 +
301 346 default:
302 347 if (isset($value['id'])) {
303 348 $option_structure[$value['grouping']]['children'][$value['id']] = $value['name'];
304 349 }
@@ -306,22 +351,22 @@
306 351 }
307 352 return $option_structure;
308 353 }
309 354
310 - function add_settings_fields($page) {
355 + private function add_settings_fields($page) {
311 356 $ctr = 0;
312 357 foreach ($this->tab_options as $value) {
313 358 $ctr++;
314 359 switch ($value['type']) {
315 - case "blurb";
316 - add_settings_field($value['grouping'].'-'.$ctr, $value['name'], [&$this, "create_section_for_blurb"], $page, $value['grouping'], $value);
360 + case "blurb":
361 + add_settings_field($value['grouping'] . '-' . $ctr, $value['name'], [&$this, "create_section_for_blurb"], $page, $value['grouping'], $value);
317 362 break;
318 363
319 - case "text";
364 + case "text":
320 365 add_settings_field($value['id'], $value['name'], [&$this, "create_section_for_text"], $page, $value['grouping'], $value);
321 366 break;
322 367
323 - case "textarea";
368 + case "textarea":
324 369 add_settings_field($value['id'], $value['name'], [&$this, "create_section_for_textarea"], $page, $value['grouping'], $value);
325 370 break;
326 371
327 372 case "select":
@@ -335,46 +380,66 @@
335 380 case "radio":
336 381 add_settings_field($value['id'], $value['name'], [&$this, "create_section_for_radio"], $page, $value['grouping'], $value);
337 382 break;
338 383
384 + case "radio-group":
385 + add_settings_field($value['id'], $value['name'], [&$this, "create_section_for_radio_group"], $page, $value['grouping'], $value);
386 + break;
387 +
339 388 case "checkbox":
340 389 add_settings_field($value['id'], $value['name'], [&$this, "create_section_for_checkbox"], $page, $value['grouping'], $value);
341 390 break;
342 391
343 - case "border":
344 - add_settings_field($value['id'], $value['name'], [&$this, "create_section_for_border"], $page, $value['grouping'], $value);
345 - break;
346 -
347 392 case "background":
348 393 add_settings_field($value['id'], $value['name'], [&$this, "create_section_for_background"], $page, $value['grouping'], $value);
349 394 break;
350 -
351 - case "padding":
352 - add_settings_field($value['id'], $value['name'], [&$this, "create_section_for_padding"], $page, $value['grouping'], $value);
353 - break;
354 395 }
355 396 }
356 397 }
357 398
358 - function create_section_for_radio($value) {
359 - global $photonic_options;
399 + public function create_section_for_radio($value) {
360 400 $defaults = Defaults::get_options();
361 401 $this->create_opening_tag($value);
362 402 foreach ($value['options'] as $option_value => $option_text) {
363 - $option_value = stripslashes($option_value);
364 - if (isset($photonic_options[$value['id']])) {
365 - $checked = checked(stripslashes($photonic_options[$value['id']]), $option_value, false);
403 + $this->create_individual_radio_item($value, $option_value, $option_text, $defaults);
404 + }
405 + $this->create_closing_tag();
406 + }
407 +
408 + public function create_section_for_radio_group($value) {
409 + $defaults = Defaults::get_options();
410 + $this->create_opening_tag($value);
411 +
412 + foreach ($value['options'] as $radio_group) {
413 + if (!empty($radio_group['header'])) {
414 + echo "<h4>" . wp_kses_post($radio_group['header']) . "</h4>\n";
366 415 }
367 - else {
368 - $checked = checked($defaults[$value['id']], $option_value, false);
416 + if (!empty($radio_group['description'])) {
417 + echo wp_kses_post($radio_group['description']) . "\n";
369 418 }
370 - echo '<div class="photonic-radio"><label><input type="radio" name="photonic_options['.$value['id'].']" value="'.$option_value.'" '.$checked."/>".$option_text."</label></div>\n";
419 + foreach ($radio_group['options'] as $option_value => $option_text) {
420 + $this->create_individual_radio_item($value, $option_value, $option_text, $defaults);
421 + }
371 422 }
372 - $this->create_closing_tag($value);
423 + $this->create_closing_tag();
373 424 }
374 425
375 - function create_section_for_text($value) {
426 + private function create_individual_radio_item($value, $option_value, $option_text, $defaults) {
376 427 global $photonic_options;
428 + $replacements = Defaults::get_migrated_options();
429 +
430 + if (isset($photonic_options[$value['id']])) {
431 + $check_value = (isset($replacements[$value['id']]) && isset($replacements[$value['id']][$photonic_options[$value['id']]])) ? $replacements[$value['id']][$photonic_options[$value['id']]] : $photonic_options[$value['id']];
432 + $checked = checked($check_value, $option_value, false);
433 + }
434 + else {
435 + $checked = checked($defaults[$value['id']], $option_value, false);
436 + }
437 + echo '<div class="photonic-radio"><label><input type="radio" name="photonic_options[' . esc_attr($value['id']) . ']" value="' . esc_attr($option_value) . '" ' . esc_attr($checked) . "/>" . wp_kses_post($option_text) . "</label></div>\n";
438 + }
439 +
440 + public function create_section_for_text($value) {
441 + global $photonic_options;
377 442 $defaults = Defaults::get_options();
378 443 $this->create_opening_tag($value);
379 444 if (!isset($photonic_options[$value['id']])) {
380 445 $text = $defaults[$value['id']];
@@ -381,63 +446,64 @@
381 446 }
382 447 else {
383 448 $text = $photonic_options[$value['id']];
384 449 $text = stripslashes($text);
385 - $text = esc_attr($text);
386 450 }
387 451
388 - echo '<input type="text" name="photonic_options['.$value['id'].']" value="'.$text.'" />'."\n";
452 + echo '<input type="text" name="photonic_options[' . esc_attr($value['id']) . ']" value="' . esc_attr($text) . '" />' . "\n";
389 453 if (isset($value['hint'])) {
390 - echo "<em> &laquo; ".$value['hint']."<br /></em>\n";
454 + echo "<em> &laquo; " . wp_kses_post($value['hint']) . "<br /></em>\n";
391 455 }
392 - $this->create_closing_tag($value);
456 + $this->create_closing_tag();
393 457 }
394 458
395 - function create_section_for_textarea($value) {
459 + public function create_section_for_textarea($value) {
396 460 global $photonic_options;
397 461 $defaults = Defaults::get_options();
398 462 $this->create_opening_tag($value);
399 - echo '<textarea name="photonic_options['.$value['id'].']" cols="" rows="">'."\n";
400 - if (isset($photonic_options[$value['id']]) && $photonic_options[$value['id']] != "") {
463 + echo '<textarea name="photonic_options[' . esc_attr($value['id']) . ']" cols="" rows="">' . "\n";
464 + if (isset($photonic_options[$value['id']]) && "" !== $photonic_options[$value['id']]) {
401 465 $text = stripslashes($photonic_options[$value['id']]);
402 - $text = esc_attr($text);
403 - echo $text;
404 466 }
405 467 else {
406 - echo $defaults[$value['id']];
468 + $text = $defaults[$value['id']];
407 469 }
470 + echo esc_attr($text);
408 471 echo '</textarea>';
409 472 if (isset($value['hint'])) {
410 - echo " &laquo; ".$value['hint']."<br />\n";
473 + echo "<em> &laquo; " . wp_kses_post($value['hint']) . "<br /></em>\n";
411 474 }
412 - $this->create_closing_tag($value);
475 + $this->create_closing_tag();
413 476 }
414 477
415 - function create_section_for_select($value) {
478 + public function create_section_for_select($value) {
416 479 global $photonic_options;
417 480 $defaults = Defaults::get_options();
481 + $replacements = Defaults::get_migrated_options();
482 +
418 483 $this->create_opening_tag($value);
419 - echo '<select name="photonic_options['.$value['id'].']">'."\n";
484 + echo '<select name="photonic_options[' . esc_attr($value['id']) . ']">' . "\n";
420 485 foreach ($value['options'] as $option_value => $option_text) {
421 486 echo "<option ";
422 487 if (isset($photonic_options[$value['id']])) {
423 - selected($photonic_options[$value['id']], $option_value);
488 + $check_value = (isset($replacements[$value['id']]) && isset($replacements[$value['id']][$photonic_options[$value['id']]])) ? $replacements[$value['id']][$photonic_options[$value['id']]] : $photonic_options[$value['id']];
489 + selected($check_value, $option_value);
424 490 }
425 491 else {
426 492 selected($defaults[$value['id']], $option_value);
427 493 }
428 - echo " value='$option_value' >".$option_text."</option>\n";
494 + echo " value='" . esc_attr($option_value) . "' >" . esc_attr($option_text) . "</option>\n";
429 495 }
430 496 echo "</select>\n";
431 - $this->create_closing_tag($value);
497 + $this->create_closing_tag();
432 498 }
433 499
434 - function create_section_for_multi_select($value) {
500 + public function create_section_for_multi_select($value) {
435 501 global $photonic_options;
436 502 $defaults = Defaults::get_options();
437 503 $this->create_opening_tag($value);
438 - echo '<div class="photonic-checklist">'."\n";
439 - echo '<ul class="photonic-checklist" id="'.$value['id'].'-chk" >'."\n";
504 + echo '<div class="photonic-checklist">' . "\n";
505 + echo '<ul class="photonic-checklist" id="' . esc_attr($value['id']) . '-chk" >' . "\n";
440 506 if (isset($defaults[$value['id']])) {
441 507 $consolidated_value = $defaults[$value['id']];
442 508 }
443 509 if (isset($photonic_options[$value['id']])) {
@@ -447,9 +513,9 @@
447 513 $consolidated_value = "";
448 514 }
449 515 $consolidated_value = trim($consolidated_value);
450 516 $exploded = [];
451 - if ($consolidated_value != '') {
517 + if ('' !== $consolidated_value) {
452 518 $exploded = explode(',', $consolidated_value);
453 519 }
454 520
455 521 foreach ($value['options'] as $option_value => $option_list) {
@@ -456,9 +522,9 @@
456 522 $checked = " ";
457 523 if ($consolidated_value) {
458 524 foreach ($exploded as $checked_value) {
459 525 $checked = checked($checked_value, $option_value, false);
460 - if (trim($checked) != '') {
526 + if ('' !== trim($checked)) {
461 527 break;
462 528 }
463 529 }
464 530 }
@@ -466,9 +532,10 @@
466 532 $depth = 0;
467 533 if (isset($option_list['depth'])) {
468 534 $depth = $option_list['depth'];
469 535 }
470 - echo '<label><input type="checkbox" name="'.$value['id']."_".$option_value.'" value="true" '.$checked.' class="depth-'.($depth+1).' photonic-options-checkbox-'.$value['id'].'" data-photonic-selection-for="'.$value['id'].'" data-photonic-value="'.$option_value.'" />'.$option_list['title']."</label>\n";
536 + echo '<label><input type="checkbox" name="' . esc_attr($value['id']) . "_" . esc_attr($option_value) . '" value="true" ' . esc_attr($checked) . ' class="depth-' . esc_attr($depth + 1) . ' photonic-options-checkbox-' . esc_attr($value['id']) . '" data-photonic-selection-for="' . esc_attr($value['id']) . '" data-photonic-value="' . esc_attr($option_value) . '" />' .
537 + wp_kses_post($option_list['title']) . "</label>\n";
471 538 echo "</li>\n";
472 539 }
473 540 echo "</ul>\n";
474 541
@@ -474,30 +541,33 @@
474 541
475 542 if (isset($photonic_options[$value['id']])) {
476 543 $set_value = $photonic_options[$value['id']];
477 544 }
478 - else if (isset($defaults[$value['id']])) {
545 + elseif (isset($defaults[$value['id']])) {
479 546 $set_value = $defaults[$value['id']];
480 547 }
481 548 else {
482 549 $set_value = "";
483 550 }
484 - echo '<input type="hidden" name="photonic_options['.$value['id'].']" id="'.$value['id'].'" value="'.$set_value.'"/>'."\n";
551 + echo '<input type="hidden" name="photonic_options[' . esc_attr($value['id']) . ']" id="' . esc_attr($value['id']) . '" value="' . esc_attr($set_value) . '"/>' . "\n";
485 552 echo "</div>\n";
486 - $this->create_closing_tag($value);
553 + $this->create_closing_tag();
487 554 }
488 555
489 - function create_settings_section($section) {
556 + public function create_settings_section($section) {
490 557 $option_structure = $this->option_structure;
491 - if ($this->displayed_sections != 0) {
558 + if (0 !== $this->displayed_sections) {
492 559 $this->show_buttons($this->previous_displayed_section, $option_structure[$this->previous_displayed_section]);
493 560 echo "</form>\n";
494 561 echo "</div><!-- /photonic-options-panel -->\n";
495 562 }
496 563
497 - echo "<div id='{$section['id']}' class='photonic-options-panel'> \n";
498 - echo "<form method=\"post\" action=\"options.php\" id=\"photonic-options-form-{$section['id']}\" class='photonic-options-form'>\n";
499 - echo '<h3>' . $option_structure[$section['id']]['name'] . "</h3>\n";
564 + echo "<div id='" . esc_attr($section['id']) . "' class='photonic-options-panel'> \n";
565 + echo "<form method=\"post\" action=\"options.php\" id=\"photonic-options-form-" . esc_attr($section['id']) . "\" class='photonic-options-form'>\n";
566 + if (!empty($option_structure[$section['id']]['preface'])) {
567 + echo wp_kses_post($option_structure[$section['id']]['preface']);
568 + }
569 + echo '<h3>' . wp_kses_post($option_structure[$section['id']]['name']) . "</h3>\n";
500 570
501 571 /*
502 572 * We store all options in one array, but display them across multiple pages. Hence we need the following hack.
503 573 * We are registering the same setting across multiple pages, hence we need to pass the "page" parameter to options.php.
@@ -502,16 +572,16 @@
502 572 * We store all options in one array, but display them across multiple pages. Hence we need the following hack.
503 573 * We are registering the same setting across multiple pages, hence we need to pass the "page" parameter to options.php.
504 574 * Otherwise options.php returns an error saying "Options page not found"
505 575 */
506 - echo "<input type='hidden' name='page' value='" . esc_attr($_REQUEST['page']) . "' />\n";
507 - if (!isset($_REQUEST['tab'])) {
508 - $tab = 'theme-options-intro.php';
576 + echo "<input type='hidden' name='page' value='" . esc_attr(sanitize_text_field($_REQUEST['page'] ?? '')) . "' />\n"; // phpcs:ignore WordPress.Security.NonceVerification
577 + if (!isset($_REQUEST['tab'])) { // phpcs:ignore WordPress.Security.NonceVerification
578 + $tab = 'Generic.php';
509 579 }
510 580 else {
511 - $tab = esc_attr($_REQUEST['tab']);
581 + $tab = sanitize_text_field($_REQUEST['tab']); // phpcs:ignore WordPress.Security.NonceVerification
512 582 }
513 - echo "<input type='hidden' name='tab' value='" . $tab . "' />\n";
583 + echo "<input type='hidden' name='tab' value='" . esc_attr($tab) . "' />\n";
514 584
515 585 settings_fields("photonic_options-{$section['id']}");
516 586 $this->displayed_sections++;
517 587 $this->previous_displayed_section = $section['id'];
@@ -516,11 +586,11 @@
516 586 $this->displayed_sections++;
517 587 $this->previous_displayed_section = $section['id'];
518 588 }
519 589
520 - function create_section_for_blurb($value) {
590 + public function create_section_for_blurb($value) {
521 591 $this->create_opening_tag($value);
522 - $this->create_closing_tag($value);
592 + $this->create_closing_tag();
523 593 }
524 594
525 595 /**
526 596 * Renders an option whose type is "checkbox". Invoked by add_settings_field.
@@ -527,169 +597,26 @@
527 597 *
528 598 * @param $value
529 599 * @return void
530 600 */
531 - function create_section_for_checkbox($value) {
601 + public function create_section_for_checkbox($value) {
532 602 global $photonic_options;
533 603 $checked = '';
534 604 if (isset($photonic_options[$value['id']])) {
535 - $checked = checked(stripslashes($photonic_options[$value['id']]), 'on', false);
605 + $checked = checked(esc_attr($photonic_options[$value['id']]), 'on', false);
536 606 }
537 607 $this->create_opening_tag($value);
538 - echo '<label><input type="checkbox" name="photonic_options['.$value['id'].']" '.$checked."/>{$value['desc']}</label>\n";
539 - $this->create_closing_tag($value);
608 + echo '<label><input type="checkbox" name="photonic_options[' . esc_attr($value['id']) . ']" ' . esc_attr($checked) . "/>" . wp_kses_post($value['desc']) . "</label>\n";
609 + $this->create_closing_tag();
540 610 }
541 611
542 612 /**
543 - * Renders an option whose type is "border". Invoked by add_settings_field.
544 - *
545 - * @param $value
546 - * @return void
547 - */
548 - function create_section_for_border($value) {
549 - global $photonic_options;
550 - $defaults = Defaults::get_options();
551 - $this->create_opening_tag($value);
552 - $original = $defaults[$value['id']];
553 - if (!isset($photonic_options[$value['id']])) {
554 - $default = $defaults[$value['id']];
555 - $default_txt = "";
556 - foreach ($default as $edge => $edge_val) {
557 - $default_txt .= $edge.'::';
558 - foreach ($edge_val as $opt => $opt_val) {
559 - $default_txt .= $opt . "=" . $opt_val . ";";
560 - }
561 - $default_txt .= "||";
562 - }
563 - }
564 - else {
565 - $default_txt = $photonic_options[$value['id']];
566 - $default = $default_txt;
567 - $edge_array = explode('||', $default);
568 - $default = [];
569 - if (is_array($edge_array)) {
570 - foreach ($edge_array as $edge_vals) {
571 - if (trim($edge_vals) != '') {
572 - $edge_val_array = explode('::', $edge_vals);
573 - if (is_array($edge_val_array) && count($edge_val_array) > 1) {
574 - $vals = explode(';', $edge_val_array[1]);
575 - $default[$edge_val_array[0]] = [];
576 - foreach ($vals as $val) {
577 - $pair = explode("=", $val);
578 - if (isset($pair[0]) && isset($pair[1])) {
579 - $default[$edge_val_array[0]][$pair[0]] = $pair[1];
580 - }
581 - else if (isset($pair[0]) && !isset($pair[1])) {
582 - $default[$edge_val_array[0]][$pair[0]] = "";
583 - }
584 - }
585 - }
586 - }
587 - }
588 - }
589 - }
590 - $edges = ['top' => 'Top', 'right' => 'Right', 'bottom' => 'Bottom', 'left' => 'Left'];
591 - $styles = ["none" => "No border",
592 - "hidden" => "Hidden",
593 - "dotted" => "Dotted",
594 - "dashed" => "Dashed",
595 - "solid" => "Solid",
596 - "double" => "Double",
597 - "grove" => "Groove",
598 - "ridge" => "Ridge",
599 - "inset" => "Inset",
600 - "outset" => "Outset"];
601 -
602 - $border_width_units = ["px" => "Pixels (px)", "em" => "Em"];
603 -
604 - foreach ($value['options'] as $option_value => $option_text) {
605 - if (isset($photonic_options[$value['id']])) {
606 - $checked = checked($photonic_options[$value['id']], $option_value, false);
607 - }
608 - else {
609 - $checked = checked($defaults[$value['id']], $option_value, false);
610 - }
611 - echo '<div class="photonic-radio"><input type="radio" name="'.$value['id'].'" value="'.$option_value.'" '.$checked."/>".$option_text."</div>\n";
612 - }
613 - ?>
614 - <div class='photonic-border-options'>
615 - <p>For any edge set style to "No Border" if you don't want a border.</p>
616 - <table class='opt-sub-table-5'>
617 - <col class='opt-sub-table-col-51'/>
618 - <col class='opt-sub-table-col-5'/>
619 - <col class='opt-sub-table-col-5'/>
620 - <col class='opt-sub-table-col-5'/>
621 - <col class='opt-sub-table-col-5'/>
622 -
623 - <tr>
624 - <th scope="col">&nbsp;</th>
625 - <th scope="col">Border Style</th>
626 - <th scope="col">Color</th>
627 - <th scope="col">Border Width</th>
628 - <th scope="col">Border Width Units</th>
629 - </tr>
630 -
631 - <?php
632 - foreach ($edges as $edge => $edge_text) {
633 - ?>
634 - <tr>
635 - <th scope="row"><?php echo $edge_text; ?></th>
636 - <td valign='top'>
637 - <select name="<?php echo $value['id'].'-'.$edge; ?>-style" id="<?php echo $value['id'].'-'.$edge; ?>-style" >
638 - <?php
639 - foreach ($styles as $option_value => $option_text) {
640 - echo "<option ";
641 - if (isset($default[$edge]) && isset($default[$edge]['style'])) {
642 - selected($default[$edge]['style'], $option_value);
643 - }
644 - echo " value='$option_value' >".$option_text."</option>\n";
645 - }
646 - ?>
647 - </select>
648 - </td>
649 -
650 - <td valign='top'>
651 - <div class="color-picker-group">
652 - <input type="radio" name="<?php echo $value['id'].'-'.$edge; ?>-colortype" value="transparent" <?php checked($default[$edge]['colortype'], 'transparent'); ?> /> Transparent / No color<br/>
653 - <input type="radio" name="<?php echo $value['id'].'-'.$edge; ?>-colortype" value="custom" <?php checked($default[$edge]['colortype'], 'custom'); ?>/> Custom
654 - <input type="text" id="<?php echo $value['id'].'-'.$edge; ?>-color" name="<?php echo $value['id']; ?>-color" value="<?php echo $default[$edge]['color']; ?>" data-photonic-default-color="<?php echo $original[$edge]['color']; ?>" class="color" /><br />
655 - Default: <span> <?php echo $original[$edge]['color']; ?> </span>
656 - </div>
657 - </td>
658 -
659 - <td valign='top'>
660 - <input type="text" id="<?php echo $value['id'].'-'.$edge; ?>-border-width" name="<?php echo $value['id'].'-'.$edge; ?>-border-width" value="<?php echo $default[$edge]['border-width']; ?>" /><br />
661 - </td>
662 -
663 - <td valign='top'>
664 - <select name="<?php echo $value['id'].'-'.$edge; ?>-border-width-type" id="<?php echo $value['id'].'-'.$edge; ?>-border-width-type" >
665 - <?php
666 - foreach ($border_width_units as $option_value => $option_text) {
667 - echo "<option ";
668 - selected($default[$edge]['border-width-type'], $option_value);
669 - echo " value='$option_value' >".$option_text."</option>\n";
670 - }
671 - ?>
672 - </select>
673 - </td>
674 - </tr>
675 - <?php
676 - }
677 - ?>
678 - </table>
679 - <input type='hidden' id="<?php echo $value['id']; ?>" name="photonic_options[<?php echo $value['id']; ?>]" value="<?php echo $default_txt; ?>" />
680 - </div>
681 - <?php
682 - $this->create_closing_tag($value);
683 - }
684 -
685 - /**
686 613 * Renders an option whose type is "background". Invoked by add_settings_field.
687 614 *
688 615 * @param $value
689 616 * @return void
690 617 */
691 - function create_section_for_background($value) {
618 + public function create_section_for_background($value) {
692 619 global $photonic_options;
693 620 $defaults = Defaults::get_options();
694 621
695 622 $this->create_opening_tag($value);
@@ -697,9 +624,9 @@
697 624 if (!isset($photonic_options[$value['id']])) {
698 625 $default = $defaults[$value['id']];
699 626 $default_txt = "";
700 627 foreach ($defaults[$value['id']] as $opt => $opt_val) {
701 - $default_txt .= $opt."=".$opt_val.";";
628 + $default_txt .= $opt . "=" . $opt_val . ";";
702 629 }
703 630 }
704 631 else {
705 632 $default_txt = $photonic_options[$value['id']];
@@ -710,27 +637,31 @@
710 637 $pair = explode("=", $val);
711 638 if (isset($pair[0]) && isset($pair[1])) {
712 639 $default[$pair[0]] = $pair[1];
713 640 }
714 - else if (isset($pair[0]) && !isset($pair[1])) {
641 + elseif (isset($pair[0]) && !isset($pair[1])) {
715 642 $default[$pair[0]] = "";
716 643 }
717 644 }
718 645 }
719 - $repeats = ["repeat" => "Repeat horizontally and vertically",
720 - "repeat-x" => "Repeat horizontally only",
721 - "repeat-y" => "Repeat vertically only",
722 - "no-repeat" => "Do not repeat"];
646 + $repeats = [
647 + "repeat" => "Repeat horizontally and vertically",
648 + "repeat-x" => "Repeat horizontally only",
649 + "repeat-y" => "Repeat vertically only",
650 + "no-repeat" => "Do not repeat"
651 + ];
723 652
724 - $positions = ["top left" => "Top left",
725 - "top center" => "Top center",
726 - "top right" => "Top right",
727 - "center left" => "Center left",
653 + $positions = [
654 + "top left" => "Top left",
655 + "top center" => "Top center",
656 + "top right" => "Top right",
657 + "center left" => "Center left",
728 658 "center center" => "Middle of the page",
729 - "center right" => "Center right",
730 - "bottom left" => "Bottom left",
659 + "center right" => "Center right",
660 + "bottom left" => "Bottom left",
731 661 "bottom center" => "Bottom center",
732 - "bottom right" => "Bottom right"];
662 + "bottom right" => "Bottom right"
663 + ];
733 664
734 665 foreach ($value['options'] as $option_value => $option_text) {
735 666 if (isset($photonic_options[$value['id']])) {
736 667 $checked = checked($photonic_options[$value['id']], $option_value, false);
@@ -737,186 +668,99 @@
737 668 }
738 669 else {
739 670 $checked = checked($defaults[$value['id']], $option_value, false);
740 671 }
741 - echo '<div class="photonic-radio"><input type="radio" name="'.$value['id'].'" value="'.$option_value.'" '.$checked."/>".$option_text."</div>\n";
672 + echo '<div class="photonic-radio"><input type="radio" name="' . esc_attr($value['id']) . '" value="' . esc_attr($option_value) . '" ' . esc_attr($checked) . "/>" . wp_kses_post($option_text) . "</div>\n";
742 673 }
743 - ?>
674 + ?>
744 675 <div class='photonic-background-options'>
745 - <table class='opt-sub-table'>
746 - <colgroup>
747 - <col class='opt-sub-table-cols'/>
748 - <col class='opt-sub-table-cols'/>
749 - </colgroup>
750 - <tr>
751 - <td valign='top'>
752 - <div class="color-picker-group">
753 - <strong>Background Color:</strong><br />
754 - <label><input type="radio" name="<?php echo $value['id']; ?>-colortype" value="transparent" <?php checked($default['colortype'], 'transparent'); ?> /> Transparent / No color</label><br/>
755 - <label><input type="radio" name="<?php echo $value['id']; ?>-colortype" value="custom" <?php checked($default['colortype'], 'custom'); ?>/> Custom</label>
756 - <input type="text" id="<?php echo $value['id']; ?>-bgcolor" name="<?php echo $value['id']; ?>-bgcolor" value="<?php echo $default['color']; ?>" data-photonic-default-color="<?php echo $original['color']; ?>" class="color" /><br />
757 - Default: <span> <?php echo $original['color']; ?> </span>
758 - </div>
759 - </td>
760 - <td valign='top'>
761 - <strong>Image URL:</strong><br />
762 - <?php $this->display_upload_field($default['image'], $value['id']."-bgimg", $value['id']."-bgimg"); ?>
763 - </td>
764 - </tr>
676 + <table class='opt-sub-table'>
677 + <colgroup>
678 + <col class='opt-sub-table-cols'/>
679 + <col class='opt-sub-table-cols'/>
680 + </colgroup>
681 + <tr>
682 + <td style='vertical-align: top'>
683 + <div class="color-picker-group">
684 + <strong>Background Color:</strong><br/>
685 + <label><input type="radio" name="<?php echo esc_attr($value['id']); ?>-colortype"
686 + value="transparent" <?php checked($default['colortype'], 'transparent'); ?> />
687 + Transparent / No color</label><br/>
688 + <label><input type="radio" name="<?php echo esc_attr($value['id']); ?>-colortype"
689 + value="custom" <?php checked($default['colortype'], 'custom'); ?>/>
690 + Custom</label>
691 + <input type="text" id="<?php echo esc_attr($value['id']); ?>-bgcolor"
692 + name="<?php echo esc_attr($value['id']); ?>-bgcolor" value="<?php echo esc_attr($default['color']); ?>"
693 + data-photonic-default-color="<?php echo esc_attr($original['color']); ?>" class="color"/><br/>
694 + Default: <span> <?php echo esc_attr($original['color']); ?> </span>
695 + </div>
696 + </td>
697 + <td style='vertical-align: top'>
698 + <strong>Image URL:</strong><br/>
699 + <?php $this->display_upload_field($default['image'], $value['id'] . "-bgimg", $value['id'] . "-bgimg"); ?>
700 + </td>
701 + </tr>
765 702
766 - <tr>
767 - <td valign='top'>
768 - <strong>Image Position:</strong><br />
769 - <select name="<?php echo $value['id']; ?>-position" id="<?php echo $value['id']; ?>-position" >
770 - <?php
771 - foreach ($positions as $option_value => $option_text) {
772 - echo "<option ";
773 - selected($default['position'], $option_value);
774 - echo " value='$option_value' >".$option_text."</option>\n";
775 - }
776 - ?>
777 - </select>
778 - </td>
779 -
780 - <td valign='top'>
781 - <strong>Image Repeat:</strong><br />
782 - <select name="<?php echo $value['id']; ?>-repeat" id="<?php echo $value['id']; ?>-repeat" >
783 - <?php
784 - foreach ($repeats as $option_value => $option_text) {
785 - echo "<option ";
786 - selected($default['repeat'], $option_value);
787 - echo " value='$option_value' >".$option_text."</option>\n";
788 - }
789 - ?>
790 - </select>
791 - </td>
792 - </tr>
793 - <tr>
794 - <td valign='top' colspan='2'>
795 - <div class='slider'>
796 - <p>
797 - <strong>Layer Transparency (not for IE):</strong>
798 - <select id="<?php echo $value['id']; ?>-trans" name="<?php echo $value['id']; ?>-trans">
703 + <tr>
704 + <td style='vertical-align: top'>
705 + <label>
706 + <strong>Image Position:</strong><br/>
707 + <select name="<?php echo esc_attr($value['id']); ?>-position"
708 + id="<?php echo esc_attr($value['id']); ?>-position">
799 709 <?php
800 - for ($i = 0; $i <= 100; $i++) {
710 + foreach ($positions as $option_value => $option_text) {
801 711 echo "<option ";
802 - selected($default['trans'], $i);
803 - echo " value='$i' >".$i."</option>\n";
712 + selected($default['position'], $option_value);
713 + echo " value='" . esc_attr($option_value) . "' >" . esc_attr($option_text) . "</option>\n";
804 714 }
805 715 ?>
806 716 </select>
807 - </p>
808 - </div>
809 - </td>
810 - </tr>
811 - </table>
812 - <input type='hidden' id="<?php echo $value['id']; ?>" name="photonic_options[<?php echo $value['id']; ?>]" value="<?php echo $default_txt; ?>" />
813 - </div>
814 - <?php
815 - $this->create_closing_tag($value);
816 - }
717 + </label>
718 + </td>
817 719
818 - /**
819 - * Renders an option whose type is "background". Invoked by add_settings_field.
820 - *
821 - * @param $value
822 - * @return void
823 - */
824 - function create_section_for_padding($value) {
825 - global $photonic_options;
826 - $defaults = Defaults::get_options();
827 - $this->create_opening_tag($value);
828 - if (!isset($photonic_options[$value['id']])) {
829 - $default = $defaults[$value['id']];
830 - $default_txt = "";
831 - foreach ($default as $edge => $edge_val) {
832 - $default_txt .= $edge.'::';
833 - foreach ($edge_val as $opt => $opt_val) {
834 - $default_txt .= $opt . "=" . $opt_val . ";";
835 - }
836 - $default_txt .= "||";
837 - }
838 - }
839 - else {
840 - $default_txt = $photonic_options[$value['id']];
841 - $default = $default_txt;
842 - $edge_array = explode('||', $default);
843 - $default = [];
844 - if (is_array($edge_array)) {
845 - foreach ($edge_array as $edge_vals) {
846 - if (trim($edge_vals) != '') {
847 - $edge_val_array = explode('::', $edge_vals);
848 - if (is_array($edge_val_array) && count($edge_val_array) > 1) {
849 - $vals = explode(';', $edge_val_array[1]);
850 - $default[$edge_val_array[0]] = [];
851 - foreach ($vals as $val) {
852 - $pair = explode("=", $val);
853 - if (isset($pair[0]) && isset($pair[1])) {
854 - $default[$edge_val_array[0]][$pair[0]] = $pair[1];
720 + <td style='vertical-align: top'>
721 + <label>
722 + <strong>Image Repeat:</strong><br/>
723 + <select name="<?php echo esc_attr($value['id']); ?>-repeat"
724 + id="<?php echo esc_attr($value['id']); ?>-repeat">
725 + <?php
726 + foreach ($repeats as $option_value => $option_text) {
727 + echo "<option ";
728 + selected($default['repeat'], $option_value);
729 + echo " value='" . esc_attr($option_value) . "' >" . esc_attr($option_text) . "</option>\n";
855 730 }
856 - else if (isset($pair[0]) && !isset($pair[1])) {
857 - $default[$edge_val_array[0]][$pair[0]] = "";
858 - }
859 - }
860 - }
861 - }
862 - }
863 - }
864 - }
865 - $edges = ['top' => 'Top', 'right' => 'Right', 'bottom' => 'Bottom', 'left' => 'Left'];
866 - $padding_units = ["px" => "Pixels (px)", "em" => "Em"];
867 -
868 - foreach ($value['options'] as $option_value => $option_text) {
869 - if (isset($photonic_options[$value['id']])) {
870 - $checked = checked($photonic_options[$value['id']], $option_value, false);
871 - }
872 - else {
873 - $checked = checked($defaults[$value['id']], $option_value, false);
874 - }
875 - echo '<div class="photonic-radio"><input type="radio" name="'.$value['id'].'" value="'.$option_value.'" '.$checked."/>".$option_text."</div>\n";
876 - }
877 - ?>
878 - <div class='photonic-padding-options'>
879 - <table class='opt-sub-table-5'>
880 - <col class='opt-sub-table-col-51'/>
881 - <col class='opt-sub-table-col-5'/>
882 - <col class='opt-sub-table-col-5'/>
883 -
731 + ?>
732 + </select>
733 + </label>
734 + </td>
735 + </tr>
884 736 <tr>
885 - <th scope="col">&nbsp;</th>
886 - <th scope="col">Padding</th>
887 - <th scope="col">Padding Units</th>
737 + <td style='vertical-align: top' colspan='2'>
738 + <div class='slider'>
739 + <p>
740 + <label>
741 + <strong>Layer Transparency (not for IE):</strong>
742 + <select id="<?php echo esc_attr($value['id']); ?>-trans"
743 + name="<?php echo esc_attr($value['id']); ?>-trans">
744 + <?php
745 + for ($i = 0; $i <= 100; $i++) {
746 + ?>
747 + <option <?php echo selected($default['trans'], $i); ?> value="<?php echo esc_attr($i); ?>" ><?php echo esc_html($i); ?></option>
748 + <?php
749 + }
750 + ?>
751 + </select>
752 + </label>
753 + </p>
754 + </div>
755 + </td>
888 756 </tr>
889 -
890 - <?php
891 - foreach ($edges as $edge => $edge_text) {
892 - ?>
893 - <tr>
894 - <th scope="row"><?php echo $edge_text; ?></th>
895 - <td valign='top'>
896 - <input type="text" id="<?php echo $value['id'].'-'.$edge; ?>-padding" name="<?php echo $value['id'].'-'.$edge; ?>-padding" value="<?php echo $default[$edge]['padding']; ?>" /><br />
897 - </td>
898 -
899 - <td valign='top'>
900 - <select name="<?php echo $value['id'].'-'.$edge; ?>-padding-type" id="<?php echo $value['id'].'-'.$edge; ?>-padding-type" >
901 - <?php
902 - foreach ($padding_units as $option_value => $option_text) {
903 - echo "<option ";
904 - selected($default[$edge]['padding-type'], $option_value);
905 - echo " value='$option_value' >".$option_text."</option>\n";
906 - }
907 - ?>
908 - </select>
909 - </td>
910 - </tr>
911 - <?php
912 - }
913 - ?>
914 757 </table>
915 - <input type='hidden' id="<?php echo $value['id']; ?>" name="photonic_options[<?php echo $value['id']; ?>]" value="<?php echo $default_txt; ?>" />
758 + <input type='hidden' id="<?php echo esc_attr($value['id']); ?>" name="photonic_options[<?php echo esc_attr($value['id']); ?>]"
759 + value="<?php echo esc_attr($default_txt); ?>"/>
916 760 </div>
917 - <?php
918 - $this->create_closing_tag($value);
761 + <?php
762 + $this->create_closing_tag();
919 763 }
920 764
921 765 /**
922 766 * Creates the opening markup for each option.
@@ -923,15 +767,15 @@
923 767 *
924 768 * @param $value
925 769 * @return void
926 770 */
927 - function create_opening_tag($value) {
771 + public function create_opening_tag($value) {
928 772 echo "<div class='photonic-section fix'>\n";
929 - if (isset($value['desc']) && $value['type'] != 'checkbox') {
930 - echo $value['desc']."<br />";
773 + if (isset($value['desc']) && 'checkbox' !== $value['type']) {
774 + echo wp_kses_post($value['desc']) . "<br />";
931 775 }
932 776 if (isset($value['note'])) {
933 - echo "<span class=\"note\">".$value['note']."</span><br />";
777 + echo "<span class=\"note\">" . wp_kses_post($value['note']) . "</span><br />";
934 778 }
935 779 }
936 780
937 781 /**
@@ -936,12 +780,11 @@
936 780
937 781 /**
938 782 * Creates the closing markup for each option.
939 783 *
940 - * @param $value
941 784 * @return void
942 785 */
943 - function create_closing_tag($value) {
786 + public function create_closing_tag() {
944 787 echo "</div><!-- photonic-section -->\n";
945 788 }
946 789
947 790 /**
@@ -953,12 +796,12 @@
953 796 * @param $name
954 797 * @param null $hint
955 798 * @return void
956 799 */
957 - function display_upload_field($upload, $id, $name, $hint = null) {
958 - echo '<input type="text" name="'.$name.'" id="'.$id.'" value="'.$upload.'" />'."\n";
959 - if ($hint != null) {
960 - echo "<em> &laquo; ".$hint."<br /></em>\n";
800 + private function display_upload_field($upload, $id, $name, $hint = null) {
801 + echo '<input type="text" name="' . esc_attr($name) . '" id="' . esc_attr($id) . '" value="' . esc_attr($upload) . '" />' . "\n";
802 + if (null !== $hint) {
803 + echo "<em> &laquo; " . wp_kses_post($hint) . "<br /></em>\n";
961 804 }
962 805 }
963 806
964 807 /**
@@ -966,15 +809,16 @@
966 809 *
967 810 * @param $custom_css
968 811 * @return bool
969 812 */
970 - function save_css_to_file($custom_css) {
971 - if(!isset($_GET['settings-updated'])) {
813 + public function save_css_to_file($custom_css): bool {
814 + if (!isset($_GET['settings-updated'])) { // phpcs:ignore WordPress.Security.NonceVerification
972 815 return false;
973 816 }
974 817
975 818 $url = wp_nonce_url('admin.php?page=photonic-options-manager');
976 - if (false === ($creds = request_filesystem_credentials($url, '', false, false))) {
819 + $creds = request_filesystem_credentials($url, '', false, false);
820 + if (false === $creds) {
977 821 return true;
978 822 }
979 823
980 824 if (!WP_Filesystem($creds)) {
@@ -985,14 +829,14 @@
985 829 /** @var $wp_filesystem \WP_Filesystem_Base */
986 830 global $wp_filesystem;
987 831 if (!is_dir(PHOTONIC_UPLOAD_DIR)) {
988 832 if (!$wp_filesystem->mkdir(PHOTONIC_UPLOAD_DIR)) {
989 - echo "<div class='error'><p>Failed to create directory ".PHOTONIC_UPLOAD_DIR.". Please check your folder permissions.</p></div>";
833 + echo "<div class='error'><p>Failed to create directory " . esc_attr(PHOTONIC_UPLOAD_DIR) . ". Please check your folder permissions.</p></div>";
990 834 return false;
991 835 }
992 836 }
993 837
994 - $filename = trailingslashit(PHOTONIC_UPLOAD_DIR).'custom-styles.css';
838 + $filename = trailingslashit(PHOTONIC_UPLOAD_DIR) . 'custom-styles.css';
995 839
996 840 if (empty($custom_css)) {
997 841 return false;
998 842 }
@@ -997,9 +841,9 @@
997 841 return false;
998 842 }
999 843
1000 844 if (!$wp_filesystem->put_contents($filename, $custom_css, FS_CHMOD_FILE)) {
1001 - echo "<div class='error'><p>Failed to save file $filename. Please check your folder permissions.</p></div>";
845 + echo wp_kses_post("<div class='error'><p>Failed to save file $filename. Please check your folder permissions.</p></div>");
1002 846 return false;
1003 847 }
1004 848 return true;
1005 849 }