PluginProbe
CryptX / 3.5.2
CryptX v3.5.2
4.2.1 4.2.0 4.1.1 trunk 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.9 2.0 2.1 2.2 2.3 2.3.1 2.3.2 2.3.3 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 All 93 releases
cryptx / classes / CryptXSettingsTabs.php

CryptXSettingsTabs.php in CryptX 3.5.2, at classes/CryptXSettingsTabs.php

468 lines 12.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace CryptX;
4
5 use CryptX\Admin\ChangelogSettingsTab;
6 use CryptX\Admin\GeneralSettingsTab;
7 use CryptX\Admin\PresentationSettingsTab;
8 use CryptX\Util\DataSanitizer;
9
10 /**
11 * Class CryptXSettingsTabs
12 * Handles the settings tabs functionality for the CryptX plugin admin interface
13 */
14 class CryptXSettingsTabs
15 {
16 /**
17 * WordPress hook name for the CryptX settings page
18 */
19 private const SETTINGS_PAGE_HOOK = 'settings_page_cryptx';
20
21 /**
22 * @var array List of allowed tabs
23 */
24 private array $allowedTabs = ['general', 'presentation', 'howto', 'changelog'];
25
26 /**
27 * @var string Current active tab
28 */
29 private string $activeTab;
30
31 /**
32 * @var CryptX Instance of the main CryptX class
33 */
34 private CryptX $cryptX;
35
36 /**
37 * CryptXSettingsTabs constructor.
38 *
39 * @param CryptX $cryptX Instance of the main CryptX class
40 */
41 public function __construct(CryptX $cryptX)
42 {
43 $this->cryptX = $cryptX;
44 $this->activeTab = $this->determineActiveTab();
45 $this->initHooks();
46 }
47
48 private function initHooks(): void
49 {
50 // Add menu registration hook
51 if (is_admin()) {
52 add_action('admin_menu', [$this, 'registerSettingsMenu']);
53 }
54
55 // Existing hooks
56 add_action('admin_enqueue_scripts', [$this, 'enqueueAdminAssets']);
57 add_action('rw_cryptx_settings_tab', [$this, 'renderTabNavigation']);
58 add_action('rw_cryptx_settings_content', [$this, 'renderTabContent']);
59 }
60
61 /**
62 * Enqueues necessary CSS and JavaScript assets for the CryptX admin settings page.
63 *
64 * @param string $hook The current admin page hook suffix.
65 * @return void
66 */
67 public function enqueueAdminAssets(string $hook): void
68 {
69 if ($hook !== self::SETTINGS_PAGE_HOOK) {
70 return;
71 }
72
73 // Enqueue CSS files with version for cache busting
74 wp_enqueue_style(
75 'cryptx-admin-css',
76 CRYPTX_DIR_URL . 'css/admin.css',
77 [],
78 CRYPTX_VERSION
79 );
80
81 wp_enqueue_style('wp-color-picker');
82
83 // Enqueue JavaScript files
84 wp_enqueue_script(
85 'cryptx-admin-js',
86 CRYPTX_DIR_URL . 'js/cryptx-admin.min.js',
87 ['jquery', 'wp-color-picker'],
88 CRYPTX_VERSION,
89 true
90 );
91
92 wp_enqueue_media();
93 }
94
95 /**
96 * Register the CryptX settings menu
97 */
98 public function registerSettingsMenu(): void
99 {
100 add_submenu_page(
101 'options-general.php',
102 _x('CryptX', 'CryptX settings page', 'cryptx'),
103 _x('CryptX', 'CryptX settings menu', 'cryptx'),
104 'manage_options',
105 'cryptx',
106 [$this, 'renderSettingsPage']
107 );
108 }
109
110 /**
111 * Render the settings page
112 */
113 public function renderSettingsPage(): void
114 {
115 if (!current_user_can('manage_options')) {
116 wp_die(__('You do not have sufficient permissions to access this page.'));
117 }
118
119 $this->handleFormSubmission();
120 $this->renderSettingsPageHtml();
121 }
122
123 /**
124 * Handle form submission
125 */
126 private function handleFormSubmission(): void
127 {
128 if (!empty($_POST['cryptX_var'])) {
129 if (!check_admin_referer('cryptX')) {
130 wp_die(__('Security check failed'));
131 }
132
133 $saveOptions = DataSanitizer::sanitize($_POST['cryptX_var']);
134
135 if (isset($_POST['cryptX_var_reset'])) {
136 $saveOptions = $this->cryptX->getCryptXOptionsDefaults();
137 }
138
139 if (isset($_POST['cryptX_save_general_settings'])) {
140 $saveOptions = $this->parseGeneralSettings($saveOptions);
141 }
142
143 $this->cryptX->saveCryptXOptions($saveOptions);
144 $this->displaySuccessMessage();
145 }
146 }
147
148
149 /**
150 * Parse general settings
151 */
152 private function parseGeneralSettings(array $saveOptions): array
153 {
154 $checkboxes = [
155 'the_content' => 0,
156 'the_meta_key' => 0,
157 'the_excerpt' => 0,
158 'comment_text' => 0,
159 'widget_text' => 0,
160 'autolink' => 0,
161 'metaBox' => 0,
162 ];
163
164 return wp_parse_args($saveOptions, $checkboxes);
165 }
166
167 /**
168 * Display success message
169 */
170 private function displaySuccessMessage(): void
171 {
172 add_settings_error(
173 'cryptx_messages',
174 'cryptx_message',
175 __('Settings saved.'),
176 'updated'
177 );
178 }
179
180 /**
181 * Render the settings page HTML
182 */
183 private function renderSettingsPageHtml(): void
184 {
185 ?>
186 <div class="cryptx-option-page">
187 <h1><?php _e("CryptX settings", 'cryptx'); ?></h1>
188 <form method="post" action="">
189 <?php
190 wp_nonce_field('cryptX');
191 settings_errors('cryptx_messages');
192 ?>
193 <h2 class="nav-tab-wrapper">
194 <?php do_action('rw_cryptx_settings_tab'); ?>
195 </h2>
196 <div class="cryptx-tab-content-wrapper">
197 <?php do_action('rw_cryptx_settings_content'); ?>
198 </div>
199 </form>
200 </div>
201 <?php
202 }
203
204 /**
205 * Determine the active tab from GET parameters
206 *
207 * @return string
208 */
209 private function determineActiveTab(): string
210 {
211 $tab = $_GET['tab'] ?? 'general';
212 return in_array($tab, $this->allowedTabs) ? $tab : 'general';
213 }
214
215 /**
216 * Get the current active tab
217 *
218 * @return string
219 */
220 public function getActiveTab(): string
221 {
222 return $this->activeTab;
223 }
224
225 /**
226 * Render the tab navigation
227 */
228 public function renderTabNavigation(): void
229 {
230 $tabs = [
231 'general' => __('General', 'cryptx'),
232 'presentation' => __('Presentation', 'cryptx'),
233 'howto' => __('How to&hellip;', 'cryptx'),
234 'changelog' => __('Changelog', 'cryptx')
235 ];
236
237 foreach ($tabs as $tab => $label) {
238 $this->renderTabLink($tab, $label);
239 }
240 }
241
242 /**
243 * Render individual tab link
244 *
245 * @param string $tab Tab identifier
246 * @param string $label Tab label
247 */
248 private function renderTabLink(string $tab, string $label): void
249 {
250 $isActive = $this->activeTab === $tab || ($this->activeTab === '' && $tab === 'general');
251 $activeClass = $isActive ? 'nav-tab-active' : '';
252 $url = admin_url('options-general.php?page=' . CRYPTX_BASEFOLDER . '&tab=' . $tab);
253
254 printf(
255 '<a class="nav-tab %s" href="%s">%s</a>',
256 esc_attr($activeClass),
257 esc_url($url),
258 esc_html($label)
259 );
260 }
261
262 /**
263 * Render the content for the current active tab
264 */
265 public function renderTabContent(): void
266 {
267 switch ($this->activeTab) {
268 case 'general':
269 $this->renderGeneralTab();
270 break;
271 case 'presentation':
272 $this->renderPresentationTab();
273 break;
274 case 'howto':
275 $this->renderHowtoTab();
276 break;
277 case 'changelog':
278 $this->renderChangelogTab();
279 break;
280 }
281 }
282
283 /**
284 * Render the general settings tab content
285 */
286 private function renderGeneralTab(): void
287 {
288 try {
289 // Get the Config instance from CryptX
290 $config = $this->cryptX->getConfig();
291
292 // Create and render the General Settings Tab
293 $generalTab = new GeneralSettingsTab($config);
294
295 // Handle form submission if needed
296 if (isset($_POST['cryptX_save_general_settings'])) {
297 if (!empty($_POST['cryptX_var'])) {
298 $generalTab->saveSettings($_POST['cryptX_var']);
299 }
300 }
301
302 // Render the tab content
303 $generalTab->render();
304
305 } catch (\Exception $e) {
306 // Log error and display admin notice
307 error_log('CryptX General Settings Tab Error: ' . $e->getMessage());
308 add_settings_error(
309 'cryptx_messages',
310 'cryptx_error',
311 __('An error occurred while loading the general settings.', 'cryptx'),
312 'error'
313 );
314 }
315 }
316
317 /**
318 * Render the presentation settings tab content
319 */
320 private function renderPresentationTab(): void
321 {
322 try {
323 // Get the Config instance from CryptX
324 $config = $this->cryptX->getConfig();
325
326 // Create and render the Presentation Settings Tab
327 $presentationTab = new PresentationSettingsTab($config);
328
329 // Handle form submission if needed
330 if (isset($_POST['cryptX_save_presentation_settings'])) {
331 if (!empty($_POST['cryptX_var'])) {
332 $presentationTab->saveSettings($_POST['cryptX_var']);
333 }
334 }
335
336 // Render the tab content
337 $presentationTab->render();
338
339 } catch (\Exception $e) {
340 // Log error and display admin notice
341 error_log('CryptX Presentation Settings Tab Error: ' . $e->getMessage());
342 add_settings_error(
343 'cryptx_messages',
344 'cryptx_error',
345 __('An error occurred while loading the presentation settings.', 'cryptx'),
346 'error'
347 );
348 }
349 }
350
351 /**
352 * Render the how-to tab content
353 */
354 private function renderHowtoTab(): void
355 {
356 require CRYPTX_DIR_PATH . '/templates/admin/tabs/howto.php';
357 }
358
359 /**
360 * Render the changelog tab content
361 */
362 private function renderChangelogTab(): void
363 {
364 try {
365 $changelogTab = new ChangelogSettingsTab($this->cryptX->getConfig());
366 $changelogTab->render();
367 } catch (\Exception $e) {
368 error_log('CryptX Changelog Tab Error: ' . $e->getMessage());
369 add_settings_error(
370 'cryptx_messages',
371 'cryptx_error',
372 __('An error occurred while loading the changelog.', 'cryptx'),
373 'error'
374 );
375 }
376 }
377
378
379 /**
380 * Parse and render changelog content from readme.txt
381 */
382 private function renderChangelogContent(): void
383 {
384 $readmePath = CRYPTX_DIR_PATH . '/readme.txt';
385 if (!file_exists($readmePath)) {
386 return;
387 }
388
389 $fileContents = file_get_contents($readmePath);
390 if ($fileContents === false) {
391 return;
392 }
393
394 $changelogs = $this->parseChangelog($fileContents);
395 foreach ($changelogs as $log) {
396 echo wp_kses_post("<dl>" . implode("", $log) . "</dl>");
397 }
398 }
399
400 /**
401 * Parse changelog content from readme.txt
402 *
403 * @param string $content
404 * @return array
405 */
406 private function parseChangelog(string $content): array
407 {
408 $content = str_replace(["\r\n", "\r"], "\n", $content);
409 $content = trim($content);
410
411 // Split into sections
412 $sections = $this->parseSections($content);
413 if (!isset($sections['changelog'])) {
414 return [];
415 }
416
417 // Parse changelog entries
418 return $this->parseChangelogEntries($sections['changelog']['content']);
419 }
420
421 /**
422 * Parse sections from readme content
423 *
424 * @param string $content
425 * @return array
426 */
427 private function parseSections(string $content): array
428 {
429 $_sections = preg_split('/^[\s]*==[\s]*(.+?)[\s]*==/m', $content, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
430 $sections = [];
431
432 for ($i = 1; $i <= count($_sections); $i += 2) {
433 $title = $_sections[$i - 1];
434 $sections[str_replace(' ', '_', strtolower($title))] = [
435 'title' => $title,
436 'content' => $_sections[$i]
437 ];
438 }
439
440 return $sections;
441 }
442
443 /**
444 * Parse changelog entries
445 *
446 * @param string $content
447 * @return array
448 */
449 private function parseChangelogEntries(string $content): array
450 {
451 $_changelogs = preg_split('/^[\s]*=[\s]*(.+?)[\s]*=/m', $content, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
452 $changelogs = [];
453
454 for ($i = 1; $i <= count($_changelogs); $i += 2) {
455 $version = $_changelogs[$i - 1];
456 $content = ltrim($_changelogs[$i], "\n");
457 $content = str_replace("* ", "<li>", $content);
458 $content = str_replace("\n", " </li>\n", $content);
459
460 $changelogs[] = [
461 'version' => "<dt>" . esc_html($version) . "</dt>",
462 'content' => "<dd><ul>" . wp_kses_post($content) . "</ul></dd>"
463 ];
464 }
465
466 return $changelogs;
467 }
468 }