PluginProbe
Document Gallery / 2.3.4
Document Gallery v2.3.4
trunk 0.8 0.8.5 1.0 1.0.1 1.0.2 1.0.3 1.0.4 1.1 1.2 1.2.1 1.3 1.3.1 1.4 1.4.1 1.4.2 1.4.3 2.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 All 94 releases
document-gallery / admin / class-admin.php

class-admin.php in Document Gallery 2.3.4, at admin/class-admin.php

1,018 lines 42.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 defined('WPINC') OR exit;
3
4 class DG_Admin {
5 /**
6 * @var string The hook for the Document Gallery settings page.
7 */
8 private static $hook;
9
10 /**
11 * @var string The current tab being rendered.
12 */
13 private static $current;
14
15 /**
16 * NOTE: This should only ever be accessed through getTabs().
17 *
18 * @var multitype:string Associative array containing all tab names, keyed by tab slug.
19 */
20 private static $tabs;
21
22 /**
23 * Returns reference to tabs array, initializing if needed.
24 *
25 * NOTE: This cannot be done in a static constructor due to timing with i18n.
26 */
27 public static function &getTabs() {
28 if (!isset(self::$tabs)) {
29 self::$tabs = array(
30 'General' => __('General', 'document-gallery'),
31 'Thumbnail' => __('Thumbnail Management', 'document-gallery'),
32 'Logging' => __('Logging', 'document-gallery'),
33 'Advanced' => __('Advanced', 'document-gallery'));
34 }
35
36 return self::$tabs;
37 }
38
39 /**
40 * Renders Document Gallery options page.
41 */
42 public static function renderOptions() { ?>
43 <div class="wrap">
44 <h2><?php echo __('Document Gallery Settings', 'document-gallery'); ?></h2>
45
46 <h2 class="nav-tab-wrapper">
47 <?php foreach (self::getTabs() as $tab => $name) {
48 $class = ($tab == self::$current) ? ' nav-tab-active' : '';
49 echo '<a class="nav-tab '.$tab.'-tab'.$class.'" href="?page=' . DG_OPTION_NAME . '&tab='.$tab.'">'.$name.'</a>';
50 } ?>
51 </h2>
52
53 <form method="post" action="options.php" id="tab-<?php echo self::$current?>">
54 <input type="hidden" name="<?php echo DG_OPTION_NAME; ?>[tab]" value="<?php echo self::$current; ?>" />
55 <?php
56 settings_fields(DG_OPTION_NAME);
57 do_settings_sections(DG_OPTION_NAME);
58 if (self::$current != 'Thumbnail' && self::$current != 'Logging') {
59 submit_button();
60 }
61 ?>
62 </form>
63
64 </div>
65 <?php }
66
67 /**
68 * Adds settings link to main plugin view.
69 */
70 public static function addSettingsLink($links) {
71 $settings = '<a href="options-general.php?page=' . DG_OPTION_NAME . '">' .
72 __('Settings', 'document-gallery') . '</a>';
73 array_unshift($links, $settings);
74 return $links;
75 }
76
77 /**
78 * Adds Document Gallery settings page to admin navigation.
79 */
80 public static function addAdminPage() {
81 DG_Admin::$hook = add_options_page(
82 __('Document Gallery Settings', 'document-gallery'),
83 __('Document Gallery', 'document-gallery'),
84 'manage_options', DG_OPTION_NAME, array(__CLASS__, 'renderOptions'));
85 add_action('admin_enqueue_scripts', array(__CLASS__, 'enqueueScriptsAndStyles'));
86 }
87
88 /**
89 * Enqueues styles and scripts for the admin settings page.
90 */
91 public static function enqueueScriptsAndStyles($hook) {
92 if ($hook !== DG_Admin::$hook) return;
93
94 wp_enqueue_style('document-gallery-admin', DG_URL . 'assets/css/admin.css', null, DG_VERSION);
95 wp_enqueue_script('document-gallery-admin', DG_URL . 'assets/js/admin.js', array('jquery'), DG_VERSION, true);
96 }
97
98 /**
99 * Registers settings for the Document Gallery options page.
100 */
101 public static function registerSettings() {
102 if (empty($_REQUEST['tab']) || !array_key_exists($_REQUEST['tab'], self::getTabs())) {
103 reset(self::getTabs());
104 self::$current = key(self::getTabs());
105 } else {
106 self::$current = $_REQUEST['tab'];
107 }
108
109 register_setting(DG_OPTION_NAME, DG_OPTION_NAME, array(__CLASS__, 'validateSettings'));
110
111 $funct = 'register' . self::$current . 'Settings';
112 DG_Admin::$funct();
113 }
114
115 /**
116 * Registers settings for the general tab.
117 */
118 private static function registerGeneralSettings() {
119 global $dg_options;
120
121 include_once DG_PATH . 'inc/class-gallery.php';
122 include_once DG_PATH . 'inc/class-thumber.php';
123
124 $defaults = $dg_options['gallery'];
125 $active = $dg_options['thumber']['active'];
126
127 add_settings_section(
128 'gallery_defaults', __('Default Settings', 'document-gallery'),
129 array(__CLASS__, 'renderDefaultSettingsSection'), DG_OPTION_NAME);
130
131 add_settings_section(
132 'thumbnail_generation', __('Thumbnail Generation', 'document-gallery'),
133 array(__CLASS__, 'renderThumberSection'), DG_OPTION_NAME);
134
135 add_settings_section(
136 'css', __('Custom CSS', 'document-gallery'),
137 array(__CLASS__, 'renderCssSection'), DG_OPTION_NAME);
138
139 add_settings_field(
140 'gallery_defaults_attachment_pg', 'attachment_pg',
141 array(__CLASS__, 'renderCheckboxField'),
142 DG_OPTION_NAME, 'gallery_defaults',
143 array (
144 'label_for' => 'label_gallery_defaults_attachment_pg',
145 'name' => 'gallery_defaults][attachment_pg',
146 'value' => esc_attr($defaults['attachment_pg']),
147 'option_name' => DG_OPTION_NAME,
148 'description' => __('Link to attachment page rather than to file', 'document-gallery')
149 ));
150
151 add_settings_field(
152 'gallery_defaults_descriptions', 'descriptions',
153 array(__CLASS__, 'renderCheckboxField'),
154 DG_OPTION_NAME, 'gallery_defaults',
155 array (
156 'label_for' => 'label_gallery_defaults_descriptions',
157 'name' => 'gallery_defaults][descriptions',
158 'value' => esc_attr($defaults['descriptions']),
159 'option_name' => DG_OPTION_NAME,
160 'description' => __('Include document descriptions', 'document-gallery')
161 ));
162
163 add_settings_field(
164 'gallery_defaults_fancy', 'fancy',
165 array(__CLASS__, 'renderCheckboxField'),
166 DG_OPTION_NAME, 'gallery_defaults',
167 array (
168 'label_for' => 'label_gallery_defaults_fancy',
169 'name' => 'gallery_defaults][fancy',
170 'value' => esc_attr($defaults['fancy']),
171 'option_name' => DG_OPTION_NAME,
172 'description' => __('Use auto-generated document thumbnails', 'document-gallery')
173 ));
174
175 add_settings_field(
176 'gallery_defaults_images', 'images',
177 array(__CLASS__, 'renderCheckboxField'),
178 DG_OPTION_NAME, 'gallery_defaults',
179 array (
180 'label_for' => 'label_gallery_defaults_images',
181 'name' => 'gallery_defaults][images',
182 'value' => esc_attr($defaults['images']),
183 'option_name' => DG_OPTION_NAME,
184 'description' => __('Include image attachments in gallery', 'document-gallery')
185 ));
186
187 add_settings_field(
188 'gallery_defaults_localpost', 'localpost',
189 array(__CLASS__, 'renderCheckboxField'),
190 DG_OPTION_NAME, 'gallery_defaults',
191 array (
192 'label_for' => 'label_gallery_defaults_localpost',
193 'name' => 'gallery_defaults][localpost',
194 'value' => esc_attr($defaults['localpost']),
195 'option_name' => DG_OPTION_NAME,
196 'description' => __('Only look for attachments in post where [dg] is used', 'document-gallery')
197 ));
198
199 add_settings_field(
200 'gallery_defaults_order', 'order',
201 array(__CLASS__, 'renderSelectField'),
202 DG_OPTION_NAME, 'gallery_defaults',
203 array (
204 'label_for' => 'label_gallery_defaults_order',
205 'name' => 'gallery_defaults][order',
206 'value' => esc_attr($defaults['order']),
207 'options' => DG_Gallery::getOrderOptions(),
208 'option_name' => DG_OPTION_NAME,
209 'description' => __('Ascending or descending sorting of documents', 'document-gallery')
210 ));
211
212 add_settings_field(
213 'gallery_defaults_orderby', 'orderby',
214 array(__CLASS__, 'renderSelectField'),
215 DG_OPTION_NAME, 'gallery_defaults',
216 array (
217 'label_for' => 'label_gallery_defaults_orderby',
218 'name' => 'gallery_defaults][orderby',
219 'value' => esc_attr($defaults['orderby']),
220 'options' => DG_Gallery::getOrderbyOptions(),
221 'option_name' => DG_OPTION_NAME,
222 'description' => __('Which field to order documents by', 'document-gallery')
223 ));
224
225 add_settings_field(
226 'gallery_defaults_relation', 'relation',
227 array(__CLASS__, 'renderSelectField'),
228 DG_OPTION_NAME, 'gallery_defaults',
229 array (
230 'label_for' => 'label_gallery_defaults_relation',
231 'name' => 'gallery_defaults][relation',
232 'value' => esc_attr($defaults['relation']),
233 'options' => DG_Gallery::getRelationOptions(),
234 'option_name' => DG_OPTION_NAME,
235 'description' => __('Whether matched documents must have all taxa_names (AND) or at least one (OR)', 'document-gallery')
236 ));
237
238 add_settings_field(
239 'gallery_defaults_limit', 'limit',
240 array(__CLASS__, 'renderTextField'),
241 DG_OPTION_NAME, 'gallery_defaults',
242 array (
243 'label_for' => 'label_gallery_defaults_limit',
244 'name' => 'gallery_defaults][limit',
245 'value' => esc_attr($defaults['limit']),
246 'type' => 'number" min="-1" step="1',
247 'option_name' => DG_OPTION_NAME,
248 'description' => __('Limit the number of documents included. -1 means no limit.', 'document-gallery')));
249
250 add_settings_field(
251 'gallery_defaults_post_status', 'post_status',
252 array(__CLASS__, 'renderSelectField'),
253 DG_OPTION_NAME, 'gallery_defaults',
254 array (
255 'label_for' => 'label_gallery_defaults_post_status',
256 'name' => 'gallery_defaults][post_status',
257 'value' => esc_attr($defaults['post_status']),
258 'options' => DG_Gallery::getPostStatuses(),
259 'option_name' => DG_OPTION_NAME,
260 'description' => __('Which post status to look for when querying documents.', 'document-gallery')
261 ));
262
263 add_settings_field(
264 'gallery_defaults_post_type', 'post_type',
265 array(__CLASS__, 'renderSelectField'),
266 DG_OPTION_NAME, 'gallery_defaults',
267 array (
268 'label_for' => 'label_gallery_defaults_post_type',
269 'name' => 'gallery_defaults][post_type',
270 'value' => esc_attr($defaults['post_type']),
271 'options' => DG_Gallery::getPostTypes(),
272 'option_name' => DG_OPTION_NAME,
273 'description' => __('Which post type to look for when querying documents.', 'document-gallery')
274 ));
275
276 add_settings_field(
277 'thumbnail_generation_av', 'Audio/Video',
278 array(__CLASS__, 'renderCheckboxField'),
279 DG_OPTION_NAME, 'thumbnail_generation',
280 array (
281 'label_for' => 'label_thumbnail_generation_av',
282 'name' => 'thumbnail_generation][av',
283 'value' => esc_attr($active['av']),
284 'option_name' => DG_OPTION_NAME,
285 'description' => esc_html__('Locally generate thumbnails for audio & video files.', 'document-gallery')
286 ));
287
288 add_settings_field(
289 'thumbnail_generation_gs', 'Ghostscript',
290 array(__CLASS__, 'renderCheckboxField'),
291 DG_OPTION_NAME, 'thumbnail_generation',
292 array (
293 'label_for' => 'label_thumbnail_generation_gs',
294 'name' => 'thumbnail_generation][gs',
295 'value' => esc_attr($active['gs']),
296 'option_name' => DG_OPTION_NAME,
297 'description' => DG_Thumber::isGhostscriptAvailable()
298 ? __('Use <a href="http://www.ghostscript.com/" target="_blank">Ghostscript</a> for faster local PDF processing (compared to Imagick).', 'document-gallery')
299 : __('Your server is not configured to run <a href="http://www.ghostscript.com/" target="_blank">Ghostscript</a>.', 'document-gallery'),
300 'disabled' => !DG_Thumber::isGhostscriptAvailable()
301 ));
302
303 add_settings_field(
304 'thumbnail_generation_imagick', 'Imagick',
305 array(__CLASS__, 'renderCheckboxField'),
306 DG_OPTION_NAME, 'thumbnail_generation',
307 array (
308 'label_for' => 'label_thumbnail_generation_imagick',
309 'name' => 'thumbnail_generation][imagick',
310 'value' => esc_attr($active['imagick']),
311 'option_name' => DG_OPTION_NAME,
312 'description' => DG_Thumber::isImagickAvailable()
313 ? __('Use <a href="http://www.php.net/manual/en/book.imagick.php" target="_blank">Imagick</a> to handle lots of filetypes locally.', 'document-gallery')
314 : __('Your server is not configured to run <a href="http://www.php.net/manual/en/book.imagick.php" target="_blank">Imagick</a>.', 'document-gallery'),
315 'disabled' => !DG_Thumber::isImagickAvailable()
316 ));
317
318 add_settings_field(
319 'thumbnail_generation_google', 'Google Drive Viewer',
320 array(__CLASS__, 'renderCheckboxField'),
321 DG_OPTION_NAME, 'thumbnail_generation',
322 array (
323 'label_for' => 'label_thumbnail_generation_google',
324 'name' => 'thumbnail_generation][google',
325 'value' => esc_attr($active['google']),
326 'option_name' => DG_OPTION_NAME,
327 'description' => DG_Thumber::isGoogleDriveAvailable()
328 ? __('Use <a href="https://drive.google.com/viewer" target="_blank">Google Drive Viewer</a> to generate thumbnails for MS Office files and many other file types remotely.', 'document-gallery')
329 : __('Your server does not allow remote HTTP access.', 'document-gallery'),
330 'disabled' => !DG_Thumber::isGoogleDriveAvailable()
331 ));
332
333 add_settings_field(
334 'thumbnail_generation_width', 'Max Thumbnail Dimensions',
335 array(__CLASS__, 'renderMultiTextField'),
336 DG_OPTION_NAME, 'thumbnail_generation',
337 array (
338 array (
339 'label_for' => 'label_advanced_width',
340 'name' => 'thumbnail_generation][width',
341 'value' => esc_attr($dg_options['thumber']['width']),
342 'type' => 'number" min="1" step="1',
343 'option_name' => DG_OPTION_NAME,
344 'description' => ' x '),
345 array (
346 'label_for' => 'label_advanced_height',
347 'name' => 'thumbnail_generation][height',
348 'value' => esc_attr($dg_options['thumber']['height']),
349 'type' => 'number" min="1" step="1',
350 'option_name' => DG_OPTION_NAME,
351 'description' => __('The max width and height (in pixels) that thumbnails will be generated.', 'document-gallery'))
352 ));
353 }
354
355 /**
356 * Registers settings for the thumbnail management tab.
357 */
358 private static function registerThumbnailSettings() {
359 add_settings_section(
360 'thumbnail_table', '',
361 array(__CLASS__, 'renderThumbnailSection'), DG_OPTION_NAME);
362 }
363
364 /**
365 * Registers settings for the logging tab.
366 */
367 private static function registerLoggingSettings() {
368 add_settings_section(
369 'logging_table', '',
370 array(__CLASS__, 'renderLoggingSection'), DG_OPTION_NAME);
371 }
372
373 /**
374 * Registers settings for the advanced tab.
375 */
376 private static function registerAdvancedSettings() {
377 global $dg_options;
378
379 add_settings_section(
380 'advanced', __('Advanced Thumbnail Generation', 'document-gallery'),
381 array(__CLASS__, 'renderAdvancedSection'), DG_OPTION_NAME);
382
383 add_settings_field(
384 'advanced_logging', 'Logging',
385 array(__CLASS__, 'renderCheckboxField'),
386 DG_OPTION_NAME, 'advanced',
387 array (
388 'label_for' => 'label_advanced_logging',
389 'name' => 'logging',
390 'value' => esc_attr($dg_options['logging']),
391 'option_name' => DG_OPTION_NAME,
392 'description' => __('Whether to log debug and error information related to Document Gallery.', 'document-gallery')
393 ));
394
395 add_settings_field(
396 'advanced_validation', 'Option Validation',
397 array(__CLASS__, 'renderCheckboxField'),
398 DG_OPTION_NAME, 'advanced',
399 array (
400 'label_for' => 'label_advanced_validation',
401 'name' => 'validation',
402 'value' => esc_attr($dg_options['validation']),
403 'option_name' => DG_OPTION_NAME,
404 'description' => __('Whether option structure should be validated before save. This is not generally necessary.', 'document-gallery')
405 ));
406
407 add_settings_field(
408 'advanced_thumb_timeout', 'Thumbnail Generation Timeout',
409 array(__CLASS__, 'renderTextField'),
410 DG_OPTION_NAME, 'advanced',
411 array (
412 'label_for' => 'label_advanced_thumb_timeout',
413 'name' => 'timeout',
414 'value' => esc_attr($dg_options['thumber']['timeout']),
415 'type' => 'number" min="1" step="1',
416 'option_name' => DG_OPTION_NAME,
417 'description' => __('Max number of seconds to wait for thumbnail generation before defaulting to filetype icons.', 'document-gallery') .
418 ' <em>' . __('Note that generation will continue where timeout happened next time the gallery is loaded.', 'document-gallery') . '</em>'));
419
420 add_settings_field(
421 'advanced_gs', 'Ghostscript Absolute Path',
422 array(__CLASS__, 'renderTextField'),
423 DG_OPTION_NAME, 'advanced',
424 array (
425 'label_for' => 'label_advanced_gs',
426 'name' => 'gs',
427 'value' => esc_attr($dg_options['thumber']['gs']),
428 'option_name' => DG_OPTION_NAME,
429 'description' => $dg_options['thumber']['gs']
430 ? __('Successfully auto-detected the location of Ghostscript.', 'document-gallery')
431 : __('Failed to auto-detect the location of Ghostscript.', 'document-gallery')
432 ));
433
434 add_settings_section(
435 'advanced_options_dump', __('Options Array Dump', 'document-gallery'),
436 array(__CLASS__, 'renderOptionsDumpSection'), DG_OPTION_NAME);
437 }
438
439 /**
440 * Validates submitted options, sanitizing any invalid options.
441 * @param array $values User-submitted new options.
442 * @return array Sanitized new options.
443 */
444 public static function validateSettings($values) {
445 if (empty($values['tab']) || !array_key_exists($values['tab'], self::getTabs())) {
446 reset(self::getTabs());
447 $values['tab'] = key(self::getTabs());
448 }
449 $funct = 'validate'.$values['tab'].'Settings';
450 unset($values['tab']);
451 return DG_Admin::$funct($values);
452 }
453
454 /**
455 * Validates general settings, sanitizing any invalid options.
456 * @param array $values User-submitted new options.
457 * @return array Sanitized new options.
458 */
459 private static function validateGeneralSettings($values) {
460 global $dg_options;
461 $ret = $dg_options;
462
463 include_once DG_PATH . 'inc/class-gallery.php';
464
465 $thumbs_cleared = false;
466
467 // handle gallery shortcode defaults
468 $errs = array();
469 $ret['gallery'] = DG_Gallery::sanitizeDefaults($values['gallery_defaults'], $errs, true);
470
471 foreach ($errs as $k => $v) {
472 add_settings_error(DG_OPTION_NAME, str_replace('_', '-', $k), $v);
473 }
474
475 // handle setting width
476 if (isset($values['thumbnail_generation']['width'])) {
477 $width = (int)$values['thumbnail_generation']['width'];
478 if ($width > 0) {
479 $ret['thumber']['width'] = $width;
480 } else {
481 add_settings_error(DG_OPTION_NAME, 'thumber-width',
482 __('Invalid width given: ', 'document-gallery') . $values['thumbnail_generation']['width']);
483 }
484
485 unset($values['thumbnail_generation']['width']);
486 }
487
488 // handle setting height
489 if (isset($values['thumbnail_generation']['height'])) {
490 $height = (int)$values['thumbnail_generation']['height'];
491 if ($height > 0) {
492 $ret['thumber']['height'] = $height;
493 } else {
494 add_settings_error(DG_OPTION_NAME, 'thumber-height',
495 __('Invalid height given: ', 'document-gallery') . $values['thumbnail_generation']['height']);
496 }
497
498 unset($values['thumbnail_generation']['width']);
499 }
500
501 // delete thumb cache to force regeneration if max dimensions changed
502 if ($ret['thumber']['width'] !== $dg_options['thumber']['width'] ||
503 $ret['thumber']['height'] !== $dg_options['thumber']['height']) {
504 foreach ($ret['thumber']['thumbs'] as $v) {
505 if (isset($v['thumber'])) {
506 @unlink($v['thumb_path']);
507 }
508 }
509
510 $ret['thumber']['thumbs'] = array();
511 $thumbs_cleared = true;
512 }
513
514 // handle setting the active thumbers
515 foreach (array_keys($ret['thumber']['active']) as $k) {
516 $ret['thumber']['active'][$k] = isset($values['thumbnail_generation'][$k]);
517 }
518
519 // if new thumbers available, clear failed thumbnails for retry
520 if (!$thumbs_cleared) {
521 foreach ($dg_options['thumber']['active'] as $k => $v) {
522 if (!$v && $ret['thumber']['active'][$k]) {
523 foreach ($dg_options['thumber']['thumbs'] as $k => $v) {
524 if (empty($v['thumber'])) {
525 unset($ret['thumber']['thumbs'][$k]);
526 }
527 }
528 break;
529 }
530 }
531 }
532
533 // handle modified CSS
534 if (trim($ret['css']['text']) !== trim($values['css'])) {
535 $ret['css']['text'] = trim($values['css']);
536 $ret['css']['minified'] = DocumentGallery::compileCustomCss($ret['css']['text']);
537 }
538
539 return $ret;
540 }
541
542 /**
543 * Validates thumbnail management settings, sanitizing any invalid options.
544 * @param array $values User-submitted new options.
545 * @return array Sanitized new options.
546 */
547 private static function validateThumbnailSettings($values) {
548 global $dg_options;
549 $ret = $dg_options;
550
551 if (isset($values['ids'])) {
552 $deleted = array_values(array_intersect(array_keys($dg_options['thumber']['thumbs']), $values['ids']));
553
554 foreach ($deleted as $k) {
555 if (isset($ret['thumber']['thumbs'][$k]['thumber'])) {
556 @unlink($ret['thumber']['thumbs'][$k]['thumb_path']);
557 }
558
559 unset($ret['thumber']['thumbs'][$k]);
560 }
561
562 if (isset($values['ajax'])) {
563 echo '[' . implode(',', $deleted) . ']';
564 add_filter('wp_redirect', array(__CLASS__, '_exit'), 1, 0);
565 }
566 }
567
568 return $ret;
569 }
570
571 /**
572 * Validates logging settings, sanitizing any invalid options.
573 * @param array $values User-submitted new options.
574 * @return array Sanitized new options.
575 */
576 private static function validateLoggingSettings($values) {
577 global $dg_options;
578 if (isset($values['clearLog'])) {
579 DG_Logger::clearLog();
580 }
581 return $dg_options;
582 }
583
584 /**
585 * Validates advanced settings, sanitizing any invalid options.
586 * @param array $values User-submitted new options.
587 * @return array Sanitized new options.
588 */
589 private static function validateAdvancedSettings($values) {
590 global $dg_options;
591 $ret = $dg_options;
592
593 // handle setting the Ghostscript path
594 if (isset($values['gs']) &&
595 0 != strcmp($values['gs'], $ret['thumber']['gs'])) {
596 if (false === strpos($values['gs'], ';')) {
597 $ret['thumber']['gs'] = $values['gs'];
598 } else {
599 add_settings_error(DG_OPTION_NAME, 'thumber-gs',
600 __('Invalid Ghostscript path given: ', 'document-gallery') . $values['gs']);
601 }
602 }
603
604 // handle setting timeout
605 if (isset($values['timeout'])) {
606 $timeout = (int)$values['timeout'];
607 if ($timeout > 0) {
608 $ret['thumber']['timeout'] = $timeout;
609 } else {
610 add_settings_error(DG_OPTION_NAME, 'thumber-timeout',
611 __('Invalid timeout given: ', 'document-gallery') . $values['timeout']);
612 }
613 }
614
615 // validation checkbox
616 $ret['validation'] = isset($values['validation']);
617
618 // logging checkbox
619 $ret['logging'] = isset($values['logging']);
620
621 return $ret;
622 }
623
624 /**
625 * @return bool Whether to register settings.
626 */
627 public static function doRegisterSettings() {
628 if (!is_multisite()) {
629 $script = !empty($GLOBALS['pagenow']) ? $GLOBALS['pagenow'] : null;
630 } else {
631 $script = parse_url($_SERVER['REQUEST_URI']);
632 $script = basename($script['path']);
633 }
634
635 return !empty($script) && ('options-general.php' === $script || 'options.php' === $script);
636 }
637
638 /**
639 * Render the Default Settings section.
640 */
641 public static function renderDefaultSettingsSection() { ?>
642 <p><?php _e('The following values will be used by default in the shortcode. You can still manually set each of these values in each individual shortcode.', 'document-gallery'); ?></p>
643 <?php }
644
645 /**
646 * Render the Thumber section.
647 */
648 public static function renderThumberSection() { ?>
649 <p><?php _e('Select which tools to use when generating thumbnails.', 'document-gallery'); ?></p>
650 <?php }
651
652 /**
653 * Renders a text field for use when modifying the CSS to be printed in addition to the default CSS.
654 */
655 public static function renderCssSection() {
656 global $dg_options; ?>
657 <p><?php printf(
658 __('Enter custom CSS styling for use with document galleries. To see which ids and classes you can style, take a look at <a href="%s" target="_blank">style.css</a>.'),
659 DG_URL . 'assets/css/style.css'); ?></p>
660 <table class="form-table">
661 <tbody>
662 <tr valign="top">
663 <td>
664 <textarea name="<?php echo DG_OPTION_NAME; ?>[css]" rows="10" cols="50" class="large-text code"><?php echo $dg_options['css']['text']; ?></textarea>
665 </td>
666 </tr>
667 </tbody>
668 </table>
669 <?php }
670
671 /**
672 * Render the Thumber Advanced section.
673 */
674 public static function renderAdvancedSection() {
675 include_once DG_PATH . 'inc/class-thumber.php';?>
676 <p><?php _e('Unless you <em>really</em> know what you\'re doing, you should not touch these values.', 'document-gallery'); ?></p>
677 <?php if (!DG_Thumber::isExecAvailable()) : ?>
678 <p>
679 <em><?php _e('NOTE: <code>exec()</code> is not accessible. Ghostscript will not function.', 'document-gallery'); ?></em>
680 </p>
681 <?php endif; ?>
682 <?php }
683
684 /**
685 * Renders a readonly textfield containing a dump of current DG options.
686 */
687 public static function renderOptionsDumpSection() {
688 global $dg_options; ?>
689 <p><?php
690 _e('The following <em>readonly text</em> should be provided when <a href="http://wordpress.org/support/plugin/document-gallery" target="_blank">reporting a bug</a>:', 'documet-gallery');
691 ?></p>
692 <table class="form-table">
693 <tbody>
694 <tr valign="top">
695 <td>
696 <textarea readonly="true" rows="10" cols="50" id="options-dump" class="large-text code"><?php var_dump($dg_options); ?></textarea>
697 </td>
698 </tr>
699 </tbody>
700 </table>
701 <?php }
702
703 /**
704 * Render the Thumbnail table.
705 */
706 public static function renderThumbnailSection() {
707 include_once DG_PATH . 'inc/class-thumber.php';
708 $options = DG_Thumber::getOptions();
709
710 $URL_params = array('page' => DG_OPTION_NAME, 'tab' => 'Thumbnail');
711 $att_ids = array();
712
713 if (isset($_REQUEST['orderby']) && in_array(strtolower($_REQUEST['orderby']), array('title', 'date'))) {
714 $orderby = strtolower($_REQUEST['orderby']);
715 $URL_params['orderby'] = $orderby;
716
717 switch ($orderby)
718 {
719 case 'date':
720 foreach ($options['thumbs'] as $key => $node) {
721 $keyArray[$key] = $node['timestamp'];
722 $options['thumbs'][$key]['thumb_id'] = $att_ids[] = $key;
723 }
724 break;
725
726 case 'title':
727 foreach ($options['thumbs'] as $key => $node) {
728 $keyArray[$key] = basename($node['thumb_path']);
729 $options['thumbs'][$key]['thumb_id'] = $att_ids[] = $key;
730 }
731 break;
732 }
733
734 $order = strtolower($_REQUEST['order']);
735 if (!isset($_REQUEST['order']) || !in_array($order, array('asc', 'desc'))) {
736 $order = 'asc';
737 }
738 $URL_params['order'] = $order;
739
740 if ($order == 'asc') {
741 array_multisort($keyArray, SORT_ASC, $options['thumbs']);
742 } else {
743 array_multisort($keyArray, SORT_DESC, $options['thumbs']);
744 }
745 } else {
746 $orderby = '';
747 foreach ($options['thumbs'] as $key => $node) {
748 $options['thumbs'][$key]['thumb_id'] = $att_ids[] = $key;
749 }
750 }
751
752 static $limit_options = array(10, 25, 75);
753 if (!isset($_REQUEST['limit']) || !in_array(intval($_REQUEST['limit']), $limit_options)) {
754 $limit = $limit_options[0];
755 } else {
756 $limit = intval($_REQUEST['limit']);
757 }
758
759 $URL_params['limit'] = $limit;
760 $select_limit = '';
761 foreach ($limit_options as $l_o) {
762 $select_limit .= '<option value="'.$l_o.'"'.selected($limit, $l_o, false).'>'.$l_o.'</option>'.PHP_EOL;
763 }
764 $thumbs_number = count($options['thumbs']);
765 $lastsheet = ceil($thumbs_number/$limit);
766 $sheet = isset($_REQUEST['sheet']) ? intval($_REQUEST['sheet']) : 1;
767 if ($sheet <= 0 || $sheet > $lastsheet) {
768 $sheet = 1;
769 }
770
771 $offset = ($sheet - 1) * $limit;
772
773 $att_ids = array_slice($att_ids, $offset, $limit);
774 $atts = get_posts(
775 array(
776 'post_type' => 'any',
777 'post_status' => 'any',
778 'numberposts' => -1,
779 'post__in' => $att_ids,
780 'orderby' => 'post__in'
781 ));
782 $titles = array();
783 foreach ($atts as $att) {
784 $path_parts = pathinfo($att->guid);
785 $titles[$att->ID] = $att->post_title.'.'.$path_parts['extension'];
786 }
787 unset($atts);
788
789 $thead = '<tr>'.
790 '<th scope="col" class="manage-column column-cb check-column">'.
791 '<label class="screen-reader-text" for="cb-select-all-%1$d">'.__('Select All', 'document-gallery').'</label>'.
792 '<input id="cb-select-all-%1$d" type="checkbox">'.
793 '</th>'.
794 '<th scope="col" class="manage-column column-icon">'.__('Thumbnail', 'document-gallery').'</th>'.
795 '<th scope="col" class="manage-column column-title '.(($orderby != 'title')?'sortable desc':'sorted '.$order).'"><a href="?'.http_build_query(array_merge($URL_params, array('orderby'=>'title','order'=>(($orderby != 'title')?'asc':(($order == 'asc')?'desc':'asc'))))).'"><span>'.__('File name', 'document-gallery').'</span><span class="sorting-indicator"></span></th>'.
796 '<th scope="col" class="manage-column column-date '.(($orderby != 'date')?'sortable asc':'sorted '.$order).'"><a href="?'.http_build_query(array_merge($URL_params, array('orderby'=>'date','order'=>(($orderby != 'date')?'desc':(($order == 'asc')?'desc':'asc'))))).'"><span>'.__('Date', 'document-gallery').'</span><span class="sorting-indicator"></span></th>'.
797 '</tr>';
798
799 $pagination = '<div class="alignleft bulkactions"><button class="button action deleteSelected">'.__('Delete Selected', 'document-gallery').'</button></div><div class="tablenav-pages">'.
800 '<span class="displaying-num">'.
801 $thumbs_number.' '._n('item', 'items', $thumbs_number).
802 '</span>'.($lastsheet>1?
803 '<span class="pagination-links">'.
804 '<a class="first-page'.( $sheet==1 ? ' disabled' : '').'" title="'.__('Go to the first page', 'document-gallery').'"'.( $sheet==1 ? '' : ' href="?'.http_build_query($URL_params).'"').'>«</a>'.
805 '<a class="prev-page'.( $sheet==1 ? ' disabled' : '').'" title="'.__('Go to the previous page', 'document-gallery').'"'.( $sheet==1 ? '' : ' href="?'.http_build_query(array_merge($URL_params, array('sheet'=>$sheet-1))).'"').'>‹</a>'.
806 '<span class="paging-input">'.
807 '<input class="current-page" title="'.__('Current page', 'document-gallery').'" type="text" name="paged" value="'.$sheet.'" size="'.strlen($sheet).'" maxlength="'.strlen($sheet).'"> '.__('of', 'document-gallery').' <span class="total-pages">'.$lastsheet.'</span></span>'.
808 '<a class="next-page'.( $sheet==$lastsheet ? ' disabled' : '').'" title="'.__('Go to the next page', 'document-gallery').'"'.( $sheet==$lastsheet ? '' : ' href="?'.http_build_query(array_merge($URL_params, array('sheet'=>$sheet+1))).'"').'>›</a>'.
809 '<a class="last-page'.( $sheet==$lastsheet ? ' disabled' : '').'" title="'.__('Go to the last page', 'document-gallery').'"'.( $sheet==$lastsheet ? '' : ' href="?'.http_build_query(array_merge($URL_params, array('sheet'=>$lastsheet))).'"').'>»</a>'.
810 '</span>':' <b>|</b> ').
811 '<span class="displaying-num"><select dir="rtl" class="limit_per_page">'.$select_limit.'</select> '.__('items per page', 'document-gallery').'</span>'.
812 '</div>'.
813 '<br class="clear" />';
814
815 // Avoiding json_encode to avoid compatibility issues on some systems
816 $json_like = '';
817 foreach ($URL_params as $k => $v) {
818 $json_like .= '"'.$k.'":"'.$v.'",';
819 }
820 ?>
821
822 <script type="text/javascript">
823 var URL_params = <?php echo '{'.trim($json_like,', ').'}'; ?>;
824 </script>
825 <div class="thumbs-list-wrapper">
826 <div>
827 <div class="tablenav top"><?php echo $pagination; ?></div>
828 <table id="ThumbsTable" class="wp-list-table widefat fixed media"
829 cellpadding="0" cellspacing="0">
830 <thead>
831 <?php printf($thead, 1); ?>
832 </thead>
833 <tfoot>
834 <?php printf($thead, 2); ?>
835 </tfoot>
836 <tbody><?php
837 $i = 0;
838 foreach ($options['thumbs'] as $v) {
839 if ($i < $offset) { $i++; continue; }
840 if (++$i > $offset + $limit) { break; }
841
842 $icon = isset($v['thumb_url']) ? $v['thumb_url'] : DG_URL . 'assets/icons/missing.png';
843 $title = isset($titles[$v['thumb_id']]) ? $titles[$v['thumb_id']] : '';
844 $date = DocumentGallery::localDateTimeFromTimestamp($v['timestamp']);
845
846 echo '<tr><td scope="row" class="check-column"><input type="checkbox" class="cb-ids" name="' . DG_OPTION_NAME . '[ids][]" value="' .
847 $v['thumb_id'].'"></td><td class="column-icon media-icon"><img src="' .
848 $icon.'" />'.'</td><td class="title column-title">' .
849 ($title ? '<strong><a href="' . home_url('/?attachment_id='.$v['thumb_id']).'" target="_blank" title="'.__('View', 'document-gallery').' \'' .
850 $title.'\' '.__('attachment page', 'document-gallery').'">'.$title.'</a></strong>' : __('Attachment not found', 'document-gallery')) .
851 '</td><td class="date column-date">'.$date.'</td></tr>'.PHP_EOL;
852 } ?>
853 </tbody>
854 </table>
855 <div class="tablenav bottom"><?php echo $pagination; ?></div>
856 </div>
857 </div>
858 <?php }
859 /**
860 * Render the Logging table.
861 */
862 public static function renderLoggingSection() {
863 $log_list = DG_Logger::readLog();
864 if ($log_list) {
865 $levels = array_map(array(__CLASS__, 'getLogLabelSpan'), array_keys(DG_LogLevel::getLogLevels()));
866
867 $thead = '<tr>'.
868 '<th scope="col" class="manage-column column-date"><span>'.__('Date', 'document-gallery').'</span></th>'.
869 '<th scope="col" class="manage-column column-level"><span>'.__('Level', 'document-gallery').'</span></th>'.
870 '<th scope="col" class="manage-column column-message"><span>'.__('Message', 'document-gallery').'</span></th>'.
871 '</tr>';
872
873 ?>
874 <div class="log-list-wrapper">
875 <div>
876 <div class="tablenav top">
877 <div class="alignleft bulkactions">
878 <button class="action expandAll">
879 <?php echo __('Expand All', 'document-gallery'); ?>
880 </button>
881 <button class="action collapseAll">
882 <?php echo __('Collapse All', 'document-gallery'); ?>
883 </button>
884 </div>
885 <div class="levelSelector">
886 <input type="checkbox" id="allLevels" name="lswitch" value="all" checked />
887 <label for="allLevels" class="allLevels">ALL</label>
888 <?php
889 foreach (array_keys(DG_LogLevel::getLogLevels()) as $k) { ?>
890 <?php
891 $lower = strtolower($k);
892 $upper = strtoupper($k);
893 ?>
894 <input type="checkbox" id="<?php echo $lower; ?>Level" name="lswitch" value="<?php echo $lower; ?>" checked />
895 <label for="<?php echo $lower; ?>Level" class="<?php echo $lower; ?>Level"><?php echo $upper; ?></label>
896 <?php }
897 ?>
898 </div>
899 </div>
900 <table id="LogTable" class="wp-list-table widefat fixed media" cellpadding="0" cellspacing="0">
901 <thead>
902 <?php echo $thead; ?>
903 </thead>
904 <tfoot>
905 <?php echo $thead; ?>
906 </tfoot>
907 <tbody><?php
908 $i = 0;
909 foreach ($log_list as $v) {
910 $date = DocumentGallery::localDateTimeFromTimestamp($v[0]);
911 $v[2] = preg_replace('/ (attachment #)(\d+) /', ' <a href="' . home_url() . '/?attachment_id=\2" target="_blank">\1<strong>\2</strong></a> ', $v[2]);
912 $v[2] = preg_replace('/^(\(\w+::\w+\)) /', '<strong>\1</strong> ', $v[2]);
913 $v[2] = preg_replace('/(\(?\w+::\w+\)?)/m', '<i>\1</i>', $v[2]);
914
915 echo '<tr><td class="date column-date" data-sort-value="'.$v[0].'"><span class="logLabel date">'.$date.'</span></td>' .
916 '<td class="column-level">'.$levels[$v[1]].'</td>' .
917 '<td class="column-entry">'.(empty($v[3]) ? '<pre>'.$v[2].'</pre>' : '<div class="expander" title="Click to Expand"><pre>'.$v[2].'</pre><div><span class="dashicons dashicons-arrow-down-alt2"></span></div></div><div class="spoiler-body"><pre>'.$v[3].'</pre></div>').'</td>' .
918 '</tr>'.PHP_EOL;
919 } ?>
920 </tbody>
921 </table>
922 <div class="tablenav bottom">
923 <div class="alignright bulkactions">
924 <button class="button action clearLog" name = '<?php echo DG_OPTION_NAME; ?>[clearLog]' value = 'true'>
925 <?php echo __('Clear Log', 'document-gallery'); ?>
926 </button>
927 </div>
928 </div>
929 </div>
930 </div>
931 <?php } else {
932 echo '<div class="noLog">'.__('There are no log entries at this time.', 'document-gallery').'<br />'.__('For Your information:', 'document-gallery').' <strong><i>'.__('Logging', 'document-gallery').'</i></strong> '.(DG_Logger::logEnabled()?'<span class="loggingON">'.__('is turned ON', 'document-gallery').'!</span>':'<span class="loggingOFF">'.__('is turned OFF', 'document-gallery').'!</span>').'</div>';
933 }
934 }
935
936 /**
937 * Takes label name and returns SPAN tag.
938 * @param string $e label name.
939 * @return string SPAN tag
940 */
941 private static function getLogLabelSpan($e) {
942 return '<span class="logLabel ' . strtolower($e) . '">' . strtoupper($e) . '</span>';
943 }
944
945 /**
946 * Render a checkbox field.
947 * @param array $args
948 */
949 public static function renderCheckboxField($args) {
950 $args['disabled'] = isset($args['disabled']) ? $args['disabled'] : false;
951 printf('<label><input type="checkbox" value="1" name="%1$s[%2$s]" id="%3$s" %4$s %5$s/> %6$s</label>',
952 $args['option_name'],
953 $args['name'],
954 $args['label_for'],
955 checked($args['value'], 1, false),
956 $args['disabled'] ? 'disabled="disabled"' : '',
957 $args['description']);
958 }
959
960 /**
961 * Render a text field.
962 * @param array $args
963 */
964 public static function renderTextField($args) {
965 printf('<input type="%1$s" value="%2$s" name="%3$s[%4$s]" id="%5$s" /> %6$s',
966 isset($args['type']) ? $args['type'] : 'text',
967 $args['value'],
968 $args['option_name'],
969 $args['name'],
970 $args['label_for'],
971 $args['description']);
972 }
973
974 /**
975 * Accepts a two-dimensional array where each inner array consists of valid arguments for renderTextField.
976 * @param array $args
977 */
978 public static function renderMultiTextField($args) {
979 foreach ($args as $arg) {
980 self::renderTextField($arg);
981 }
982 }
983
984 /**
985 * Render a select field.
986 * @param array $args
987 */
988 public static function renderSelectField($args) {
989 printf('<select name="%1$s[%2$s]" id="%3$s">',
990 $args['option_name'],
991 $args['name'],
992 $args['label_for']);
993
994 foreach ($args['options'] as $val) {
995 printf('<option value="%1$s" %2$s>%3$s</option>',
996 $val,
997 selected($val, $args['value'], false),
998 $val,
999 $args['description']);
1000 }
1001
1002 print '</select> ' . $args['description'];
1003 }
1004
1005 /**
1006 * Wraps the PHP exit language construct.
1007 */
1008 public static function _exit() {
1009 exit;
1010 }
1011
1012 /**
1013 * Blocks instantiation. All functions are static.
1014 */
1015 private function __construct() {
1016
1017 }
1018 }