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

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