PluginProbe
Document Gallery / 3.2
Document Gallery v3.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 3.2, at admin/class-admin.php

1,314 lines 56.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
75 return $links;
76 }
77
78 /**
79 * Adds donate link to main plugin view.
80 */
81 public static function addDonateLink($links, $file) {
82 if ($file === DG_BASENAME) {
83 global $dg_options;
84
85 $donate = '<strong><a href="' . $dg_options['meta']['donate_link'] . '">' .
86 __('Donate', 'document-gallery') . '</a></strong>';
87 $links[] = $donate;
88 }
89
90 return $links;
91 }
92
93 /**
94 * Adds Document Gallery settings page to admin navigation.
95 */
96 public static function addAdminPage() {
97 DG_Admin::$hook = add_options_page(
98 __('Document Gallery Settings', 'document-gallery'),
99 __('Document Gallery', 'document-gallery'),
100 'manage_options', DG_OPTION_NAME, array(__CLASS__, 'renderOptions'));
101 add_action('admin_enqueue_scripts', array(__CLASS__, 'enqueueScriptsAndStyles'));
102 }
103
104 /**
105 * Enqueues styles and scripts for the admin settings page.
106 */
107 public static function enqueueScriptsAndStyles($hook) {
108 if ($hook === DG_Admin::$hook) {
109 // Settings Page
110 wp_enqueue_style('document-gallery-admin', DG_URL . 'assets/css/admin.css', null, DG_VERSION);
111
112 // gracefully degrade for older WP versions
113 if (version_compare(get_bloginfo('version'), '3.8', '<')) {
114 echo '<style type="text/css">.dashicons, .nav-tab:before, .deleteSelected:before, .clearLog:before, .expandAll:before, .collapseAll:before, .logLabel.date:before, .collapser:after, .expander:after, #ThumbsTable .title a:after, #LogTable>tbody a:after {display: none !important;}</style>' . PHP_EOL;
115 }
116
117 wp_enqueue_script('document-gallery-admin', DG_URL . 'assets/js/admin.js', array('jquery'), DG_VERSION, true);
118 wp_localize_script('document-gallery-admin', 'dg_admin_vars', array('upload_limit' => wp_max_upload_size()));
119 if ($hook == 'post.php') {
120 wp_localize_script('document-gallery-admin', 'ajax_object', array('ajax_url' => admin_url('admin-ajax.php')));
121
122 // Media Manager
123 global $dg_options;
124 wp_enqueue_script('document-gallery-media-manager', DG_URL . 'assets/js/media_manager.js', array('media-views'), DG_VERSION, true);
125 wp_localize_script( 'document-gallery-media-manager', 'DGl10n', array(
126 'documentGalleryMenuTitle' => __('Create Document Gallery', 'document-gallery'),
127 'documentGalleryButton' => __('Create a new Document Gallery', 'document-gallery'),
128 'cancelDocumentGalleryTitle' => __('&#8592; Cancel Document Gallery', 'document-gallery'),
129 'updateDocumentGallery' => __('Update Document Gallery', 'document-gallery'),
130 'insertDocumentGallery' => __('Insert Document Gallery', 'document-gallery'),
131 'addToDocumentGallery' => __('Add to Document Gallery', 'document-gallery'),
132 'addToDocumentGalleryTitle' => __('Add to Document Gallery', 'document-gallery'),
133 'editDocumentGalleryTitle' => __('Edit Document Gallery', 'document-gallery')
134 ) );
135 wp_localize_script('document-gallery-media-manager', 'documentGalleryDefaults', $dg_options['gallery']);
136 }
137 }
138 }
139
140 /**
141 * Load Document Gallery Custom templates.
142 */
143 public static function loadCustomTemplates() {
144 include_once DG_PATH . 'admin/media-manager-template.php';
145 }
146
147 /**
148 * Registers settings for the Document Gallery options page.
149 */
150 public static function registerSettings() {
151 if (empty($_REQUEST['tab']) || !array_key_exists($_REQUEST['tab'], self::getTabs())) {
152 reset(self::getTabs());
153 self::$current = key(self::getTabs());
154 } else {
155 self::$current = $_REQUEST['tab'];
156 }
157
158 register_setting(DG_OPTION_NAME, DG_OPTION_NAME, array(__CLASS__, 'validateSettings'));
159
160 $funct = 'register' . self::$current . 'Settings';
161 DG_Admin::$funct();
162 }
163
164 /**
165 * Registers settings for the general tab.
166 */
167 private static function registerGeneralSettings() {
168 global $dg_options;
169
170 include_once DG_PATH . 'inc/class-gallery.php';
171 include_once DG_PATH . 'inc/class-thumber.php';
172
173 $defaults = $dg_options['gallery'];
174 $active = $dg_options['thumber']['active'];
175
176 add_settings_section(
177 'gallery_defaults', __('Default Settings', 'document-gallery'),
178 array(__CLASS__, 'renderDefaultSettingsSection'), DG_OPTION_NAME);
179
180 add_settings_section(
181 'thumbnail_generation', __('Thumbnail Generation', 'document-gallery'),
182 array(__CLASS__, 'renderThumberSection'), DG_OPTION_NAME);
183
184 add_settings_section(
185 'css', __('Custom CSS', 'document-gallery'),
186 array(__CLASS__, 'renderCssSection'), DG_OPTION_NAME);
187
188 add_settings_field(
189 'gallery_defaults_attachment_pg', 'attachment_pg',
190 array(__CLASS__, 'renderCheckboxField'),
191 DG_OPTION_NAME, 'gallery_defaults',
192 array (
193 'label_for' => 'label_gallery_defaults_attachment_pg',
194 'name' => 'gallery_defaults][attachment_pg',
195 'value' => esc_attr($defaults['attachment_pg']),
196 'option_name' => DG_OPTION_NAME,
197 'description' => __('Link to attachment page rather than to file', 'document-gallery')
198 ));
199
200 add_settings_field(
201 'gallery_defaults_columns', 'columns',
202 array(__CLASS__, 'renderTextField'),
203 DG_OPTION_NAME, 'gallery_defaults',
204 array (
205 'label_for' => 'label_gallery_defaults_columns',
206 'name' => 'gallery_defaults][columns',
207 'value' => esc_attr($defaults['columns']),
208 'type' => 'number" min="1" step="1',
209 'option_name' => DG_OPTION_NAME,
210 'description' => __('The number of columns to display when not rendering descriptions.', 'document-gallery')
211 ));
212
213 add_settings_field(
214 'gallery_defaults_descriptions', 'descriptions',
215 array(__CLASS__, 'renderCheckboxField'),
216 DG_OPTION_NAME, 'gallery_defaults',
217 array (
218 'label_for' => 'label_gallery_defaults_descriptions',
219 'name' => 'gallery_defaults][descriptions',
220 'value' => esc_attr($defaults['descriptions']),
221 'option_name' => DG_OPTION_NAME,
222 'description' => __('Include document descriptions', 'document-gallery')
223 ));
224
225 add_settings_field(
226 'gallery_defaults_fancy', 'fancy',
227 array(__CLASS__, 'renderCheckboxField'),
228 DG_OPTION_NAME, 'gallery_defaults',
229 array (
230 'label_for' => 'label_gallery_defaults_fancy',
231 'name' => 'gallery_defaults][fancy',
232 'value' => esc_attr($defaults['fancy']),
233 'option_name' => DG_OPTION_NAME,
234 'description' => __('Use auto-generated document thumbnails', 'document-gallery')
235 ));
236
237 add_settings_field(
238 'gallery_defaults_order', 'order',
239 array(__CLASS__, 'renderSelectField'),
240 DG_OPTION_NAME, 'gallery_defaults',
241 array (
242 'label_for' => 'label_gallery_defaults_order',
243 'name' => 'gallery_defaults][order',
244 'value' => esc_attr($defaults['order']),
245 'options' => DG_Gallery::getOrderOptions(),
246 'option_name' => DG_OPTION_NAME,
247 'description' => __('Ascending or descending sorting of documents', 'document-gallery')
248 ));
249
250 add_settings_field(
251 'gallery_defaults_orderby', 'orderby',
252 array(__CLASS__, 'renderSelectField'),
253 DG_OPTION_NAME, 'gallery_defaults',
254 array (
255 'label_for' => 'label_gallery_defaults_orderby',
256 'name' => 'gallery_defaults][orderby',
257 'value' => esc_attr($defaults['orderby']),
258 'options' => DG_Gallery::getOrderbyOptions(),
259 'option_name' => DG_OPTION_NAME,
260 'description' => __('Which field to order documents by', 'document-gallery')
261 ));
262
263 add_settings_field(
264 'gallery_defaults_relation', 'relation',
265 array(__CLASS__, 'renderSelectField'),
266 DG_OPTION_NAME, 'gallery_defaults',
267 array (
268 'label_for' => 'label_gallery_defaults_relation',
269 'name' => 'gallery_defaults][relation',
270 'value' => esc_attr($defaults['relation']),
271 'options' => DG_Gallery::getRelationOptions(),
272 'option_name' => DG_OPTION_NAME,
273 'description' => __('Whether matched documents must have all taxa_names (AND) or at least one (OR)', 'document-gallery')
274 ));
275
276 add_settings_field(
277 'gallery_defaults_limit', 'limit',
278 array(__CLASS__, 'renderTextField'),
279 DG_OPTION_NAME, 'gallery_defaults',
280 array (
281 'label_for' => 'label_gallery_defaults_limit',
282 'name' => 'gallery_defaults][limit',
283 'value' => esc_attr($defaults['limit']),
284 'type' => 'number" min="-1" step="1',
285 'option_name' => DG_OPTION_NAME,
286 'description' => __('Limit the number of documents included. -1 means no limit.', 'document-gallery')
287 ));
288
289 add_settings_field(
290 'gallery_defaults_mime_types', 'mime_types',
291 array(__CLASS__, 'renderTextField'),
292 DG_OPTION_NAME, 'gallery_defaults',
293 array (
294 'label_for' => 'label_gallery_defaults_mime_types',
295 'name' => 'gallery_defaults][mime_types',
296 'value' => esc_attr($defaults['mime_types']),
297 'type' => 'text',
298 'option_name' => DG_OPTION_NAME,
299 'description' => __('Comma-delimited list of <a href="http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types">MIME types</a>.', 'document-gallery')
300 ));
301
302 add_settings_field(
303 'gallery_defaults_new_window', 'new_window',
304 array(__CLASS__, 'renderCheckboxField'),
305 DG_OPTION_NAME, 'gallery_defaults',
306 array (
307 'label_for' => 'label_gallery_defaults_new_window',
308 'name' => 'gallery_defaults][new_window',
309 'value' => esc_attr($defaults['new_window']),
310 'option_name' => DG_OPTION_NAME,
311 'description' => __('Open thumbnail links in new window.', 'document-gallery')
312 ));
313
314 add_settings_field(
315 'gallery_defaults_post_status', 'post_status',
316 array(__CLASS__, 'renderSelectField'),
317 DG_OPTION_NAME, 'gallery_defaults',
318 array (
319 'label_for' => 'label_gallery_defaults_post_status',
320 'name' => 'gallery_defaults][post_status',
321 'value' => esc_attr($defaults['post_status']),
322 'options' => DG_Gallery::getPostStatuses(),
323 'option_name' => DG_OPTION_NAME,
324 'description' => __('Which post status to look for when querying documents.', 'document-gallery')
325 ));
326
327 add_settings_field(
328 'gallery_defaults_post_type', 'post_type',
329 array(__CLASS__, 'renderSelectField'),
330 DG_OPTION_NAME, 'gallery_defaults',
331 array (
332 'label_for' => 'label_gallery_defaults_post_type',
333 'name' => 'gallery_defaults][post_type',
334 'value' => esc_attr($defaults['post_type']),
335 'options' => DG_Gallery::getPostTypes(),
336 'option_name' => DG_OPTION_NAME,
337 'description' => __('Which post type to look for when querying documents.', 'document-gallery')
338 ));
339
340 add_settings_field(
341 'thumbnail_generation_av', __('Audio/Video', 'document-gallery'),
342 array(__CLASS__, 'renderCheckboxField'),
343 DG_OPTION_NAME, 'thumbnail_generation',
344 array (
345 'label_for' => 'label_thumbnail_generation_av',
346 'name' => 'thumbnail_generation][av',
347 'value' => esc_attr($active['av']),
348 'option_name' => DG_OPTION_NAME,
349 'description' => esc_html__('Locally generate thumbnails for audio & video files.', 'document-gallery')
350 ));
351
352 add_settings_field(
353 'thumbnail_generation_gs', 'Ghostscript',
354 array(__CLASS__, 'renderCheckboxField'),
355 DG_OPTION_NAME, 'thumbnail_generation',
356 array (
357 'label_for' => 'label_thumbnail_generation_gs',
358 'name' => 'thumbnail_generation][gs',
359 'value' => esc_attr($active['gs']),
360 'option_name' => DG_OPTION_NAME,
361 'description' => DG_Thumber::isGhostscriptAvailable()
362 ? __('Use <a href="http://www.ghostscript.com/" target="_blank">Ghostscript</a> for faster local PDF processing (compared to Imagick).', 'document-gallery')
363 : __('Your server is not configured to run <a href="http://www.ghostscript.com/" target="_blank">Ghostscript</a>.', 'document-gallery'),
364 'disabled' => !DG_Thumber::isGhostscriptAvailable()
365 ));
366
367 add_settings_field(
368 'thumbnail_generation_imagick', 'Imagick',
369 array(__CLASS__, 'renderCheckboxField'),
370 DG_OPTION_NAME, 'thumbnail_generation',
371 array (
372 'label_for' => 'label_thumbnail_generation_imagick',
373 'name' => 'thumbnail_generation][imagick',
374 'value' => esc_attr($active['imagick']),
375 'option_name' => DG_OPTION_NAME,
376 'description' => DG_Thumber::isImagickAvailable()
377 ? __('Use <a href="http://www.php.net/manual/en/book.imagick.php" target="_blank">Imagick</a> to handle lots of filetypes locally.', 'document-gallery')
378 : __('Your server is not configured to run <a href="http://www.php.net/manual/en/book.imagick.php" target="_blank">Imagick</a>.', 'document-gallery'),
379 'disabled' => !DG_Thumber::isImagickAvailable()
380 ));
381
382 add_settings_field(
383 'thumbnail_generation_width', __('Max Thumbnail Dimensions', 'document-gallery'),
384 array(__CLASS__, 'renderMultiTextField'),
385 DG_OPTION_NAME, 'thumbnail_generation',
386 array (
387 array (
388 'label_for' => 'label_advanced_width',
389 'name' => 'thumbnail_generation][width',
390 'value' => esc_attr($dg_options['thumber']['width']),
391 'type' => 'number" min="1" step="1',
392 'option_name' => DG_OPTION_NAME,
393 'description' => ' x '),
394 array (
395 'label_for' => 'label_advanced_height',
396 'name' => 'thumbnail_generation][height',
397 'value' => esc_attr($dg_options['thumber']['height']),
398 'type' => 'number" min="1" step="1',
399 'option_name' => DG_OPTION_NAME,
400 'description' => __('The max width and height (in pixels) that thumbnails will be generated.', 'document-gallery'))
401 ));
402 }
403
404 /**
405 * Registers settings for the thumbnail management tab.
406 */
407 private static function registerThumbnailSettings() {
408 add_settings_section(
409 'thumbnail_table', '',
410 array(__CLASS__, 'renderThumbnailSection'), DG_OPTION_NAME);
411 }
412
413 /**
414 * Registers settings for the logging tab.
415 */
416 private static function registerLoggingSettings() {
417 add_settings_section(
418 'logging_table', '',
419 array(__CLASS__, 'renderLoggingSection'), DG_OPTION_NAME);
420 }
421
422 /**
423 * Registers settings for the advanced tab.
424 */
425 private static function registerAdvancedSettings() {
426 global $dg_options;
427
428 add_settings_section(
429 'advanced', __('Advanced Thumbnail Generation', 'document-gallery'),
430 array(__CLASS__, 'renderAdvancedSection'), DG_OPTION_NAME);
431
432 add_settings_field(
433 'advanced_logging_enabled', __('Logging Enabled', 'document-gallery'),
434 array(__CLASS__, 'renderCheckboxField'),
435 DG_OPTION_NAME, 'advanced',
436 array (
437 'label_for' => 'label_advanced_logging_enabled',
438 'name' => 'logging_enabled',
439 'value' => esc_attr($dg_options['logging']['enabled']),
440 'option_name' => DG_OPTION_NAME,
441 'description' => __('Whether to log debug and error information related to Document Gallery.', 'document-gallery')
442 ));
443
444 add_settings_field(
445 'advanced_logging_purge_interval', __('Logging Purge Interval', 'document-gallery'),
446 array(__CLASS__, 'renderTextField'),
447 DG_OPTION_NAME, 'advanced',
448 array (
449 'label_for' => 'label_advanced_logging_purge_interval',
450 'name' => 'logging_purge_interval',
451 'value' => esc_attr($dg_options['logging']['purge_interval']),
452 'type' => 'number" min="0" step="1',
453 'option_name' => DG_OPTION_NAME,
454 'description' => __('Number of days to keep old log entries (0 disables purging).', 'document-gallery')
455 ));
456
457 add_settings_field(
458 'advanced_validation', __('Option Validation', 'document-gallery'),
459 array(__CLASS__, 'renderCheckboxField'),
460 DG_OPTION_NAME, 'advanced',
461 array (
462 'label_for' => 'label_advanced_validation',
463 'name' => 'validation',
464 'value' => esc_attr($dg_options['validation']),
465 'option_name' => DG_OPTION_NAME,
466 'description' => __('Whether option structure should be validated before save. This is not generally necessary.', 'document-gallery')
467 ));
468
469 add_settings_field(
470 'advanced_thumb_timeout', __('Thumbnail Generation Timeout', 'document-gallery'),
471 array(__CLASS__, 'renderTextField'),
472 DG_OPTION_NAME, 'advanced',
473 array (
474 'label_for' => 'label_advanced_thumb_timeout',
475 'name' => 'timeout',
476 'value' => esc_attr($dg_options['thumber']['timeout']),
477 'type' => 'number" min="1" step="1',
478 'option_name' => DG_OPTION_NAME,
479 'description' => __('Max number of seconds to wait for thumbnail generation before defaulting to filetype icons.', 'document-gallery') .
480 ' <em>' . __('Note that generation will continue where timeout happened next time the gallery is loaded.', 'document-gallery') . '</em>'));
481
482 add_settings_field(
483 'advanced_gs', __('Ghostscript Absolute Path', 'document-gallery'),
484 array(__CLASS__, 'renderTextField'),
485 DG_OPTION_NAME, 'advanced',
486 array (
487 'label_for' => 'label_advanced_gs',
488 'name' => 'gs',
489 'value' => esc_attr($dg_options['thumber']['gs']),
490 'option_name' => DG_OPTION_NAME,
491 'description' => $dg_options['thumber']['gs']
492 ? __('Successfully auto-detected the location of Ghostscript.', 'document-gallery')
493 : __('Failed to auto-detect the location of Ghostscript.', 'document-gallery')
494 ));
495
496 add_settings_section(
497 'advanced_options_dump', __('Options Array Dump', 'document-gallery'),
498 array(__CLASS__, 'renderOptionsDumpSection'), DG_OPTION_NAME);
499 }
500
501 /**
502 * Validates submitted options, sanitizing any invalid options.
503 * @param array $values User-submitted new options.
504 * @return array Sanitized new options.
505 */
506 public static function validateSettings($values) {
507 // NOTE: WP double-calls this function -- below logic prevents potential
508 // side effects by processing a maximum of one call to validate
509 // per page load, re-returning the previous result on any
510 // subsequent calls.
511 static $ret = null;
512 if (is_null($ret)) {
513 if (empty($values['tab']) || !array_key_exists($values['tab'], self::getTabs())) {
514 reset(self::getTabs());
515 $values['tab'] = key(self::getTabs());
516 }
517 $funct = 'validate'.$values['tab'].'Settings';
518 unset($values['tab']);
519 $ret = DG_Admin::$funct($values);
520 }
521
522 return $ret;
523 }
524
525 /**
526 * Validates general settings, sanitizing any invalid options.
527 * @param array $values User-submitted new options.
528 * @return array Sanitized new options.
529 */
530 private static function validateGeneralSettings($values) {
531 global $dg_options;
532 $ret = $dg_options;
533
534 include_once DG_PATH . 'inc/class-gallery.php';
535
536 $thumbs_cleared = false;
537
538 // handle gallery shortcode defaults
539 $errs = array();
540 $ret['gallery'] = DG_Gallery::sanitizeDefaults(null, $values['gallery_defaults'], $errs);
541
542 foreach ($errs as $k => $v) {
543 add_settings_error(DG_OPTION_NAME, str_replace('_', '-', $k), $v);
544 }
545
546 // handle setting width
547 if (isset($values['thumbnail_generation']['width'])) {
548 $width = (int)$values['thumbnail_generation']['width'];
549 if ($width > 0) {
550 $ret['thumber']['width'] = $width;
551 } else {
552 add_settings_error(DG_OPTION_NAME, 'thumber-width',
553 __('Invalid width given: ', 'document-gallery') . $values['thumbnail_generation']['width']);
554 }
555
556 unset($values['thumbnail_generation']['width']);
557 }
558
559 // handle setting height
560 if (isset($values['thumbnail_generation']['height'])) {
561 $height = (int)$values['thumbnail_generation']['height'];
562 if ($height > 0) {
563 $ret['thumber']['height'] = $height;
564 } else {
565 add_settings_error(DG_OPTION_NAME, 'thumber-height',
566 __('Invalid height given: ', 'document-gallery') . $values['thumbnail_generation']['height']);
567 }
568
569 unset($values['thumbnail_generation']['width']);
570 }
571
572 // delete thumb cache to force regeneration if max dimensions changed
573 if ($ret['thumber']['width'] !== $dg_options['thumber']['width'] ||
574 $ret['thumber']['height'] !== $dg_options['thumber']['height']) {
575 foreach ($ret['thumber']['thumbs'] as $v) {
576 if (isset($v['thumber'])) {
577 @unlink($v['thumb_path']);
578 }
579 }
580
581 $ret['thumber']['thumbs'] = array();
582 $thumbs_cleared = true;
583 }
584
585 // handle setting the active thumbers
586 foreach (array_keys($ret['thumber']['active']) as $k) {
587 $ret['thumber']['active'][$k] = isset($values['thumbnail_generation'][$k]);
588 }
589
590 // if new thumbers available, clear failed thumbnails for retry
591 if (!$thumbs_cleared) {
592 foreach ($dg_options['thumber']['active'] as $k => $v) {
593 if (!$v && $ret['thumber']['active'][$k]) {
594 foreach ($dg_options['thumber']['thumbs'] as $k => $v) {
595 if (empty($v['thumber'])) {
596 unset($ret['thumber']['thumbs'][$k]);
597 }
598 }
599 break;
600 }
601 }
602 }
603
604 // handle modified CSS
605 if (trim($ret['css']['text']) !== trim($values['css'])) {
606 $ret['css']['text'] = trim($values['css']);
607 $ret['css']['minified'] = DocumentGallery::compileCustomCss($ret['css']['text']);
608 }
609
610 return $ret;
611 }
612
613 /**
614 * Validates thumbnail management settings, sanitizing any invalid options.
615 * @param array $values User-submitted new options.
616 * @return array Sanitized new options.
617 */
618 private static function validateThumbnailSettings($values) {
619 global $dg_options;
620 $ret = $dg_options;
621 $responseArr = array('result' => false);
622
623 if (isset($values['entry'])) {
624 $ID = intval($values['entry']);
625 } else {
626 $ID = -1;
627 }
628
629 // Thumbnail(s) cleanup;
630 // cleanup value is a marker
631 if ( isset($values['cleanup']) && isset($values['ids']) ) {
632 $deleted = array_values(array_intersect(array_keys($dg_options['thumber']['thumbs']), $values['ids']));
633
634 foreach ($deleted as $k) {
635 if (isset($ret['thumber']['thumbs'][$k]['thumber'])) {
636 @unlink($ret['thumber']['thumbs'][$k]['thumb_path']);
637 }
638
639 unset($ret['thumber']['thumbs'][$k]);
640 }
641
642 $responseArr['result'] = true;
643 $responseArr['deleted'] = $deleted;
644 }
645
646 // Attachment title update
647 // title value is a marker
648 elseif ( isset($values['title']) && $ID != -1 ) {
649 $attachment = array(
650 'ID' => $ID,
651 'post_title' => rawurldecode(addslashes($values['title']))
652 );
653 if ( wp_update_post( $attachment ) ) {
654 $responseArr['result'] = true;
655 }
656 }
657
658 // Attachment description update
659 // description value is a marker
660 elseif ( isset($values['description']) && $ID != -1 ) {
661 $attachment = array(
662 'ID' => $ID,
663 'post_content' => rawurldecode(addslashes($values['description']))
664 );
665 if ( wp_update_post( $attachment ) ) {
666 $responseArr['result'] = true;
667 }
668 }
669
670 // Thumbnail file manual refresh (one at a time)
671 // upload value is a marker
672 elseif ( isset($values['upload']) && isset($_FILES['file']) && isset($ret['thumber']['thumbs'][$ID]) ) {
673 $old_path = $ret['thumber']['thumbs'][$ID]['thumb_path'];
674 $uploaded_filename = self::validateUploadedFile();
675 if ($uploaded_filename && DG_Thumber::setThumbnail($ID, $uploaded_filename)) {
676 if ($dg_options['thumber']['thumbs'][$ID]['thumb_path'] !== $old_path) {
677 @unlink($old_path);
678 }
679 $responseArr['result'] = true;
680 $responseArr['url'] = $dg_options['thumber']['thumbs'][$ID]['thumb_url'];
681 $ret['thumber']['thumbs'][$ID] = $dg_options['thumber']['thumbs'][$ID];
682 }
683 }
684
685 if (isset($values['ajax'])) {
686 echo DG_Util::jsonEncode($responseArr);
687 add_filter('wp_redirect', array(__CLASS__, '_exit'), 1, 0);
688 }
689
690 return $ret;
691 }
692
693 /**
694 * Validates uploaded file as a semi for potential thumbnail.
695 * @param str $var File field name.
696 * @return bool|str False on failure, path to temp file on success.
697 */
698 public static function validateUploadedFile($var = 'file') {
699 // checking if any file was delivered
700 if (!isset($_FILES[$var]))
701 return false;
702 // we gonna process only first one
703 if ( !is_array($_FILES[$var]['error']) ) {
704 $upload_err = $_FILES[$var]['error'];
705 $upload_path = $_FILES[$var]['tmp_name'];
706 $upload_size = $_FILES[$var]['size'];
707 $upload_type = $_FILES[$var]['type'];
708 $upload_name = $_FILES[$var]['name'];
709 } else {
710 $upload_err = $_FILES[$var]['error'][0];
711 $upload_path = $_FILES[$var]['tmp_name'][0];
712 $upload_size = $_FILES[$var]['size'][0];
713 $upload_type = $_FILES[$var]['type'][0];
714 $upload_name = $_FILES[$var]['name'][0];
715 }
716 $info = getimagesize($upload_path);
717 if ($info) {
718 if ($info['mime']!=$upload_type) {// in DG_Thumber::getExt() we'll define and set appropriate extension
719 DG_Logger::writeLog(
720 DG_LogLevel::Warning,
721 __('File extension doesn\'t match the MIME type of the image: ', 'document-gallery') .
722 $upload_name.' - '.$info['mime']);
723 }
724 if ($upload_size>wp_max_upload_size()) {
725 DG_Logger::writeLog(
726 DG_LogLevel::Warning,
727 __('Uploaded file size exceeds the allowable limit: ', 'document-gallery') .
728 $upload_name.' - '.$upload_size.'b');
729 return false;
730 }
731 } else {
732 DG_Logger::writeLog(
733 DG_LogLevel::Warning,
734 __('Uploaded file is not an image: ', 'document-gallery') .
735 $upload_name);
736 return false;
737 }
738 if ($upload_err == UPLOAD_ERR_OK && $upload_size > 0) {
739 $temp_file = $upload_path;
740 } else {
741 DG_Logger::writeLog(
742 DG_LogLevel::Error,
743 __('Failed to get uploaded file: ', 'document-gallery') .
744 $upload_err);
745 return false;
746 }
747
748 return $temp_file;
749 }
750
751 /**
752 * Validates logging settings, sanitizing any invalid options.
753 * @param array $values User-submitted new options.
754 * @return array Sanitized new options.
755 */
756 private static function validateLoggingSettings($values) {
757 global $dg_options;
758 if (isset($values['clearLog'])) {
759 DG_Logger::clearLog();
760 }
761 return $dg_options;
762 }
763
764 /**
765 * Validates advanced settings, sanitizing any invalid options.
766 * @param array $values User-submitted new options.
767 * @return array Sanitized new options.
768 */
769 private static function validateAdvancedSettings($values) {
770 global $dg_options;
771 $ret = $dg_options;
772
773 // handle setting the Ghostscript path
774 if (isset($values['gs']) &&
775 0 != strcmp($values['gs'], $ret['thumber']['gs'])) {
776 if (false === strpos($values['gs'], ';')) {
777 $ret['thumber']['gs'] = $values['gs'];
778 } else {
779 add_settings_error(DG_OPTION_NAME, 'thumber-gs',
780 __('Invalid Ghostscript path given: ', 'document-gallery') . $values['gs']);
781 }
782 }
783
784 // handle setting timeout
785 if (isset($values['timeout'])) {
786 $timeout = (int)$values['timeout'];
787 if ($timeout > 0) {
788 $ret['thumber']['timeout'] = $timeout;
789 } else {
790 add_settings_error(DG_OPTION_NAME, 'thumber-timeout',
791 __('Invalid timeout given: ', 'document-gallery') . $values['timeout']);
792 }
793 }
794
795 // validation checkbox
796 $ret['validation'] = isset($values['validation']);
797
798 // logging settings
799 $ret['logging']['enabled'] = isset($values['logging_enabled']);
800 if (isset($values['logging_purge_interval'])) {
801 $purge_interval = (int)$values['logging_purge_interval'];
802 if ($purge_interval >= 0) {
803 $ret['logging']['purge_interval'] = $purge_interval;
804 } else {
805 add_settings_error(DG_OPTION_NAME, 'thumber-logging-purge-interval',
806 __('Invalid logging purge interval given: ', 'document-gallery') . $values['logging_purge_interval']);
807 }
808 }
809
810 return $ret;
811 }
812
813 /**
814 * @return bool Whether to register settings.
815 */
816 public static function doRegisterSettings() {
817 if (!is_multisite()) {
818 $script = !empty($GLOBALS['pagenow']) ? $GLOBALS['pagenow'] : null;
819 } else {
820 $script = parse_url($_SERVER['REQUEST_URI']);
821 $script = basename($script['path']);
822 }
823
824 return !empty($script) && ('options-general.php' === $script || 'options.php' === $script);
825 }
826
827 /**
828 * Render the Default Settings section.
829 */
830 public static function renderDefaultSettingsSection() { ?>
831 <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>
832 <?php }
833
834 /**
835 * Render the Thumber section.
836 */
837 public static function renderThumberSection() { ?>
838 <p><?php _e('Select which tools to use when generating thumbnails.', 'document-gallery'); ?></p>
839 <?php }
840
841 /**
842 * Renders a text field for use when modifying the CSS to be printed in addition to the default CSS.
843 */
844 public static function renderCssSection() {
845 global $dg_options; ?>
846 <p><?php printf(
847 __('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>.'),
848 DG_URL . 'assets/css/style.css'); ?></p>
849 <table class="form-table">
850 <tbody>
851 <tr valign="top">
852 <td>
853 <textarea name="<?php echo DG_OPTION_NAME; ?>[css]" rows="10" cols="50" class="large-text code"><?php echo $dg_options['css']['text']; ?></textarea>
854 </td>
855 </tr>
856 </tbody>
857 </table>
858 <?php }
859
860 /**
861 * Render the Thumber Advanced section.
862 */
863 public static function renderAdvancedSection() {
864 include_once DG_PATH . 'inc/class-thumber.php';?>
865 <p><?php _e('Unless you <em>really</em> know what you\'re doing, you should not touch these values.', 'document-gallery'); ?></p>
866 <?php if (!DG_Thumber::isExecAvailable()) : ?>
867 <p>
868 <em><?php _e('NOTE: <code>exec()</code> is not accessible. Ghostscript will not function.', 'document-gallery'); ?></em>
869 </p>
870 <?php endif; ?>
871 <?php }
872
873 /**
874 * Renders a readonly textfield containing a dump of current DG options.
875 */
876 public static function renderOptionsDumpSection() {
877 global $dg_options; ?>
878 <p><?php
879 _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');
880 ?></p>
881 <table class="form-table">
882 <tbody>
883 <tr valign="top">
884 <td>
885 <textarea readonly="true" rows="10" cols="50" id="options-dump" class="large-text code"><?php print_r($dg_options); ?></textarea>
886 </td>
887 </tr>
888 </tbody>
889 </table>
890 <?php }
891
892 /**
893 * Render the Thumbnail table.
894 */
895 public static function renderThumbnailSection() {
896 include_once DG_PATH . 'inc/class-thumber.php';
897 $options = DG_Thumber::getOptions();
898
899 $URL_params = array('page' => DG_OPTION_NAME, 'tab' => 'Thumbnail');
900 $att_ids = array();
901
902 if (isset($_REQUEST['orderby']) && in_array(strtolower($_REQUEST['orderby']), array('title', 'date'))) {
903 $orderby = strtolower($_REQUEST['orderby']);
904 $URL_params['orderby'] = $orderby;
905
906 switch ($orderby) {
907 case 'date':
908 foreach ($options['thumbs'] as $key => $node) {
909 $keyArray[$key] = $node['timestamp'];
910 $options['thumbs'][$key]['thumb_id'] = $att_ids[] = $key;
911 }
912 break;
913
914 case 'title':
915 foreach ($options['thumbs'] as $key => $node) {
916 $keyArray[$key] = basename($node['thumb_path']);
917 $options['thumbs'][$key]['thumb_id'] = $att_ids[] = $key;
918 }
919 break;
920 }
921
922 $order = strtolower($_REQUEST['order']);
923 if (!isset($_REQUEST['order']) || !in_array($order, array('asc', 'desc'))) {
924 $order = 'asc';
925 }
926 $URL_params['order'] = $order;
927
928 if ($order == 'asc') {
929 array_multisort($keyArray, SORT_ASC, $options['thumbs']);
930 } else {
931 array_multisort($keyArray, SORT_DESC, $options['thumbs']);
932 }
933 } else {
934 $orderby = '';
935 foreach ($options['thumbs'] as $key => $node) {
936 $options['thumbs'][$key]['thumb_id'] = $att_ids[] = $key;
937 }
938 }
939
940 static $limit_options = array(10, 25, 75);
941 if (!isset($_REQUEST['limit']) || !in_array(intval($_REQUEST['limit']), $limit_options)) {
942 $limit = $limit_options[0];
943 } else {
944 $limit = intval($_REQUEST['limit']);
945 }
946
947 $URL_params['limit'] = $limit;
948 $select_limit = '';
949 foreach ($limit_options as $l_o) {
950 $select_limit .= '<option value="'.$l_o.'"'.selected($limit, $l_o, false).'>'.$l_o.'</option>'.PHP_EOL;
951 }
952 $thumbs_number = count($options['thumbs']);
953 $lastsheet = ceil($thumbs_number/$limit);
954 $sheet = isset($_REQUEST['sheet']) ? intval($_REQUEST['sheet']) : 1;
955 if ($sheet <= 0 || $sheet > $lastsheet) {
956 $sheet = 1;
957 }
958
959 $offset = ($sheet - 1) * $limit;
960
961 $att_ids = array_slice($att_ids, $offset, $limit);
962
963 // https://core.trac.wordpress.org/ticket/12212
964 $atts = array();
965 if (!empty($att_ids)) {
966 $atts = get_posts(
967 array(
968 'post_type' => 'any',
969 'post_status' => 'any',
970 'numberposts' => -1,
971 'post__in' => $att_ids,
972 'orderby' => 'post__in'
973 ));
974 }
975
976 $titles = array();
977 $contents = array();
978 foreach ($atts as $att) {
979 $path_parts = pathinfo($att->guid);
980 $titles[$att->ID] = $att->post_title;
981 $types[$att->ID] = $path_parts['extension'];
982 $contents[$att->ID] = $att->post_content;
983 }
984 unset($atts);
985
986 $thead = '<tr>'.
987 '<th scope="col" class="manage-column column-cb check-column">'.
988 '<label class="screen-reader-text" for="cb-select-all-%1$d">'.__('Select All', 'document-gallery').'</label>'.
989 '<input id="cb-select-all-%1$d" type="checkbox">'.
990 '</th>'.
991 '<th scope="col" class="manage-column column-icon">'.__('Thumbnail', 'document-gallery').'</th>'.
992 '<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>'.
993 '<th scope="col" class="manage-column column-description">'.__('Description', 'document-gallery').'</th>'.
994 '<th scope="col" class="manage-column column-thumbupload"></th>'.
995 '<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>'.
996 '</tr>';
997
998 $pagination = '<div class="alignleft bulkactions"><button class="button action deleteSelected">'.__('Delete Selected', 'document-gallery').'</button></div><div class="tablenav-pages">'.
999 '<span class="displaying-num">'.
1000 $thumbs_number.' '._n('item', 'items', $thumbs_number).
1001 '</span>'.($lastsheet>1?
1002 '<span class="pagination-links">'.
1003 '<a class="first-page'.( $sheet==1 ? ' disabled' : '').'" title="'.__('Go to the first page', 'document-gallery').'"'.( $sheet==1 ? '' : ' href="?'.http_build_query($URL_params).'"').'>«</a>'.
1004 '<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>'.
1005 '<span class="paging-input">'.
1006 '<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>'.
1007 '<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>'.
1008 '<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>'.
1009 '</span>':' <b>|</b> ').
1010 '<span class="displaying-num"><select dir="rtl" class="limit_per_page">'.$select_limit.'</select> '.__('items per page', 'document-gallery').'</span>'.
1011 '</div>'.
1012 '<br class="clear" />';
1013 ?>
1014
1015 <script type="text/javascript">
1016 var URL_params = <?php echo DG_Util::jsonEncode($URL_params); ?>;
1017 </script>
1018 <div class="thumbs-list-wrapper">
1019 <div>
1020 <div class="tablenav top"><?php echo $pagination; ?></div>
1021 <table id="ThumbsTable" class="wp-list-table widefat fixed media"
1022 cellpadding="0" cellspacing="0">
1023 <thead>
1024 <?php printf($thead, 1); ?>
1025 </thead>
1026 <tfoot>
1027 <?php printf($thead, 2); ?>
1028 </tfoot>
1029 <tbody><?php
1030 $i = 0;
1031 foreach ($options['thumbs'] as $v) {
1032 if ($i < $offset) { $i++; continue; }
1033 if (++$i > $offset + $limit) { break; }
1034
1035 $icon = isset($v['thumb_url']) ? $v['thumb_url'] : DG_Thumber::getDefaultThumbnail($v['thumb_id']);
1036 $title = isset($titles[$v['thumb_id']]) ? $titles[$v['thumb_id']] : '';
1037 $type = $types[$v['thumb_id']];
1038 $description = $contents[$v['thumb_id']];
1039 $date = DocumentGallery::localDateTimeFromTimestamp($v['timestamp']);
1040
1041 echo '<tr data-entry="'.$v['thumb_id'].'"><td scope="row" class="check-column"><input type="checkbox" class="cb-ids" name="' . DG_OPTION_NAME . '[ids][]" value="' .
1042 $v['thumb_id'].'"></td><td class="column-icon media-icon"><img src="' .
1043 $icon.'" />'.'</td><td class="title column-title">' .
1044 ($title ? '<strong><a href="' . home_url('/?attachment_id='.$v['thumb_id']).'" target="_blank" title="'.__('View', 'document-gallery').' \'' .
1045 $title.'\' '.__('attachment page', 'document-gallery').'"><span class="editable-title">'.$title.'</span> <sup>'.$type.'</sup></a></strong>' : __('Attachment not found', 'document-gallery')) .
1046 '<span class="dashicons dashicons-edit"></span><span class="edit-controls"><span class="dashicons dashicons-yes"></span> <span class="dashicons dashicons-no"></span></span></td><td class="column-description"><div class="editable-description">'.$description.'</div><span class="dashicons dashicons-edit"></span><span class="edit-controls"><span class="dashicons dashicons-yes"></span> <span class="dashicons dashicons-no"></span></span>'. '</td><td class="column-thumbupload">' .
1047 '<span class="manual-download">' .
1048 '<span class="dashicons dashicons-upload"></span>' .
1049 '<span class="html5dndmarker">Drop file here<span> or </span></span>' .
1050 '<span class="buttons-area">' .
1051 '<input id="upload-button'.$v['thumb_id'].'" type="file" />' .
1052 '<input id="trigger-button'.$v['thumb_id'].'" type="button" value="Select File" class="button" />' .
1053 '</span>' .
1054 '</span>' .
1055 '</td><td class="date column-date">'.$date.'</td></tr>'.PHP_EOL;
1056 } ?>
1057 </tbody>
1058 </table>
1059 <div class="tablenav bottom"><?php echo $pagination; ?></div>
1060 </div>
1061 </div>
1062 <?php }
1063
1064 /**
1065 * Adds meta box to the attchements' edit pages.
1066 */
1067 public static function addMetaBox() {
1068 $screens = array( 'attachment' );
1069 foreach ( $screens as $screen ) {
1070 add_meta_box(
1071 DG_OPTION_NAME.'_gen_box',
1072 __( '<b>Thumbnail</b> for <i><b>Document Gallery</b></i>', 'document-gallery' ),
1073 array(__CLASS__, 'renderMetaBox'),
1074 $screen,
1075 'normal'
1076 );
1077 }
1078 DG_Admin::$hook = 'post.php';
1079 add_action('admin_enqueue_scripts', array(__CLASS__, 'enqueueScriptsAndStyles'));
1080 }
1081
1082 /**
1083 * Render a Meta Box.
1084 */
1085 public static function renderMetaBox($post) {
1086 global $dg_options;
1087 wp_nonce_field( DG_OPTION_NAME.'_meta_box', DG_OPTION_NAME.'_meta_box_nonce' );
1088 $ID = $post->ID;
1089 $icon = isset($dg_options['thumber']['thumbs'][$ID]['thumb_url']) ? $dg_options['thumber']['thumbs'][$ID]['thumb_url'] : DG_Thumber::getDefaultThumbnail($ID);
1090
1091 echo '<table id="ThumbsTable" class="wp-list-table widefat fixed media" cellpadding="0" cellspacing="0">'.
1092 '<tbody><tr data-entry="'.$ID.'"><td class="column-icon media-icon"><img src="' .
1093 $icon.'" />'.'</td><td class="column-thumbupload">' .
1094 '<span class="manual-download">' .
1095 '<span class="dashicons dashicons-upload"></span>' .
1096 '<span class="html5dndmarker">Drop file here<span> or </span></span>' .
1097 '<span class="buttons-area">' .
1098 '<input id="upload-button'.$ID.'" type="file" />' .
1099 '<input id="trigger-button'.$ID.'" type="button" value="Select File" class="button" />' .
1100 '</span>' .
1101 '</span>' .
1102 '</td></tr></tbody></table>'.
1103 (empty($dg_options['thumber']['thumbs'][$ID]) ? '<span class="dashicons dashicons-info"></span><span class="">Please note this attachment hasn&#39;t been used in any Document Gallery instance and so there is no autogenerated thumbnail, in the meantime default one is used instead.</span>' : '').PHP_EOL;
1104 }
1105
1106 /**
1107 * Save a Meta Box.
1108 */
1109 public static function saveMetaBox($post_id) {
1110 // Check if our nonce is set.
1111 // Verify that the nonce is valid.
1112 // If this is an autosave, our form has not been submitted, so we don't want to do anything.
1113 if ( !isset($_POST[DG_OPTION_NAME.'_meta_box_nonce']) || !wp_verify_nonce($_POST[DG_OPTION_NAME.'_meta_box_nonce'], DG_OPTION_NAME.'_meta_box') || (defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE) ) {
1114 return;
1115 }
1116
1117 global $dg_options;
1118 $responseArr = array('result' => false);
1119 if (isset($_POST[DG_OPTION_NAME]['entry'])) {
1120 $ID = intval($_POST[DG_OPTION_NAME]['entry']);
1121 } else {
1122 $ID = -1;
1123 }
1124 if ( isset($_POST[DG_OPTION_NAME]['upload']) && isset($_FILES['file']) && isset($dg_options['thumber']['thumbs'][$ID]) ) {
1125 $old_path = $dg_options['thumber']['thumbs'][$ID]['thumb_path'];
1126 $uploaded_filename = self::validateUploadedFile();
1127 if ($uploaded_filename && DG_Thumber::setThumbnail($ID, $uploaded_filename)) {
1128 if ($dg_options['thumber']['thumbs'][$ID]['thumb_path'] !== $old_path) {
1129 @unlink($old_path);
1130 }
1131 $responseArr['result'] = true;
1132 $responseArr['url'] = $dg_options['thumber']['thumbs'][$ID]['thumb_url'];
1133 }
1134 }
1135 if (isset($_POST[DG_OPTION_NAME]['ajax'])) {
1136 echo DG_Util::jsonEncode($responseArr);
1137 wp_die();
1138 }
1139 }
1140
1141 /**
1142 * Render the Logging table.
1143 */
1144 public static function renderLoggingSection() {
1145 $log_list = DG_Logger::readLog();
1146 if ($log_list) {
1147 $levels = array_map(array(__CLASS__, 'getLogLabelSpan'), array_keys(DG_LogLevel::getLogLevels()));
1148
1149 $fmt =
1150 '<tr>' .
1151 '<th scope="col" class="manage-column column-date sorted desc"><a href="javascript:void(0);">' .
1152 '<span>%s</span><span class="sorting-indicator"></span></a>' .
1153 '</th>' .
1154 '<th scope="col" class="manage-column column-level"><span>%s</span></th>' .
1155 '<th scope="col" class="manage-column column-message"><span>%s</span></th>' .
1156 '</tr>';
1157
1158 $thead = sprintf($fmt,
1159 __('Date', 'document-gallery'),
1160 __('Level', 'document-gallery'),
1161 __('Message', 'document-gallery'));
1162
1163 ?>
1164 <div class="log-list-wrapper">
1165 <div>
1166 <div class="tablenav top">
1167 <div class="alignleft bulkactions">
1168 <button class="action expandAll">
1169 <?php echo __('Expand All', 'document-gallery'); ?>
1170 </button>
1171 <button class="action collapseAll">
1172 <?php echo __('Collapse All', 'document-gallery'); ?>
1173 </button>
1174 </div>
1175 <div class="levelSelector">
1176 <input type="checkbox" id="allLevels" name="lswitch" value="all" checked />
1177 <label for="allLevels" class="allLevels">ALL</label>
1178 <?php
1179 foreach (array_keys(DG_LogLevel::getLogLevels()) as $k) { ?>
1180 <?php
1181 $lower = strtolower($k);
1182 $upper = strtoupper($k);
1183 ?>
1184 <input type="checkbox" id="<?php echo $lower; ?>Level" name="lswitch" value="<?php echo $lower; ?>" checked />
1185 <label for="<?php echo $lower; ?>Level" class="<?php echo $lower; ?>Level"><?php echo $upper; ?></label>
1186 <?php }
1187 ?>
1188 </div>
1189 </div>
1190 <table id="LogTable" class="wp-list-table widefat fixed media" cellpadding="0" cellspacing="0">
1191 <thead>
1192 <?php echo $thead; ?>
1193 </thead>
1194 <tfoot>
1195 <?php echo $thead; ?>
1196 </tfoot>
1197 <tbody><?php
1198 for ($i = count($log_list); $i > 0; $i--) {
1199 $log_entry = $log_list[$i - 1];
1200 $date = DocumentGallery::localDateTimeFromTimestamp($log_entry[0]);
1201
1202 // convert attachment names to links
1203 $log_entry[2] = preg_replace('/[ ^](attachment #)(\d+)[., ]/i', ' <a href="' . home_url() . '/?attachment_id=\2" target="_blank">\1<strong>\2</strong></a> ', $log_entry[2]);
1204
1205 // bold the place where log entry was submitted
1206 $log_entry[2] = preg_replace('/^(\(\w+::\w+\)) /', '<strong>\1</strong> ', $log_entry[2]);
1207
1208 // italicize any function references within log entry
1209 $log_entry[2] = preg_replace('/(\(?\w+::\w+\)?)/m', '<i>\1</i>', $log_entry[2]);
1210
1211 echo '<tr><td class="date column-date" data-sort-value="'.$log_entry[0].'"><span class="logLabel date">'.$date.'</span></td>' .
1212 '<td class="column-level">'.$levels[$log_entry[1]].'</td>' .
1213 '<td class="column-entry">'.(empty($log_entry[3]) ? '<pre>'.$log_entry[2].'</pre>' : '<div class="expander" title="Click to Expand"><pre>'.$log_entry[2].'</pre><div><span class="dashicons dashicons-arrow-down-alt2"></span></div></div><div class="spoiler-body"><pre>'.$log_entry[3].'</pre></div>').'</td>' .
1214 '</tr>'.PHP_EOL;
1215 } ?>
1216 </tbody>
1217 </table>
1218 <div class="tablenav bottom">
1219 <div class="alignright bulkactions">
1220 <button class="button action clearLog" name = '<?php echo DG_OPTION_NAME; ?>[clearLog]' value = 'true'>
1221 <?php echo __('Clear Log', 'document-gallery'); ?>
1222 </button>
1223 </div>
1224 </div>
1225 </div>
1226 </div>
1227 <?php } else {
1228 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>';
1229 }
1230 }
1231
1232 /**
1233 * Takes label name and returns SPAN tag.
1234 * @param string $e label name.
1235 * @return string SPAN tag
1236 */
1237 private static function getLogLabelSpan($e) {
1238 return '<span class="logLabel ' . strtolower($e) . '">' . strtoupper($e) . '</span>';
1239 }
1240
1241 /**
1242 * Render a checkbox field.
1243 * @param array $args
1244 */
1245 public static function renderCheckboxField($args) {
1246 $args['disabled'] = isset($args['disabled']) ? $args['disabled'] : false;
1247 printf('<label><input type="checkbox" value="1" name="%1$s[%2$s]" id="%3$s" %4$s %5$s/> %6$s</label>',
1248 $args['option_name'],
1249 $args['name'],
1250 $args['label_for'],
1251 checked($args['value'], 1, false),
1252 disabled($args['disabled'], true, false),
1253 $args['description']);
1254 }
1255
1256 /**
1257 * Render a text field.
1258 * @param array $args
1259 */
1260 public static function renderTextField($args) {
1261 printf('<input type="%1$s" value="%2$s" name="%3$s[%4$s]" id="%5$s" /> %6$s',
1262 isset($args['type']) ? $args['type'] : 'text',
1263 $args['value'],
1264 $args['option_name'],
1265 $args['name'],
1266 $args['label_for'],
1267 $args['description']);
1268 }
1269
1270 /**
1271 * Accepts a two-dimensional array where each inner array consists of valid arguments for renderTextField.
1272 * @param array $args
1273 */
1274 public static function renderMultiTextField($args) {
1275 foreach ($args as $arg) {
1276 self::renderTextField($arg);
1277 }
1278 }
1279
1280 /**
1281 * Render a select field.
1282 * @param array $args
1283 */
1284 public static function renderSelectField($args) {
1285 printf('<select name="%1$s[%2$s]" id="%3$s">',
1286 $args['option_name'],
1287 $args['name'],
1288 $args['label_for']);
1289
1290 foreach ($args['options'] as $val) {
1291 printf('<option value="%1$s" %2$s>%3$s</option>',
1292 $val,
1293 selected($val, $args['value'], false),
1294 $val,
1295 $args['description']);
1296 }
1297
1298 print '</select> ' . $args['description'];
1299 }
1300
1301 /**
1302 * Wraps the PHP exit language construct.
1303 */
1304 public static function _exit() {
1305 exit;
1306 }
1307
1308 /**
1309 * Blocks instantiation. All functions are static.
1310 */
1311 private function __construct() {
1312
1313 }
1314 }