PluginProbe
Document Gallery / 2.2.2
Document Gallery v2.2.2
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.2.2, at admin/class-admin.php

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