Document Gallery - Version 3.1

Version Description

  • Enhancement: The Media Manager can now be used to generate a gallery without needing to manually write the shortcode.
  • Enhancement: Document Gallery logs can now be rolled over at regular intervals to avoid generating massive log files over extended periods of time.
Download this release

Release Info

Developer dan.rossiter
Plugin Icon 128x128 Document Gallery
Version 3.1
Comparing to
See all releases

Code changes from version 3.0.2 to 3.1

README.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: dan.rossiter, demur
3
  Tags: attachments, thumbnail, documents, gallery, MS office, pdf
4
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=EE5LWRLG933EN&lc=US&item_name=Document%20Gallery%20Plugin&item_number=document%2dgallery&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted
5
  Requires at least: 3.6
6
- Tested up to: 4.1.1
7
- Stable tag: 3.0.2
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -194,9 +194,8 @@ taxa match (OR).
194
  *NOTE: This has no bearing on the relationship between different terms for a single
195
  taxon (eg: `[dg category=x,y,z relation=AND]` will return any attachments where the
196
  category is x, y, OR z). If you wish to return only attachments with all 3 categories,
197
- you will instead need to use the following syntax:
198
- `[dg category=x,y,z category_relation=AND]`. This syntax of *taxon*_relation will
199
- work for any taxon, not just "category."*
200
 
201
  = Customize Appearance =
202
 
@@ -249,8 +248,8 @@ Each of the following filters provides an bool argument which indicates
249
  whither the gallery being generated will display descriptions, which
250
  allows you to handle galleries with and without descriptions differently.
251
 
252
- If you wish to wrap your galleries in some additional content, the
253
- `dg_gallery_template` is the tool for the job. With it you can include
254
  content prior to or following your document galleries. The filter
255
  exposes 1 special tag which is replaced during gallery generation
256
  with data specific to that gallery. The tag is described below:
@@ -270,8 +269,8 @@ These tags are as follows:
270
  * **%icons%**: The icon data for this row.
271
 
272
 
273
- If you wish to modify the HTML that wraps individual icons, the
274
- `dg_icon_template` filter is what you will use. The filter is passed
275
  two arguments which may be used to gain additional information about
276
  the document that will be used in generating this icon. The first
277
  argument is a bool value which indicates whether descriptions will
@@ -388,8 +387,8 @@ change is saved, the Ghostscript checkbox should be enabled on the first tab.
388
  = Q: Why are all of my document icons in a single column? =
389
 
390
  A: Assuming that you do not have the `columns` attribute set to 1, the likely cause
391
- of this behavior is that descriptions are enabled. To fix this, simply use
392
- `[dg descriptions=false]`.
393
 
394
  = Q: Why is [insert thumbnail generation method] enabled on one of my WordPress installs, but not on another one? =
395
 
@@ -414,13 +413,17 @@ returning our thumbnail.
414
 
415
  == Screenshots ==
416
 
417
- 1. This is an example of "fancy" thumbnails. The images are a copy of the front
 
 
 
 
418
  page for each document.
419
- 2. This is an example of multiple Document Galleries on a single page (using
420
  the `ids` attribute). It also shows how images will appear in a Document
421
  Gallery. Note that the description field supports HTML markup, so the
422
  possibilities are endless!
423
- 3. This is how the Document Gallery looks with `descriptions=false` (default).
424
  Note that the display inherits styling from your active theme.
425
 
426
  == Changelog ==
@@ -431,6 +434,16 @@ To see a list of features planned for the future as well as to propose your own
431
  ideas for future Document Gallery development, take a look at our
432
  [issue tracker](https://github.com/thenadz/document-gallery/issues).
433
 
 
 
 
 
 
 
 
 
 
 
434
  = 3.0.2 =
435
  * **Bug Fix:** The update process was broken in 3.0 -- this resolves that issue.
436
 
3
  Tags: attachments, thumbnail, documents, gallery, MS office, pdf
4
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=EE5LWRLG933EN&lc=US&item_name=Document%20Gallery%20Plugin&item_number=document%2dgallery&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted
5
  Requires at least: 3.6
6
+ Tested up to: 4.2.2
7
+ Stable tag: 3.1
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
194
  *NOTE: This has no bearing on the relationship between different terms for a single
195
  taxon (eg: `[dg category=x,y,z relation=AND]` will return any attachments where the
196
  category is x, y, OR z). If you wish to return only attachments with all 3 categories,
197
+ you will instead need to use the following syntax: `[dg category=x,y,z category_relation=AND]`.
198
+ This syntax of *taxon*_relation will work for any taxon, not just "category."*
 
199
 
200
  = Customize Appearance =
201
 
248
  whither the gallery being generated will display descriptions, which
249
  allows you to handle galleries with and without descriptions differently.
250
 
251
+ If you wish to wrap your galleries in some additional content,
252
+ the `dg_gallery_template` is the tool for the job. With it you can include
253
  content prior to or following your document galleries. The filter
254
  exposes 1 special tag which is replaced during gallery generation
255
  with data specific to that gallery. The tag is described below:
269
  * **%icons%**: The icon data for this row.
270
 
271
 
272
+ If you wish to modify the HTML that wraps individual icons,
273
+ the `dg_icon_template` filter is what you will use. The filter is passed
274
  two arguments which may be used to gain additional information about
275
  the document that will be used in generating this icon. The first
276
  argument is a bool value which indicates whether descriptions will
387
  = Q: Why are all of my document icons in a single column? =
388
 
389
  A: Assuming that you do not have the `columns` attribute set to 1, the likely cause
390
+ of this behavior is that descriptions are enabled. To fix this, simply add `descriptions=false`
391
+ (eg: `[dg descriptions=false]`).
392
 
393
  = Q: Why is [insert thumbnail generation method] enabled on one of my WordPress installs, but not on another one? =
394
 
413
 
414
  == Screenshots ==
415
 
416
+ 1. Document Gallery integrates directly with the WordPress Media Manager.
417
+ 2. The common configuration options are directly accessible through the Media Manager
418
+ interface, but additional configuration can be manually added to the generated
419
+ shortcode.
420
+ 3. This is an example of "fancy" thumbnails. The images are a copy of the front
421
  page for each document.
422
+ 4. This is an example of multiple Document Galleries on a single page (using
423
  the `ids` attribute). It also shows how images will appear in a Document
424
  Gallery. Note that the description field supports HTML markup, so the
425
  possibilities are endless!
426
+ 5. This is how the Document Gallery looks with `descriptions=false` (default).
427
  Note that the display inherits styling from your active theme.
428
 
429
  == Changelog ==
434
  ideas for future Document Gallery development, take a look at our
435
  [issue tracker](https://github.com/thenadz/document-gallery/issues).
436
 
437
+ = 3.2 =
438
+ * **Enhancement:** The long awaited option to open thumbnail links in a new window
439
+ has been added. Simply use `[dg new_window=true]`.
440
+
441
+ = 3.1 =
442
+ * **Enhancement:** The Media Manager can now be used to generate a gallery without
443
+ needing to manually write the shortcode.
444
+ * **Enhancement:** Document Gallery logs can now be rolled over at regular intervals
445
+ to avoid generating massive log files over extended periods of time.
446
+
447
  = 3.0.2 =
448
  * **Bug Fix:** The update process was broken in 3.0 -- this resolves that issue.
449
 
admin/class-admin.php CHANGED
@@ -105,15 +105,44 @@ class DG_Admin {
105
  * Enqueues styles and scripts for the admin settings page.
106
  */
107
  public static function enqueueScriptsAndStyles($hook) {
108
- if ($hook !== DG_Admin::$hook) return;
109
-
110
- wp_enqueue_style('document-gallery-admin', DG_URL . 'assets/css/admin.css', null, DG_VERSION);
111
- wp_enqueue_script('document-gallery-admin', DG_URL . 'assets/js/admin.js', array('jquery'), DG_VERSION, true);
112
- wp_localize_script('document-gallery-admin', 'dg_admin_vars', array('upload_limit' => wp_max_upload_size()));
113
- if ($hook == 'post.php') {
114
- wp_localize_script('document-gallery-admin', 'ajax_object', array('ajax_url' => admin_url('admin-ajax.php')));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  }
116
  }
 
 
 
 
 
 
 
117
 
118
  /**
119
  * Registers settings for the Document Gallery options page.
@@ -297,7 +326,7 @@ class DG_Admin {
297
  ));
298
 
299
  add_settings_field(
300
- 'thumbnail_generation_av', 'Audio/Video',
301
  array(__CLASS__, 'renderCheckboxField'),
302
  DG_OPTION_NAME, 'thumbnail_generation',
303
  array (
@@ -339,7 +368,7 @@ class DG_Admin {
339
  ));
340
 
341
  add_settings_field(
342
- 'thumbnail_generation_width', 'Max Thumbnail Dimensions',
343
  array(__CLASS__, 'renderMultiTextField'),
344
  DG_OPTION_NAME, 'thumbnail_generation',
345
  array (
@@ -389,19 +418,32 @@ class DG_Admin {
389
  array(__CLASS__, 'renderAdvancedSection'), DG_OPTION_NAME);
390
 
391
  add_settings_field(
392
- 'advanced_logging', 'Logging',
393
  array(__CLASS__, 'renderCheckboxField'),
394
  DG_OPTION_NAME, 'advanced',
395
  array (
396
- 'label_for' => 'label_advanced_logging',
397
- 'name' => 'logging',
398
- 'value' => esc_attr($dg_options['logging']),
399
  'option_name' => DG_OPTION_NAME,
400
  'description' => __('Whether to log debug and error information related to Document Gallery.', 'document-gallery')
401
  ));
402
 
403
  add_settings_field(
404
- 'advanced_validation', 'Option Validation',
 
 
 
 
 
 
 
 
 
 
 
 
 
405
  array(__CLASS__, 'renderCheckboxField'),
406
  DG_OPTION_NAME, 'advanced',
407
  array (
@@ -413,7 +455,7 @@ class DG_Admin {
413
  ));
414
 
415
  add_settings_field(
416
- 'advanced_thumb_timeout', 'Thumbnail Generation Timeout',
417
  array(__CLASS__, 'renderTextField'),
418
  DG_OPTION_NAME, 'advanced',
419
  array (
@@ -426,7 +468,7 @@ class DG_Admin {
426
  ' <em>' . __('Note that generation will continue where timeout happened next time the gallery is loaded.', 'document-gallery') . '</em>'));
427
 
428
  add_settings_field(
429
- 'advanced_gs', 'Ghostscript Absolute Path',
430
  array(__CLASS__, 'renderTextField'),
431
  DG_OPTION_NAME, 'advanced',
432
  array (
@@ -450,13 +492,22 @@ class DG_Admin {
450
  * @return array Sanitized new options.
451
  */
452
  public static function validateSettings($values) {
453
- if (empty($values['tab']) || !array_key_exists($values['tab'], self::getTabs())) {
454
- reset(self::getTabs());
455
- $values['tab'] = key(self::getTabs());
 
 
 
 
 
 
 
 
 
 
456
  }
457
- $funct = 'validate'.$values['tab'].'Settings';
458
- unset($values['tab']);
459
- return DG_Admin::$funct($values);
460
  }
461
 
462
  /**
@@ -732,8 +783,17 @@ class DG_Admin {
732
  // validation checkbox
733
  $ret['validation'] = isset($values['validation']);
734
 
735
- // logging checkbox
736
- $ret['logging'] = isset($values['logging']);
 
 
 
 
 
 
 
 
 
737
 
738
  return $ret;
739
  }
@@ -1074,11 +1134,19 @@ class DG_Admin {
1074
  if ($log_list) {
1075
  $levels = array_map(array(__CLASS__, 'getLogLabelSpan'), array_keys(DG_LogLevel::getLogLevels()));
1076
 
1077
- $thead = '<tr>'.
1078
- '<th scope="col" class="manage-column column-date"><span>'.__('Date', 'document-gallery').'</span></th>'.
1079
- '<th scope="col" class="manage-column column-level"><span>'.__('Level', 'document-gallery').'</span></th>'.
1080
- '<th scope="col" class="manage-column column-message"><span>'.__('Message', 'document-gallery').'</span></th>'.
 
 
 
1081
  '</tr>';
 
 
 
 
 
1082
 
1083
  ?>
1084
  <div class="log-list-wrapper">
@@ -1115,22 +1183,22 @@ class DG_Admin {
1115
  <?php echo $thead; ?>
1116
  </tfoot>
1117
  <tbody><?php
1118
- $i = 0;
1119
- foreach ($log_list as $v) {
1120
- $date = DocumentGallery::localDateTimeFromTimestamp($v[0]);
1121
 
1122
  // convert attachment names to links
1123
- $v[2] = preg_replace('/[ ^](attachment #)(\d+)[., ]/i', ' <a href="' . home_url() . '/?attachment_id=\2" target="_blank">\1<strong>\2</strong></a> ', $v[2]);
1124
 
1125
  // bold the place where log entry was submitted
1126
- $v[2] = preg_replace('/^(\(\w+::\w+\)) /', '<strong>\1</strong> ', $v[2]);
1127
 
1128
  // italicize any function references within log entry
1129
- $v[2] = preg_replace('/(\(?\w+::\w+\)?)/m', '<i>\1</i>', $v[2]);
1130
 
1131
- echo '<tr><td class="date column-date" data-sort-value="'.$v[0].'"><span class="logLabel date">'.$date.'</span></td>' .
1132
- '<td class="column-level">'.$levels[$v[1]].'</td>' .
1133
- '<td class="column-entry">'.(empty($v[3]) ? '<pre>'.$v[2].'</pre>' : '<div class="expander" title="Click to Expand"><pre>'.$v[2].'</pre><div><span class="dashicons dashicons-arrow-down-alt2"></span></div></div><div class="spoiler-body"><pre>'.$v[3].'</pre></div>').'</td>' .
1134
  '</tr>'.PHP_EOL;
1135
  } ?>
1136
  </tbody>
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.
326
  ));
327
 
328
  add_settings_field(
329
+ 'thumbnail_generation_av', __('Audio/Video', 'document-gallery'),
330
  array(__CLASS__, 'renderCheckboxField'),
331
  DG_OPTION_NAME, 'thumbnail_generation',
332
  array (
368
  ));
369
 
370
  add_settings_field(
371
+ 'thumbnail_generation_width', __('Max Thumbnail Dimensions', 'document-gallery'),
372
  array(__CLASS__, 'renderMultiTextField'),
373
  DG_OPTION_NAME, 'thumbnail_generation',
374
  array (
418
  array(__CLASS__, 'renderAdvancedSection'), DG_OPTION_NAME);
419
 
420
  add_settings_field(
421
+ 'advanced_logging_enabled', __('Logging Enabled', 'document-gallery'),
422
  array(__CLASS__, 'renderCheckboxField'),
423
  DG_OPTION_NAME, 'advanced',
424
  array (
425
+ 'label_for' => 'label_advanced_logging_enabled',
426
+ 'name' => 'logging_enabled',
427
+ 'value' => esc_attr($dg_options['logging']['enabled']),
428
  'option_name' => DG_OPTION_NAME,
429
  'description' => __('Whether to log debug and error information related to Document Gallery.', 'document-gallery')
430
  ));
431
 
432
  add_settings_field(
433
+ 'advanced_logging_purge_interval', __('Logging Purge Interval', 'document-gallery'),
434
+ array(__CLASS__, 'renderTextField'),
435
+ DG_OPTION_NAME, 'advanced',
436
+ array (
437
+ 'label_for' => 'label_advanced_logging_purge_interval',
438
+ 'name' => 'logging_purge_interval',
439
+ 'value' => esc_attr($dg_options['logging']['purge_interval']),
440
+ 'type' => 'number" min="0" step="1',
441
+ 'option_name' => DG_OPTION_NAME,
442
+ 'description' => __('Number of days to keep old log entries (0 disables purging).', 'document-gallery')
443
+ ));
444
+
445
+ add_settings_field(
446
+ 'advanced_validation', __('Option Validation', 'document-gallery'),
447
  array(__CLASS__, 'renderCheckboxField'),
448
  DG_OPTION_NAME, 'advanced',
449
  array (
455
  ));
456
 
457
  add_settings_field(
458
+ 'advanced_thumb_timeout', __('Thumbnail Generation Timeout', 'document-gallery'),
459
  array(__CLASS__, 'renderTextField'),
460
  DG_OPTION_NAME, 'advanced',
461
  array (
468
  ' <em>' . __('Note that generation will continue where timeout happened next time the gallery is loaded.', 'document-gallery') . '</em>'));
469
 
470
  add_settings_field(
471
+ 'advanced_gs', __('Ghostscript Absolute Path', 'document-gallery'),
472
  array(__CLASS__, 'renderTextField'),
473
  DG_OPTION_NAME, 'advanced',
474
  array (
492
  * @return array Sanitized new options.
493
  */
494
  public static function validateSettings($values) {
495
+ // NOTE: WP double-calls this function -- below logic prevents potential
496
+ // side effects by processing a maximum of one call to validate
497
+ // per page load, re-returning the previous result on any
498
+ // subsequent calls.
499
+ static $ret = null;
500
+ if (is_null($ret)) {
501
+ if (empty($values['tab']) || !array_key_exists($values['tab'], self::getTabs())) {
502
+ reset(self::getTabs());
503
+ $values['tab'] = key(self::getTabs());
504
+ }
505
+ $funct = 'validate'.$values['tab'].'Settings';
506
+ unset($values['tab']);
507
+ $ret = DG_Admin::$funct($values);
508
  }
509
+
510
+ return $ret;
 
511
  }
512
 
513
  /**
783
  // validation checkbox
784
  $ret['validation'] = isset($values['validation']);
785
 
786
+ // logging settings
787
+ $ret['logging']['enabled'] = isset($values['logging_enabled']);
788
+ if (isset($values['logging_purge_interval'])) {
789
+ $purge_interval = (int)$values['logging_purge_interval'];
790
+ if ($purge_interval >= 0) {
791
+ $ret['logging']['purge_interval'] = $purge_interval;
792
+ } else {
793
+ add_settings_error(DG_OPTION_NAME, 'thumber-logging-purge-interval',
794
+ __('Invalid logging purge interval given: ', 'document-gallery') . $values['logging_purge_interval']);
795
+ }
796
+ }
797
 
798
  return $ret;
799
  }
1134
  if ($log_list) {
1135
  $levels = array_map(array(__CLASS__, 'getLogLabelSpan'), array_keys(DG_LogLevel::getLogLevels()));
1136
 
1137
+ $fmt =
1138
+ '<tr>' .
1139
+ '<th scope="col" class="manage-column column-date sorted desc"><a href="javascript:void(0);">' .
1140
+ '<span>%s</span><span class="sorting-indicator"></span></a>' .
1141
+ '</th>' .
1142
+ '<th scope="col" class="manage-column column-level"><span>%s</span></th>' .
1143
+ '<th scope="col" class="manage-column column-message"><span>%s</span></th>' .
1144
  '</tr>';
1145
+
1146
+ $thead = sprintf($fmt,
1147
+ __('Date', 'document-gallery'),
1148
+ __('Level', 'document-gallery'),
1149
+ __('Message', 'document-gallery'));
1150
 
1151
  ?>
1152
  <div class="log-list-wrapper">
1183
  <?php echo $thead; ?>
1184
  </tfoot>
1185
  <tbody><?php
1186
+ for ($i = count($log_list); $i > 0; $i--) {
1187
+ $log_entry = $log_list[$i - 1];
1188
+ $date = DocumentGallery::localDateTimeFromTimestamp($log_entry[0]);
1189
 
1190
  // convert attachment names to links
1191
+ $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]);
1192
 
1193
  // bold the place where log entry was submitted
1194
+ $log_entry[2] = preg_replace('/^(\(\w+::\w+\)) /', '<strong>\1</strong> ', $log_entry[2]);
1195
 
1196
  // italicize any function references within log entry
1197
+ $log_entry[2] = preg_replace('/(\(?\w+::\w+\)?)/m', '<i>\1</i>', $log_entry[2]);
1198
 
1199
+ echo '<tr><td class="date column-date" data-sort-value="'.$log_entry[0].'"><span class="logLabel date">'.$date.'</span></td>' .
1200
+ '<td class="column-level">'.$levels[$log_entry[1]].'</td>' .
1201
+ '<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>' .
1202
  '</tr>'.PHP_EOL;
1203
  } ?>
1204
  </tbody>
admin/media-manager-template.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php /* Custom templates into the DOM */
2
+ include_once DG_PATH . 'inc/class-gallery.php';
3
+ ?>
4
+ <script type="text/html" id="tmpl-document-gallery-settings">
5
+ <h3><?php _e('Document Gallery Settings'); ?></h3>
6
+
7
+ <label class="setting">
8
+ <table><tr>
9
+ <td><span><?php _e('Link To'); ?></span></td>
10
+ <td><select class="link-to" data-setting="attachment_pg">
11
+ <option value="false" <# if ( !documentGalleryDefaults.attachment_pg ) { #>selected="selected"<# } #>>
12
+ <?php esc_attr_e('Media File'); ?>
13
+ </option>
14
+ <option value="true" <# if ( documentGalleryDefaults.attachment_pg ) { #>selected="selected"<# } #>>
15
+ <?php esc_attr_e('Attachment Page'); ?>
16
+ </option>
17
+ </select></td>
18
+ </tr></table>
19
+ </label>
20
+
21
+ <label class="setting">
22
+ <table><tr>
23
+ <td><span><?php _e('Columns'); ?></span></td>
24
+ <td><select class="columns" name="columns" data-setting="columns">
25
+ <option value="-1" <#
26
+ if ( '-1' == documentGalleryDefaults.columns ) { #>selected="selected"<# }
27
+ #>>
28
+ &infin;
29
+ </option>
30
+ <?php for ( $i = 1; $i <= 9; $i++ ) : ?>
31
+ <option value="<?php echo esc_attr( $i ); ?>" <#
32
+ if ( <?php echo $i ?> == documentGalleryDefaults.columns ) { #>selected="selected"<# }
33
+ #>>
34
+ <?php echo esc_html( $i ); ?>
35
+ </option>
36
+ <?php endfor; ?>
37
+ </select></td>
38
+ </tr></table>
39
+ </label>
40
+
41
+ <label class="setting">
42
+ <table><tr>
43
+ <td><span><?php _e('Include document descriptions', 'document-gallery'); ?></span></td>
44
+ <td><input type="checkbox" data-setting="descriptions" <# if ( documentGalleryDefaults.descriptions ) { #>checked="checked"<# } #>/></td>
45
+ </tr></table>
46
+ </label>
47
+
48
+ <label class="setting">
49
+ <table><tr>
50
+ <td><span><?php _e('Use auto-generated document thumbnails', 'document-gallery'); ?></span></td>
51
+ <td><input type="checkbox" data-setting="fancy" <# if ( documentGalleryDefaults.fancy ) { #>checked="checked"<# } #>/></td>
52
+ </tr></table>
53
+ </label>
54
+
55
+ <label class="setting">
56
+ <table><tr>
57
+ <td><span><?php _e('Which field to order documents by', 'document-gallery'); ?></span></td>
58
+ <td><select class="DGorderby" name="DGorderby" data-setting="DGorderby">
59
+ <?php foreach ( DG_Gallery::getOrderbyOptions() as $i ) : ?>
60
+ <option value="<?php echo esc_attr( $i ); ?>" <#
61
+ if ( '<?php echo $i ?>' == documentGalleryDefaults.orderby ) { #>selected="selected"<# }
62
+ #>>
63
+ <?php echo esc_html( $i ); ?>
64
+ </option>
65
+ <?php endforeach; ?>
66
+ </select></td>
67
+ </tr></table>
68
+ </label>
69
+
70
+ <label class="setting">
71
+ <table><tr>
72
+ <td><span><?php _e('Ascending or descending sorting of documents', 'document-gallery'); ?></span></td>
73
+ <td><select class="order" name="order" data-setting="order">
74
+ <?php foreach ( DG_Gallery::getOrderOptions() as $i ) : ?>
75
+ <option value="<?php echo esc_attr( $i ); ?>" <#
76
+ if ( '<?php echo $i ?>' == documentGalleryDefaults.order ) { #>selected="selected"<# }
77
+ #>>
78
+ <?php echo esc_html( $i ); ?>
79
+ </option>
80
+ <?php endforeach; ?>
81
+ </select></td>
82
+ </tr></table>
83
+ </label>
84
+ </script>
assets/css/admin.css CHANGED
@@ -467,4 +467,23 @@ td.column-title input {
467
  height: 5px;
468
  background-color: #9b9b9b;;
469
  -webkit-border-radius: 5px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
470
  }
467
  height: 5px;
468
  background-color: #9b9b9b;;
469
  -webkit-border-radius: 5px;
470
+ }
471
+ .document-gallery-settings label.setting {
472
+ margin: 2px 0;
473
+ }
474
+ .document-gallery-settings label.setting table {
475
+ width: 100%;
476
+ padding-right: 8px;
477
+ }
478
+ .document-gallery-settings label.setting table tr td:last-of-type, .document-gallery-settings label.setting table tr td:last-of-type * {
479
+ text-align: right !important;
480
+ float: none !important;
481
+ margin: auto 0 !important;
482
+ }
483
+ .document-gallery-settings label.setting table tr td:last-of-type select {
484
+ max-width: none !important;
485
+ }
486
+ .document-gallery-settings label.setting table tr td span {
487
+ text-align: left !important;
488
+ float: none !important;
489
  }
assets/js/admin.js CHANGED
@@ -94,6 +94,13 @@ jQuery(document).ready(function(){
94
  }
95
  }
96
  });
 
 
 
 
 
 
 
97
 
98
  function DragDropFilesStop(e) {
99
  e = e || event;
94
  }
95
  }
96
  });
97
+
98
+ jQuery('#LogTable .manage-column.column-date').click(function(){
99
+ jQuery(this).toggleClass('asc desc');
100
+ var table = jQuery('#LogTable > tbody');
101
+ var rows = table.children('tr');
102
+ table.append(rows.get().reverse());
103
+ });
104
 
105
  function DragDropFilesStop(e) {
106
  e = e || event;
assets/js/media_manager.js ADDED
@@ -0,0 +1,385 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ( function( $, _ ) {
2
+ var media = wp.media;
3
+
4
+ // Link any localized strings.
5
+ l10n = media.view.l10n = typeof _wpMediaViewsL10n === 'undefined' ? {} : _wpMediaViewsL10n;
6
+ jQuery.extend(l10n, DGl10n);
7
+
8
+ /**
9
+ * wp.media.controller.DocumentGalleryEdit
10
+ *
11
+ * A state for editing a Document Gallery's images and settings.
12
+ *
13
+ * @class
14
+ * @augments wp.media.controller.Library
15
+ * @augments wp.media.controller.State
16
+ * @augments Backbone.Model
17
+ *
18
+ * @param {object} [attributes] The attributes hash passed to the state.
19
+ * @param {string} [attributes.id=gallery-edit] Unique identifier.
20
+ * @param {string} [attributes.title=Edit Gallery] Title for the state. Displays in the frame's title region.
21
+ * @param {wp.media.model.Attachments} [attributes.library] The collection of attachments in the gallery.
22
+ * If one is not supplied, an empty media.model.Selection collection is created.
23
+ * @param {boolean} [attributes.multiple=false] Whether multi-select is enabled.
24
+ * @param {boolean} [attributes.searchable=false] Whether the library is searchable.
25
+ * @param {boolean} [attributes.sortable=true] Whether the Attachments should be sortable. Depends on the orderby property being set to menuOrder on the attachments collection.
26
+ * @param {string|false} [attributes.content=browse] Initial mode for the content region.
27
+ * @param {string|false} [attributes.toolbar=image-details] Initial mode for the toolbar region.
28
+ * @param {boolean} [attributes.describe=true] Whether to offer UI to describe attachments - e.g. captioning images in a gallery.
29
+ * @param {boolean} [attributes.displaySettings=true] Whether to show the attachment display settings interface.
30
+ * @param {boolean} [attributes.dragInfo=true] Whether to show instructional text about the attachments being sortable.
31
+ * @param {int} [attributes.idealColumnWidth=170] The ideal column width in pixels for attachments.
32
+ * @param {boolean} [attributes.editing=false] Whether the gallery is being created, or editing an existing instance.
33
+ * @param {int} [attributes.priority=60] The priority for the state link in the media menu.
34
+ * @param {boolean} [attributes.syncSelection=false] Whether the Attachments selection should be persisted from the last state.
35
+ * Defaults to false for this state, because the library passed in *is* the selection.
36
+ * @param {view} [attributes.AttachmentView] The single `Attachment` view to be used in the `Attachments`.
37
+ * If none supplied, defaults to wp.media.view.Attachment.EditLibrary.
38
+ */
39
+ media.controller.DocumentGalleryEdit = media.controller.Library.extend({
40
+ defaults: {
41
+ id: 'document-gallery-edit',
42
+ title: l10n.editDocumentGalleryTitle,
43
+ multiple: false,
44
+ searchable: false,
45
+ sortable: true,
46
+ display: false,
47
+ content: 'browse',
48
+ toolbar: 'document-gallery-edit',
49
+ describe: true,
50
+ displaySettings: true,
51
+ dragInfo: true,
52
+ idealColumnWidth: 170,
53
+ editing: false,
54
+ priority: 60,
55
+ syncSelection: false
56
+ },
57
+
58
+ /**
59
+ * @since 3.5.0
60
+ */
61
+ initialize: function() {
62
+ // If we haven't been provided a `library`, create a `Selection`.
63
+ if ( ! this.get('library') )
64
+ this.set( 'library', new media.model.Selection() );
65
+
66
+ // The single `Attachment` view to be used in the `Attachments` view.
67
+ if ( ! this.get('AttachmentView') )
68
+ this.set( 'AttachmentView', media.view.Attachment.EditLibrary );
69
+ media.controller.Library.prototype.initialize.apply( this, arguments );
70
+ },
71
+
72
+ /**
73
+ * @since 3.5.0
74
+ */
75
+ activate: function() {
76
+ var library = this.get('library');
77
+
78
+ // Limit the library to images only.
79
+ //library.props.set( 'type', '' );
80
+
81
+ // Watch for uploaded attachments.
82
+ this.get('library').observe( wp.Uploader.queue );
83
+
84
+ this.frame.on( 'content:render:browse', this.gallerySettings, this );
85
+
86
+ media.controller.Library.prototype.activate.apply( this, arguments );
87
+ },
88
+
89
+ /**
90
+ * @since 3.5.0
91
+ */
92
+ deactivate: function() {
93
+ // Stop watching for uploaded attachments.
94
+ this.get('library').unobserve( wp.Uploader.queue );
95
+
96
+ this.frame.off( 'content:render:browse', this.gallerySettings, this );
97
+
98
+ media.controller.Library.prototype.deactivate.apply( this, arguments );
99
+ },
100
+
101
+ /**
102
+ * @since 3.5.0
103
+ *
104
+ * @param browser
105
+ */
106
+ gallerySettings: function( browser ) {
107
+ if ( ! this.get('displaySettings') ) {
108
+ return;
109
+ }
110
+
111
+ var library = this.get('library');
112
+
113
+ if ( ! library || ! browser ) {
114
+ return;
115
+ }
116
+
117
+ library.gallery = library.gallery || new Backbone.Model();
118
+
119
+ browser.sidebar.set({
120
+ document_gallery: new media.view.Settings.DocumentGallery({
121
+ controller: this,
122
+ model: library.gallery,
123
+ priority: 40
124
+ })
125
+ });
126
+
127
+ browser.toolbar.set( 'reverse', {
128
+ text: l10n.reverseOrder,
129
+ priority: 80,
130
+
131
+ click: function() {
132
+ library.reset( library.toArray().reverse() );
133
+ }
134
+ });
135
+ }
136
+ });
137
+
138
+ /**
139
+ * A state for selecting more images to add to a Document Gallery.
140
+ *
141
+ * @class
142
+ * @augments wp.media.controller.Library
143
+ * @augments wp.media.controller.State
144
+ * @augments Backbone.Model
145
+ *
146
+ * @param {object} [attributes] The attributes hash passed to the state.
147
+ * @param {string} [attributes.id=gallery-library] Unique identifier.
148
+ * @param {string} [attributes.title=Add to Gallery] Title for the state. Displays in the frame's title region.
149
+ * @param {boolean} [attributes.multiple=add] Whether multi-select is enabled. @todo 'add' doesn't seem do anything special, and gets used as a boolean.
150
+ * @param {wp.media.model.Attachments} [attributes.library] The attachments collection to browse.
151
+ * If one is not supplied, a collection of all images will be created.
152
+ * @param {boolean|string} [attributes.filterable=uploaded] Whether the library is filterable, and if so what filters should be shown.
153
+ * Accepts 'all', 'uploaded', or 'unattached'.
154
+ * @param {string} [attributes.menu=gallery] Initial mode for the menu region.
155
+ * @param {string} [attributes.content=upload] Initial mode for the content region.
156
+ * Overridden by persistent user setting if 'contentUserSetting' is true.
157
+ * @param {string} [attributes.router=browse] Initial mode for the router region.
158
+ * @param {string} [attributes.toolbar=gallery-add] Initial mode for the toolbar region.
159
+ * @param {boolean} [attributes.searchable=true] Whether the library is searchable.
160
+ * @param {boolean} [attributes.sortable=true] Whether the Attachments should be sortable. Depends on the orderby property being set to menuOrder on the attachments collection.
161
+ * @param {boolean} [attributes.autoSelect=true] Whether an uploaded attachment should be automatically added to the selection.
162
+ * @param {boolean} [attributes.contentUserSetting=true] Whether the content region's mode should be set and persisted per user.
163
+ * @param {int} [attributes.priority=100] The priority for the state link in the media menu.
164
+ * @param {boolean} [attributes.syncSelection=false] Whether the Attachments selection should be persisted from the last state.
165
+ * Defaults to false because for this state, because the library of the Edit Gallery state is the selection.
166
+ */
167
+ media.controller.DocumentGalleryAdd = media.controller.Library.extend({
168
+ defaults: _.defaults({
169
+ id: 'document-gallery-library',
170
+ title: l10n.addToDocumentGalleryTitle,
171
+ multiple: 'add',
172
+ filterable: 'uploaded',
173
+ menu: 'document-gallery',
174
+ toolbar: 'document-gallery-add',
175
+ priority: 100,
176
+ syncSelection: false
177
+ }, media.controller.Library.prototype.defaults ),
178
+
179
+ /**
180
+ * @since 3.5.0
181
+ */
182
+ initialize: function() {
183
+ // If a library wasn't supplied, create a library of images.
184
+ if ( ! this.get('library') )
185
+ this.set( 'library', media.query() );
186
+
187
+ media.controller.Library.prototype.initialize.apply( this, arguments );
188
+ },
189
+
190
+ /**
191
+ * @since 3.5.0
192
+ */
193
+ activate: function() {
194
+ var library = this.get('library'),
195
+ edit = this.frame.state('document-gallery-edit').get('library');
196
+
197
+ if ( this.editLibrary && this.editLibrary !== edit )
198
+ library.unobserve( this.editLibrary );
199
+
200
+ // Accepts attachments that exist in the original library and
201
+ // that do not exist in gallery's library.
202
+ library.validator = function( attachment ) {
203
+ return !! this.mirroring.get( attachment.cid ) && ! edit.get( attachment.cid ) && media.model.Selection.prototype.validator.apply( this, arguments );
204
+ };
205
+
206
+ // Reset the library to ensure that all attachments are re-added
207
+ // to the collection. Do so silently, as calling `observe` will
208
+ // trigger the `reset` event.
209
+ library.reset( library.mirroring.models, { silent: true });
210
+ library.observe( edit );
211
+ this.editLibrary = edit;
212
+
213
+ media.controller.Library.prototype.activate.apply( this, arguments );
214
+ }
215
+ });
216
+
217
+ /**
218
+ * wp.media.view.Settings.DocumentGallery
219
+ *
220
+ * @class
221
+ * @augments wp.media.view.Settings
222
+ * @augments wp.media.View
223
+ * @augments wp.Backbone.View
224
+ * @augments Backbone.View
225
+ */
226
+ media.view.Settings.DocumentGallery = media.view.Settings.extend({
227
+ className: 'collection-settings gallery-settings document-gallery-settings',
228
+ template: media.template('document-gallery-settings')
229
+ });
230
+
231
+ // supersede the default MediaFrame.Post view
232
+ var wpMediaFramePost = wp.media.view.MediaFrame.Post;
233
+ wp.media.view.MediaFrame.Post = wpMediaFramePost.extend(
234
+ {
235
+ initialize: function() {
236
+ wpMediaFramePost.prototype.initialize.apply( this, arguments );
237
+ this.states.add([
238
+ new media.controller.Library({
239
+ id: 'document-gallery',
240
+ title: l10n.documentGalleryMenuTitle,
241
+ priority: 50,
242
+ toolbar: 'main-document-gallery',
243
+ filterable: 'all',
244
+ multiple: 'add',
245
+ editable: false,
246
+
247
+ library: media.query( this.options.library )
248
+ }),
249
+
250
+ // Document Gallery states.
251
+ new media.controller.DocumentGalleryEdit({
252
+ library: this.options.selection,
253
+ editing: this.options.editing,
254
+ menu: 'document-gallery'
255
+ }),
256
+
257
+ new media.controller.DocumentGalleryAdd()
258
+ ]);
259
+
260
+ this.on( 'menu:create:document-gallery', this.createMenu, this );
261
+ this.on( 'toolbar:create:main-document-gallery', this.createToolbar, this );
262
+
263
+ this.on( 'menu:render:document-gallery', this.documentGalleryMenu, this );
264
+ this.on( 'toolbar:render:main-document-gallery', this.mainDocumentGalleryToolbar, this );
265
+ this.on( 'toolbar:render:document-gallery-edit', this.documentGalleryEditToolbar, this );
266
+ this.on( 'toolbar:render:document-gallery-add', this.documentGalleryAddToolbar, this );
267
+ },
268
+
269
+ documentGalleryMenu: function( view ) {
270
+ var lastState = this.lastState(),
271
+ previous = lastState && lastState.id,
272
+ frame = this;
273
+
274
+ view.set({
275
+ cancel: {
276
+ text: l10n.cancelDocumentGalleryTitle,
277
+ priority: 20,
278
+ click: function() {
279
+ if ( previous ) {
280
+ frame.setState( previous );
281
+ } else {
282
+ frame.close();
283
+ }
284
+
285
+ // Keep focus inside media modal
286
+ // after canceling a gallery
287
+ this.controller.modal.focusManager.focus();
288
+ }
289
+ },
290
+ separateCancel: new media.View({
291
+ className: 'separator',
292
+ priority: 40
293
+ })
294
+ });
295
+ },
296
+
297
+ /**
298
+ * @param {wp.Backbone.View} view
299
+ */
300
+ mainDocumentGalleryToolbar: function( view ) {
301
+ var controller = this;
302
+
303
+ this.selectionStatusToolbar( view );
304
+
305
+ view.set( 'document-gallery', {
306
+ style: 'primary',
307
+ text: l10n.documentGalleryButton,
308
+ priority: 60,
309
+ requires: { selection: true },
310
+
311
+ click: function() {
312
+ var selection = controller.state().get('selection'),
313
+ edit = controller.state('document-gallery-edit'),
314
+ models = selection.models;
315
+
316
+ edit.set( 'library', selection );
317
+
318
+ this.controller.setState('document-gallery-edit');
319
+
320
+ // Keep focus inside media modal
321
+ // after jumping to gallery view
322
+ this.controller.modal.focusManager.focus();
323
+ }
324
+ });
325
+ },
326
+
327
+ documentGalleryEditToolbar: function() {
328
+ var editing = this.state().get('editing');
329
+ this.toolbar.set( new media.view.Toolbar({
330
+ controller: this,
331
+ items: {
332
+ insert: {
333
+ style: 'primary',
334
+ text: editing ? l10n.updateDocumentGallery : l10n.insertDocumentGallery,
335
+ priority: 80,
336
+ requires: { library: true },
337
+
338
+ /**
339
+ * @fires wp.media.controller.State#update
340
+ */
341
+ click: function() {
342
+ var controller = this.controller,
343
+ state = controller.state();
344
+
345
+ controller.close();
346
+ //state.trigger( 'update', state.get('library') );
347
+ wp.media.editor.insert( wp.media.gallery.shortcode( state.get('library') ).string().replace(/^\[gallery/ig, '[dg').replace(/DGorderby/ig, 'orderby') );
348
+
349
+ // Restore and reset the default state.
350
+ controller.setState( controller.options.state );
351
+ controller.reset();
352
+ }
353
+ }
354
+ }
355
+ }) );
356
+ },
357
+
358
+ documentGalleryAddToolbar: function() {
359
+ this.toolbar.set( new media.view.Toolbar({
360
+ controller: this,
361
+ items: {
362
+ insert: {
363
+ style: 'primary',
364
+ text: l10n.addToDocumentGallery,
365
+ priority: 80,
366
+ requires: { selection: true },
367
+
368
+ /**
369
+ * @fires wp.media.controller.State#reset
370
+ */
371
+ click: function() {
372
+ var controller = this.controller,
373
+ state = controller.state(),
374
+ edit = controller.state('document-gallery-edit');
375
+
376
+ edit.get('library').add( state.get('selection').models );
377
+ state.trigger('reset');
378
+ controller.setState('document-gallery-edit');
379
+ }
380
+ }
381
+ }
382
+ }) );
383
+ }
384
+ });
385
+ }(jQuery, _));
document-gallery.php CHANGED
@@ -5,14 +5,14 @@ defined('WPINC') OR exit;
5
  Plugin Name: Document Gallery
6
  Plugin URI: http://wordpress.org/extend/plugins/document-gallery/
7
  Description: Display non-images (and images) in gallery format on a page or post with the [dg] shortcode.
8
- Version: 3.0.2
9
  Author: Dan Rossiter
10
  Author URI: http://danrossiter.org/
11
  License: GPLv2
12
  Text Domain: document-gallery
13
  */
14
 
15
- define('DG_VERSION', '3.0.2');
16
 
17
  // define helper paths & URLs
18
  define('DG_BASENAME', plugin_basename(__FILE__));
@@ -26,11 +26,15 @@ global $dg_options;
26
  define('DG_OPTION_NAME', 'document_gallery');
27
  $dg_options = get_option(DG_OPTION_NAME, null);
28
 
 
 
 
29
  // DG general utility functions
30
  include_once DG_PATH . 'inc/class-util.php';
31
 
32
  // logging functionality
33
  include_once DG_PATH . 'inc/class-logger.php';
 
34
 
35
  // handle activation, updates, and uninstallation
36
  include_once DG_PATH . 'inc/class-setup.php';
@@ -65,6 +69,9 @@ if (is_admin()) {
65
  // add meta box for managing thumbnail generation to attachment Edit Media page
66
  add_action('add_meta_boxes', array('DG_Admin', 'addMetaBox'));
67
  add_action('wp_ajax_dg_upload_thumb', array('DG_Admin', 'saveMetaBox'));
 
 
 
68
 
69
  if (DG_Admin::doRegisterSettings()) {
70
  add_action('admin_init', array('DG_Admin', 'registerSettings'));
@@ -80,252 +87,5 @@ if (is_admin()) {
80
  // adds 'dg' shortcode
81
  add_shortcode('dg', array('DocumentGallery', 'doShortcode'));
82
 
83
- /**
84
- * DocumentGallery wraps basic functionality to setup the plugin.
85
- *
86
- * @author drossiter
87
- */
88
- class DocumentGallery {
89
-
90
- /*==========================================================================
91
- * THE SHORTCODE
92
- *=========================================================================*/
93
-
94
- /**
95
- * Takes values passed from attributes and returns sutable HTML to represent
96
- * all valid attachments requested.
97
- *
98
- * @param multitype:string $atts Arguments from the user.
99
- * @return string HTML for the Document Gallery.
100
- */
101
- public static function doShortcode($atts) {
102
- include_once 'inc/class-gallery.php';
103
-
104
- $start = microtime(true);
105
- $gallery = (string)new DG_Gallery($atts);
106
- DG_Logger::writeLog(DG_LogLevel::Detail, 'Generation Time: ' . sprintf('%.2f', (microtime(true) - $start)) . ' s');
107
-
108
- return $gallery;
109
- }
110
-
111
- /**
112
- * Enqueue standard DG CSS.
113
- */
114
- public static function enqueueGalleryStyle() {
115
- wp_enqueue_style('document-gallery', DG_URL . 'assets/css/style.css', null, DG_VERSION);
116
- }
117
-
118
- /**
119
- * Prints user's custom CSS.
120
- */
121
- public static function printCustomStyle() {
122
- global $dg_options;
123
-
124
- if (!empty($dg_options['css']['minified'])) {
125
- echo "<style type='text/css'>{$dg_options['css']['minified']}</style>" . PHP_EOL;
126
- }
127
- }
128
-
129
- /*==========================================================================
130
- * I18n
131
- *=========================================================================*/
132
-
133
- /**
134
- * Loads language files into WP core.
135
- */
136
- public static function loadTextDomain() {
137
- load_plugin_textdomain('document-gallery', false, dirname(DG_BASENAME) . '/languages/');
138
- }
139
-
140
- /*==========================================================================
141
- * HELPER FUNCTIONS
142
- *=========================================================================*/
143
-
144
- /**
145
- * @param int $blog ID of the blog to be retrieved in multisite env.
146
- * @return multitype:unknown Options for the blog.
147
- */
148
- public static function getOptions($blog = null) {
149
- global $dg_options;
150
- return is_null($blog)
151
- ? $dg_options
152
- : get_blog_option($blog, DG_OPTION_NAME, null);
153
- }
154
-
155
- /**
156
- * @param multitype:unknown $options
157
- * @param int $blog ID of the blog to be set in multisite env.
158
- */
159
- public static function setOptions($options, $blog = null) {
160
- if (is_null($blog)) {
161
- global $dg_options;
162
- update_option(DG_OPTION_NAME, $options);
163
- $dg_options = $options;
164
- } else {
165
- update_blog_option($blog, DG_OPTION_NAME, $options);
166
- }
167
- }
168
-
169
- /**
170
- * @param int $blog ID of the blog to be deleted in multisite env.
171
- */
172
- public static function deleteOptions($blog = null) {
173
- if (is_null($blog)) {
174
- delete_option(DG_OPTION_NAME);
175
- } else {
176
- delete_blog_option($blog, DG_OPTION_NAME);
177
- }
178
- }
179
-
180
- /**
181
- * Adds hook to validate DG options every time save is attempted.
182
- */
183
- public static function addValidation() {
184
- add_filter('pre_update_option_' . DG_OPTION_NAME, array('DocumentGallery', 'validateOptionsStructure'), 10, 2);
185
- }
186
-
187
- /**
188
- * Checks whether the given options match the option schema.
189
- * @param multivar $new The new options to be validated.
190
- * @param multivar $old The old options.
191
- * @return array The options to be saved.
192
- */
193
- public static function validateOptionsStructure($new, $old) {
194
- if (self::isValidOptionsStructure($new)) {
195
- $ret = $new;
196
- } else {
197
- $ret = $old;
198
- DG_Logger::writeLog(DG_LogLevel::Error, 'Attempted to save invalid options.' . PHP_EOL . print_r($new, true), true, true);
199
- }
200
-
201
- return $ret;
202
- }
203
-
204
- /**
205
- * @param multivar|unknown $o The options structure to validate.
206
- * @param multivar $schema The schema to validate against (note that only keys matter -- non-array values are ignored).
207
- * @return bool Whether the given options structure matches the schema.
208
- */
209
- private static function isValidOptionsStructure($o, $schema = null) {
210
- if (is_null($schema)) {
211
- $schema = DG_Setup::getDefaultOptions(true);
212
- }
213
-
214
- // simple checks first
215
- $valid = is_array($o) && (count($schema) === count($o));
216
-
217
- if ($valid) {
218
- foreach ($schema as $sk => $sv) {
219
- $valid = array_key_exists($sk, $o);
220
- if (is_array($sv) && !empty($sv)) {
221
- $valid = $valid && self::isValidOptionsStructure($o[$sk], $sv);
222
- }
223
-
224
- if (!$valid) {
225
- break;
226
- }
227
- }
228
- }
229
-
230
- return $valid;
231
- }
232
-
233
- /**
234
- * Function takes a GMT timestamp and returns a date/time string in the
235
- * current timezone and WP format.
236
- * @param int $timestamp The GMT timestamp to translate.
237
- * @return string The local time in the WP date/time format.
238
- */
239
- public static function localDateTimeFromTimestamp($timestamp) {
240
- static $gmt_offet = null;
241
- static $wp_date_format = null;
242
- static $wp_time_format = null;
243
- if (is_null($gmt_offet)) {
244
- $gmt_offet = get_option('gmt_offset');
245
- $wp_date_format = get_option('date_format');
246
- $wp_time_format = get_option('time_format');
247
- }
248
-
249
- return '<span class="nowrap">'.date_i18n($wp_date_format, $timestamp + $gmt_offet * 3600).'</span> <span class="nowrap">'.date_i18n($wp_time_format, $timestamp + $gmt_offet * 3600).'</span>';
250
- }
251
-
252
- /**
253
- * Compiles any custom CSS, including minification and escaping HTML.
254
- * @param string $custom The custom CSS to compile.
255
- * @return string Compiled CSS.
256
- */
257
- public static function compileCustomCss($custom) {
258
- $css = str_replace('&gt;', '>', esc_html($custom));
259
- return self::minifyCss($css);
260
- }
261
-
262
- /**
263
- * Minifies CSS string.
264
- * Source: http://stackoverflow.com/a/15195752/866618
265
- */
266
- private static function minifyCss($css) {
267
- # remove comments first (simplifies the other regex)
268
- $re1 = <<<EOS
269
- (?sx)
270
- # quotes
271
- (
272
- "(?:[^"\\\\]++|\\.)*+"
273
- | '(?:[^'\\\\]++|\\.)*+'
274
- )
275
- |
276
- # comments
277
- /\* (?> .*? \*/ )
278
- EOS;
279
-
280
- $re2 = <<<EOS
281
- (?six)
282
- # quotes
283
- (
284
- "(?:[^"\\\\]++|\\.)*+"
285
- | '(?:[^'\\\\]++|\\.)*+'
286
- )
287
- |
288
- # ; before } (and the spaces after it while we're here)
289
- \s*+ ; \s*+ ( } ) \s*+
290
- |
291
- # all spaces around meta chars/operators
292
- \s*+ ( [*$~^|]?+= | [{};,>~+-] | !important\b ) \s*+
293
- |
294
- # spaces right of ( [ :
295
- ( [[(:] ) \s++
296
- |
297
- # spaces left of ) ]
298
- \s++ ( [])] )
299
- |
300
- # spaces left (and right) of :
301
- \s++ ( : ) \s*+
302
- # but not in selectors: not followed by a {
303
- (?!
304
- (?>
305
- [^{}"']++
306
- | "(?:[^"\\\\]++|\\.)*+"
307
- | '(?:[^'\\\\]++|\\.)*+'
308
- )*+
309
- {
310
- )
311
- |
312
- # spaces at beginning/end of string
313
- ^ \s++ | \s++ \z
314
- |
315
- # double spaces to single
316
- (\s)\s+
317
- EOS;
318
-
319
- $css = preg_replace("%$re1%", '$1', $css);
320
- return preg_replace("%$re2%", '$1$2$3$4$5$6$7', $css);
321
- }
322
-
323
- /**
324
- * Blocks instantiation. All functions are static.
325
- */
326
- private function __construct() {
327
-
328
- }
329
- }
330
-
331
- ?>
5
  Plugin Name: Document Gallery
6
  Plugin URI: http://wordpress.org/extend/plugins/document-gallery/
7
  Description: Display non-images (and images) in gallery format on a page or post with the [dg] shortcode.
8
+ Version: 3.1
9
  Author: Dan Rossiter
10
  Author URI: http://danrossiter.org/
11
  License: GPLv2
12
  Text Domain: document-gallery
13
  */
14
 
15
+ define('DG_VERSION', '3.1');
16
 
17
  // define helper paths & URLs
18
  define('DG_BASENAME', plugin_basename(__FILE__));
26
  define('DG_OPTION_NAME', 'document_gallery');
27
  $dg_options = get_option(DG_OPTION_NAME, null);
28
 
29
+ // core functionality
30
+ include_once DG_PATH . 'inc/class-document-gallery.php';
31
+
32
  // DG general utility functions
33
  include_once DG_PATH . 'inc/class-util.php';
34
 
35
  // logging functionality
36
  include_once DG_PATH . 'inc/class-logger.php';
37
+ add_action(DG_Logger::PurgeLogsAction, array('DG_Logger', 'purgeExpiredEntries'));
38
 
39
  // handle activation, updates, and uninstallation
40
  include_once DG_PATH . 'inc/class-setup.php';
69
  // add meta box for managing thumbnail generation to attachment Edit Media page
70
  add_action('add_meta_boxes', array('DG_Admin', 'addMetaBox'));
71
  add_action('wp_ajax_dg_upload_thumb', array('DG_Admin', 'saveMetaBox'));
72
+
73
+ // Media Manager integration
74
+ add_action('admin_print_footer_scripts', array('DG_Admin', 'loadCustomTemplates')); //wp_print_scripts || wp_footer
75
 
76
  if (DG_Admin::doRegisterSettings()) {
77
  add_action('admin_init', array('DG_Admin', 'registerSettings'));
87
  // adds 'dg' shortcode
88
  add_shortcode('dg', array('DocumentGallery', 'doShortcode'));
89
 
90
+ // public API for developers
91
+ include_once DG_PATH . 'inc/class-api.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/class-api.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ defined('WPINC') OR exit;
3
+
4
+ /**
5
+ * All methods within this class may be considered "documented" and
6
+ * developers may rely on their existence moving forward. If there is
7
+ * a need to remove a method in this class, it will go through a
8
+ * deprecation period before being removed.
9
+ *
10
+ * This guarantee is only provided for this file and class-logger. All
11
+ * other methods throughout Document Gallery may be removed or
12
+ * significantly changed from version-to-version and should not be relied
13
+ * on in any way for external development.
14
+ *
15
+ * NOTE: If you are performing actions related to Document Gallery, you
16
+ * you are encouraged to log important events through the Document Gallery
17
+ * logging interface. This interface is available under the DG_Logger class.
18
+ *
19
+ * @author drossiter
20
+ */
21
+ class DG_API {
22
+ /**
23
+ * Sets the thumbnail for the given attachment ID.
24
+ *
25
+ * @param int $ID Document ID.
26
+ * @param string $path System path to thumbnail.
27
+ * @param unknown $generator Descriptor for generation method -- usually method name.
28
+ * @return bool Whether set was successful.
29
+ */
30
+ public static function setThumbnail($ID, $path, $generator = 'unknown') {
31
+ include_once DG_PATH . 'inc/class-thumber.php';
32
+ return DG_Thumber::setThumbnail($ID, $path, $generator);
33
+ }
34
+
35
+ /**
36
+ * Sets the thumbnail for the given attachment ID to a failed state.
37
+ * This prevents the plugin attempting to generate a thumbnail for this
38
+ * plugin in the future.
39
+ *
40
+ * @param int $ID The attachment ID.
41
+ */
42
+ public static function setThumbnailFailed($ID) {
43
+ include_once DG_PATH . 'inc/class-thumber.php';
44
+ return DG_Thumber::setThumbnailFailed($ID);
45
+ }
46
+
47
+ /**
48
+ *
49
+ * @param int $ID The attachment ID.
50
+ * @param number $pg The page number to use (1-based numbering).
51
+ * @param string $generate_if_missing Whether to generate the thumbnail if it has not
52
+ * yet been generated.
53
+ * @return string The URL for the thumbnail NULL. Note that if generate_if_missing
54
+ * is true then you will never get NULL -- you will get a default icon if generation fails.
55
+ */
56
+ public static function getThumbnail($ID, $pg = 1, $generate_if_missing = false) {
57
+ include_once DG_PATH . 'inc/class-thumber.php';
58
+ return DG_Thumber::getThumbnail($ID, $pg, $generate_if_missing);
59
+ }
60
+
61
+ /**
62
+ * Removes all metadata related to a thumbnail for the given attachment ID(s). This allows
63
+ * the plugin to attempt to re-generate the thumbnail for this attachment next time it
64
+ * is requested in a gallery or through some other means.
65
+ *
66
+ * @param int|array $ids Which thumbnails to delete.
67
+ * @return array All IDs that were deleted -- some subset of IDs requested to be deleted.
68
+ */
69
+ public static function deleteThumbnails($ids) {
70
+ include_once DG_PATH . 'inc/class-thumber.php';
71
+ return DG_Thumber::deleteThumbMeta($ids);
72
+ }
73
+ }
inc/class-document-gallery.php ADDED
@@ -0,0 +1,251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * DocumentGallery wraps core functionality involved in plugin setup.
5
+ *
6
+ * @author drossiter
7
+ */
8
+ class DocumentGallery {
9
+
10
+ /*==========================================================================
11
+ * THE SHORTCODE
12
+ *=========================================================================*/
13
+
14
+ /**
15
+ * Takes values passed from attributes and returns sutable HTML to represent
16
+ * all valid attachments requested.
17
+ *
18
+ * @param multitype:string $atts Arguments from the user.
19
+ * @return string HTML for the Document Gallery.
20
+ */
21
+ public static function doShortcode($atts) {
22
+ include_once DG_PATH . 'inc/class-gallery.php';
23
+
24
+ $start = microtime(true);
25
+ $gallery = (string)new DG_Gallery($atts);
26
+ DG_Logger::writeLog(DG_LogLevel::Detail, 'Generation Time: ' . sprintf('%.2f', (microtime(true) - $start)) . ' s');
27
+
28
+ return $gallery;
29
+ }
30
+
31
+ /**
32
+ * Enqueue standard DG CSS.
33
+ */
34
+ public static function enqueueGalleryStyle() {
35
+ wp_enqueue_style('document-gallery', DG_URL . 'assets/css/style.css', null, DG_VERSION);
36
+ }
37
+
38
+ /**
39
+ * Prints user's custom CSS.
40
+ */
41
+ public static function printCustomStyle() {
42
+ global $dg_options;
43
+
44
+ if (!empty($dg_options['css']['minified'])) {
45
+ echo "<style type='text/css'>{$dg_options['css']['minified']}</style>" . PHP_EOL;
46
+ }
47
+ }
48
+
49
+ /*==========================================================================
50
+ * I18n
51
+ *=========================================================================*/
52
+
53
+ /**
54
+ * Loads language files into WP core.
55
+ */
56
+ public static function loadTextDomain() {
57
+ load_plugin_textdomain('document-gallery', false, dirname(DG_BASENAME) . '/languages/');
58
+ }
59
+
60
+ /*==========================================================================
61
+ * HELPER FUNCTIONS
62
+ *=========================================================================*/
63
+
64
+ /**
65
+ * @param int $blog ID of the blog to be retrieved in multisite env.
66
+ * @return multitype:unknown Options for the blog.
67
+ */
68
+ public static function getOptions($blog = null) {
69
+ global $dg_options;
70
+ return is_null($blog)
71
+ ? $dg_options
72
+ : get_blog_option($blog, DG_OPTION_NAME, null);
73
+ }
74
+
75
+ /**
76
+ * @param multitype:unknown $options
77
+ * @param int $blog ID of the blog to be set in multisite env.
78
+ */
79
+ public static function setOptions($options, $blog = null) {
80
+ if (is_null($blog)) {
81
+ global $dg_options;
82
+ update_option(DG_OPTION_NAME, $options);
83
+ $dg_options = $options;
84
+ } else {
85
+ update_blog_option($blog, DG_OPTION_NAME, $options);
86
+ }
87
+ }
88
+
89
+ /**
90
+ * @param int $blog ID of the blog to be deleted in multisite env.
91
+ */
92
+ public static function deleteOptions($blog = null) {
93
+ if (is_null($blog)) {
94
+ delete_option(DG_OPTION_NAME);
95
+ } else {
96
+ delete_blog_option($blog, DG_OPTION_NAME);
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Adds hook to validate DG options every time save is attempted.
102
+ */
103
+ public static function addValidation() {
104
+ add_filter('pre_update_option_' . DG_OPTION_NAME, array('DocumentGallery', 'validateOptionsStructure'), 10, 2);
105
+ }
106
+
107
+ /**
108
+ * Checks whether the given options match the option schema.
109
+ * @param multivar $new The new options to be validated.
110
+ * @param multivar $old The old options.
111
+ * @return array The options to be saved.
112
+ */
113
+ public static function validateOptionsStructure($new, $old) {
114
+ if (self::isValidOptionsStructure($new)) {
115
+ $ret = $new;
116
+ } else {
117
+ $ret = $old;
118
+ DG_Logger::writeLog(DG_LogLevel::Error, 'Attempted to save invalid options.' . PHP_EOL . print_r($new, true), true, true);
119
+ }
120
+
121
+ return $ret;
122
+ }
123
+
124
+ /**
125
+ * @param multivar|unknown $o The options structure to validate.
126
+ * @param multivar $schema The schema to validate against (note that only keys matter -- non-array values are ignored).
127
+ * @return bool Whether the given options structure matches the schema.
128
+ */
129
+ private static function isValidOptionsStructure($o, $schema = null) {
130
+ if (is_null($schema)) {
131
+ $schema = DG_Setup::getDefaultOptions(true);
132
+ }
133
+
134
+ // simple checks first
135
+ $valid = is_array($o) && (count($schema) === count($o));
136
+
137
+ if ($valid) {
138
+ foreach ($schema as $sk => $sv) {
139
+ $valid = array_key_exists($sk, $o);
140
+ if (is_array($sv) && !empty($sv)) {
141
+ $valid = $valid && self::isValidOptionsStructure($o[$sk], $sv);
142
+ }
143
+
144
+ if (!$valid) {
145
+ break;
146
+ }
147
+ }
148
+ }
149
+
150
+ return $valid;
151
+ }
152
+
153
+ /**
154
+ * Function takes a GMT timestamp and returns a date/time string in the
155
+ * current timezone and WP format.
156
+ * @param int $timestamp The GMT timestamp to translate.
157
+ * @return string The local time in the WP date/time format.
158
+ */
159
+ public static function localDateTimeFromTimestamp($timestamp) {
160
+ static $gmt_offet = null;
161
+ static $wp_date_format = null;
162
+ static $wp_time_format = null;
163
+ if (is_null($gmt_offet)) {
164
+ $gmt_offet = get_option('gmt_offset');
165
+ $wp_date_format = get_option('date_format');
166
+ $wp_time_format = get_option('time_format');
167
+ }
168
+
169
+ return '<span class="nowrap">'.date_i18n($wp_date_format, $timestamp + $gmt_offet * 3600).'</span> <span class="nowrap">'.date_i18n($wp_time_format, $timestamp + $gmt_offet * 3600).'</span>';
170
+ }
171
+
172
+ /**
173
+ * Compiles any custom CSS, including minification and escaping HTML.
174
+ * @param string $custom The custom CSS to compile.
175
+ * @return string Compiled CSS.
176
+ */
177
+ public static function compileCustomCss($custom) {
178
+ $css = str_replace('&gt;', '>', esc_html($custom));
179
+ return self::minifyCss($css);
180
+ }
181
+
182
+ /**
183
+ * Minifies CSS string.
184
+ * Source: http://stackoverflow.com/a/15195752/866618
185
+ */
186
+ private static function minifyCss($css) {
187
+ # remove comments first (simplifies the other regex)
188
+ $re1 = <<<EOS
189
+ (?sx)
190
+ # quotes
191
+ (
192
+ "(?:[^"\\\\]++|\\.)*+"
193
+ | '(?:[^'\\\\]++|\\.)*+'
194
+ )
195
+ |
196
+ # comments
197
+ /\* (?> .*? \*/ )
198
+ EOS;
199
+
200
+ $re2 = <<<EOS
201
+ (?six)
202
+ # quotes
203
+ (
204
+ "(?:[^"\\\\]++|\\.)*+"
205
+ | '(?:[^'\\\\]++|\\.)*+'
206
+ )
207
+ |
208
+ # ; before } (and the spaces after it while we're here)
209
+ \s*+ ; \s*+ ( } ) \s*+
210
+ |
211
+ # all spaces around meta chars/operators
212
+ \s*+ ( [*$~^|]?+= | [{};,>~+-] | !important\b ) \s*+
213
+ |
214
+ # spaces right of ( [ :
215
+ ( [[(:] ) \s++
216
+ |
217
+ # spaces left of ) ]
218
+ \s++ ( [])] )
219
+ |
220
+ # spaces left (and right) of :
221
+ \s++ ( : ) \s*+
222
+ # but not in selectors: not followed by a {
223
+ (?!
224
+ (?>
225
+ [^{}"']++
226
+ | "(?:[^"\\\\]++|\\.)*+"
227
+ | '(?:[^'\\\\]++|\\.)*+'
228
+ )*+
229
+ {
230
+ )
231
+ |
232
+ # spaces at beginning/end of string
233
+ ^ \s++ | \s++ \z
234
+ |
235
+ # double spaces to single
236
+ (\s)\s+
237
+ EOS;
238
+
239
+ $css = preg_replace("%$re1%", '$1', $css);
240
+ return preg_replace("%$re2%", '$1$2$3$4$5$6$7', $css);
241
+ }
242
+
243
+ /**
244
+ * Blocks instantiation. All functions are static.
245
+ */
246
+ private function __construct() {
247
+
248
+ }
249
+ }
250
+
251
+ ?>
inc/class-logger.php CHANGED
@@ -5,14 +5,20 @@ defined('WPINC') OR exit;
5
  * Encapsulates the logic required to maintain and read log files.
6
  */
7
  class DG_Logger {
 
8
  /**
9
- * Appends DG log file if logging is enabled. The following format is used for each line:
10
- * datetime | level | entry | stacktrace (optional)
 
 
 
 
11
  *
12
- * @param int The level of serverity (should be passed using DG_LogLevel consts).
13
- * @param string $entry Value to be logged.
14
  * @param bool $stacktrace Whether to include full stack trace.
15
- * @param bool $force Whether to ignore logging flag and log no matter what.
 
16
  */
17
  public static function writeLog($level, $entry, $stacktrace = false, $force = false) {
18
  if ($force || self::logEnabled()) {
@@ -23,43 +29,7 @@ class DG_Logger {
23
  $trace = debug_backtrace(false);
24
  if ($stacktrace) {
25
  unset($trace[0]);
26
-
27
- $trace_str = '';
28
- $i = 1;
29
-
30
- foreach($trace as $node) {
31
- $trace_str .= "#$i ";
32
-
33
- $file = '';
34
- if (isset($node['file'])) {
35
- // convert to relative path from WP root
36
- $file = str_replace(ABSPATH, '', $node['file']);
37
- }
38
-
39
- if (isset($node['line'])) {
40
- $file .= "({$node['line']})";
41
- }
42
-
43
- if ($file) {
44
- $trace_str .= "$file: ";
45
- }
46
-
47
- if(isset($node['class'])) {
48
- $trace_str .= "{$node['class']}{$node['type']}";
49
- }
50
-
51
- if (isset($node['function'])) {
52
- $args = '';
53
- if (isset($node['args'])) {
54
- $args = implode(', ', array_map(array(__CLASS__, 'print_r'), $node['args']));
55
- }
56
-
57
- $trace_str .= "{$node['function']}($args)" . PHP_EOL;
58
- }
59
- $i++;
60
- }
61
-
62
- $fields[] = $trace_str;
63
  } else {
64
  // Remove first item from backtrace as it's this function which is redundant.
65
  $caller = $trace[1];
@@ -85,7 +55,7 @@ class DG_Logger {
85
 
86
  if ($fp !== false) {
87
  $ret = array();
88
- while (count($ret) < $limit && ($fields = fgetcsv($fp)) !== false) {
89
  if ($skip > 0) {
90
  $skip--;
91
  continue;
@@ -95,6 +65,8 @@ class DG_Logger {
95
  $ret[] = $fields;
96
  }
97
  }
 
 
98
  }
99
 
100
  return $ret;
@@ -109,18 +81,148 @@ class DG_Logger {
109
  }
110
 
111
  /**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  * @return bool Whether debug logging is currently enabled.
113
  */
114
  public static function logEnabled() {
115
- global $dg_options;
116
- return $dg_options['logging'];
 
 
 
 
 
 
 
 
 
 
 
117
  }
118
 
119
  /**
 
120
  * @return string Full path to log file for current blog.
121
  */
122
- private static function getLogFileName() {
123
- return DG_PATH . 'log/' . get_current_blog_id() . '.log';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  }
125
 
126
  /**
@@ -131,6 +233,13 @@ class DG_Logger {
131
  private static function print_r($v) {
132
  return print_r($v, true);
133
  }
 
 
 
 
 
 
 
134
  }
135
 
136
  /**
5
  * Encapsulates the logic required to maintain and read log files.
6
  */
7
  class DG_Logger {
8
+
9
  /**
10
+ * @var string Name of the log purge action.
11
+ */
12
+ const PurgeLogsAction = 'document-gallery_purge-logs';
13
+
14
+ /**
15
+ * Appends DG log file if logging is enabled.
16
  *
17
+ * @param int The level of serverity (should be passed using DG_LogLevel consts).
18
+ * @param string $entry Value to be logged.
19
  * @param bool $stacktrace Whether to include full stack trace.
20
+ * @param bool $force Whether to ignore logging flag and log no matter what.
21
+ * Only should be used when the user *must* know about something.
22
  */
23
  public static function writeLog($level, $entry, $stacktrace = false, $force = false) {
24
  if ($force || self::logEnabled()) {
29
  $trace = debug_backtrace(false);
30
  if ($stacktrace) {
31
  unset($trace[0]);
32
+ $fields[] = self::getStackTraceString($trace);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  } else {
34
  // Remove first item from backtrace as it's this function which is redundant.
35
  $caller = $trace[1];
55
 
56
  if ($fp !== false) {
57
  $ret = array();
58
+ while (count($ret) < $limit && false !== ($fields = fgetcsv($fp))) {
59
  if ($skip > 0) {
60
  $skip--;
61
  continue;
65
  $ret[] = $fields;
66
  }
67
  }
68
+
69
+ @fclose($fp);
70
  }
71
 
72
  return $ret;
81
  }
82
 
83
  /**
84
+ * Clears the log file for all blogs.
85
+ */
86
+ public static function clearLogs() {
87
+ // we don't care if the files actually exist -- they won't when we're done
88
+ foreach (self::getLogFileNames() as $file) {
89
+ @unlink($file);
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Truncates all blog logs to the current purge interval.
95
+ *
96
+ * TODO: This is a memory hog. Consider switching to stream filter.
97
+ */
98
+ public static function purgeExpiredEntries() {
99
+ self::writeLog(DG_LogLevel::Detail, 'Beginning scheduled log file purge.');
100
+
101
+ $blogs = array(null);
102
+ if (is_multisite()) {
103
+ global $wpdb;
104
+ $blogs = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
105
+ }
106
+
107
+ // truncate each blog's log file
108
+ $time = time();
109
+ foreach ($blogs as $blog) {
110
+ $blog_num = !is_null($blog) ? $blog : get_current_blog_id();
111
+ $options = self::getOptions($blog);
112
+ $purge_interval = $options['purge_interval'] * DAY_IN_SECONDS;
113
+
114
+ // purging is disabled for this blog
115
+ if ($purge_interval <= 0) continue;
116
+
117
+ // do perge for this blog
118
+ $file = self::getLogFileName($blog_num);
119
+ if (file_exists($file)) {
120
+ $fp = @fopen($file, 'r');
121
+
122
+ if ($fp !== false) {
123
+ $truncate = false;
124
+ $offset = 0;
125
+
126
+ // find the first non-expired entry
127
+ while (($fields = fgetcsv($fp)) !== false) {
128
+ if (!is_null($fields) && $time > ($fields[0] + $purge_interval)) {
129
+ // we've reached the recent entries -- nothing beyond here will be removed
130
+ break;
131
+ }
132
+
133
+ $truncate = true;
134
+ $offset = @ftell($fp);
135
+ if (false === $offset) {
136
+ break;
137
+ }
138
+ }
139
+
140
+ @fclose($fp);
141
+
142
+ // if any expired entries exist -- remove them from the file
143
+ if ($truncate) {
144
+ self::writeLog(DG_LogLevel::Detail, "Purging log entries for blog #$blog_num.");
145
+ $data = file_get_contents($file, false, null, $offset);
146
+ file_put_contents($file, $data, LOCK_EX);
147
+ }
148
+ }
149
+ }
150
+ }
151
+ }
152
+
153
+ /**
154
+ * Generally not necessary to call external to this class -- only use if generating
155
+ * log entry will take significant resources and you want to avoid this operation
156
+ * if it will not actually be logged.
157
+ *
158
  * @return bool Whether debug logging is currently enabled.
159
  */
160
  public static function logEnabled() {
161
+ $options = self::getOptions();
162
+ return $options['enabled'];
163
+ }
164
+
165
+ /**
166
+ * Gets logging options.
167
+ *
168
+ * @param int $blog ID of the blog to be retrieved in multisite env.
169
+ * @return multitype:unknown Logger options for the blog.
170
+ */
171
+ public static function getOptions($blog = null) {
172
+ $options = DocumentGallery::getOptions($blog);
173
+ return $options['logging'];
174
  }
175
 
176
  /**
177
+ * @param $id int The ID of the blog to retrieve log file name for. Defaults to current blog.
178
  * @return string Full path to log file for current blog.
179
  */
180
+ private static function getLogFileName($id = null) {
181
+ $id = !is_null($id) ? $id : get_current_blog_id();
182
+ return DG_PATH . 'log/' . $id . '.log';
183
+ }
184
+
185
+ /**
186
+ * @param multitype $trace Array containing stack trace to be converted to string.
187
+ * @return string The stack trace in human-readable form.
188
+ */
189
+ private static function getStackTraceString($trace) {
190
+ $trace_str = '';
191
+ $i = 1;
192
+
193
+ foreach($trace as $node) {
194
+ $trace_str .= "#$i ";
195
+
196
+ $file = '';
197
+ if (isset($node['file'])) {
198
+ // convert to relative path from WP root
199
+ $file = str_replace(ABSPATH, '', $node['file']);
200
+ }
201
+
202
+ if (isset($node['line'])) {
203
+ $file .= "({$node['line']})";
204
+ }
205
+
206
+ if ($file) {
207
+ $trace_str .= "$file: ";
208
+ }
209
+
210
+ if(isset($node['class'])) {
211
+ $trace_str .= "{$node['class']}{$node['type']}";
212
+ }
213
+
214
+ if (isset($node['function'])) {
215
+ $args = '';
216
+ if (isset($node['args'])) {
217
+ $args = implode(', ', array_map(array(__CLASS__, 'print_r'), $node['args']));
218
+ }
219
+
220
+ $trace_str .= "{$node['function']}($args)" . PHP_EOL;
221
+ }
222
+ $i++;
223
+ }
224
+
225
+ return $trace_str;
226
  }
227
 
228
  /**
233
  private static function print_r($v) {
234
  return print_r($v, true);
235
  }
236
+
237
+ /**
238
+ * Blocks instantiation. All functions are static.
239
+ */
240
+ private function __construct() {
241
+
242
+ }
243
  }
244
 
245
  /**
inc/class-setup.php CHANGED
@@ -92,11 +92,17 @@ class DG_Setup {
92
  'donate_link' => $donate_link
93
  ),
94
 
95
- // whether to validate DG option structure on save
96
- 'validation' => false,
 
 
 
 
 
 
97
 
98
- // whether to logging DG activity
99
- 'logging' => false
100
  );
101
  }
102
 
@@ -104,7 +110,7 @@ class DG_Setup {
104
  * @return multitype:string The default MIME types to include in gallery.
105
  */
106
  public static function getDefaultMimeTypes() {
107
- return array('application', 'video', 'text', 'audio');
108
  }
109
 
110
  /**
@@ -141,6 +147,7 @@ class DG_Setup {
141
  self::twoPointTwo($options);
142
  self::twoPointThree($options);
143
  self::threePointZeroBeta($options);
 
144
 
145
  // update plugin meta data
146
  $options['meta']['version'] = DG_VERSION;
@@ -262,6 +269,25 @@ class DG_Setup {
262
  }
263
  }
264
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
265
  /**
266
  * Sets up Document Gallery on all blog(s) activated.
267
  * @param bool $networkwide Whether this is a network-wide update (multisite only).
@@ -280,6 +306,9 @@ class DG_Setup {
280
  foreach ($blogs as $blog) {
281
  self::_activate($blog);
282
  }
 
 
 
283
  }
284
 
285
  /**
@@ -324,7 +353,10 @@ class DG_Setup {
324
  foreach ($blogs as $blog) {
325
  self::_uninstall($blog);
326
  }
 
 
327
  }
 
328
  /**
329
  * Runs when DG is uninstalled for an individual blog.
330
  */
92
  'donate_link' => $donate_link
93
  ),
94
 
95
+ // logging options
96
+ 'logging' => array(
97
+ // TODO: more granular -- log_level instead of blanket enable/disable
98
+ 'enabled' => false,
99
+
100
+ // max age of log entry (days)
101
+ 'purge_interval' => 7
102
+ ),
103
 
104
+ // whether to validate DG option structure on save
105
+ 'validation' => false
106
  );
107
  }
108
 
110
  * @return multitype:string The default MIME types to include in gallery.
111
  */
112
  public static function getDefaultMimeTypes() {
113
+ return array('application', 'video', 'text', 'audio', 'image');
114
  }
115
 
116
  /**
147
  self::twoPointTwo($options);
148
  self::twoPointThree($options);
149
  self::threePointZeroBeta($options);
150
+ self::threePointOne($options);
151
 
152
  // update plugin meta data
153
  $options['meta']['version'] = DG_VERSION;
269
  }
270
  }
271
 
272
+ /**
273
+ * Flat logging option split out into multiple options in a nested array.
274
+ *
275
+ * Added scheduled log purge event to handle rollovers.
276
+ *
277
+ * @param unknown $options
278
+ */
279
+ private static function threePointOne(&$options) {
280
+ if (version_compare($options['meta']['version'], '3.1', '<')) {
281
+ $logging_enabled = $options['logging'];
282
+ $options['logging'] = array(
283
+ 'enabled' => $logging_enabled,
284
+ 'purge_interval' => 7);
285
+
286
+ // purge log entries regularly
287
+ wp_schedule_event(time(), 'daily', DG_Logger::PurgeLogsAction);
288
+ }
289
+ }
290
+
291
  /**
292
  * Sets up Document Gallery on all blog(s) activated.
293
  * @param bool $networkwide Whether this is a network-wide update (multisite only).
306
  foreach ($blogs as $blog) {
307
  self::_activate($blog);
308
  }
309
+
310
+ // handle purging log entries regularly
311
+ wp_schedule_event(time(), 'daily', DG_Logger::PurgeLogsAction);
312
  }
313
 
314
  /**
353
  foreach ($blogs as $blog) {
354
  self::_uninstall($blog);
355
  }
356
+
357
+ wp_clear_scheduled_hook(DG_Logger::PurgeLogsAction);
358
  }
359
+
360
  /**
361
  * Runs when DG is uninstalled for an individual blog.
362
  */
inc/class-thumber.php CHANGED
@@ -51,11 +51,12 @@ class DG_Thumber {
51
  /**
52
  * Wraps generation of thumbnails for various attachment filetypes.
53
  *
54
- * @param int $ID Document ID
55
- * @param int $pg Page number to get thumb from.
56
- * @return str URL to the thumbnail.
 
57
  */
58
- public static function getThumbnail($ID, $pg = 1) {
59
  static $start = null;
60
  if (is_null($start)) {
61
  $start = time();
@@ -65,6 +66,11 @@ class DG_Thumber {
65
 
66
  // if we haven't saved a thumb, generate one
67
  if (empty($options['thumbs'][$ID])) {
 
 
 
 
 
68
  // prevent page timing out or user waiting too long for page
69
  if ((time() - $start) > $options['timeout']) {
70
  return self::getDefaultThumbnail($ID, $pg);
51
  /**
52
  * Wraps generation of thumbnails for various attachment filetypes.
53
  *
54
+ * @param int $ID Document ID
55
+ * @param int $pg Page number to get thumb from.
56
+ * @param bool $generate_if_missing Whether to attempt generating the thumbnail if missing.
57
+ * @return str URL to the thumbnail.
58
  */
59
+ public static function getThumbnail($ID, $pg = 1, $generate_if_missing = true) {
60
  static $start = null;
61
  if (is_null($start)) {
62
  $start = time();
66
 
67
  // if we haven't saved a thumb, generate one
68
  if (empty($options['thumbs'][$ID])) {
69
+ // short-circuit generation if not required
70
+ if (!$generate_if_missing) {
71
+ return null;
72
+ }
73
+
74
  // prevent page timing out or user waiting too long for page
75
  if ((time() - $start) > $options['timeout']) {
76
  return self::getDefaultThumbnail($ID, $pg);
languages/document-gallery.pot CHANGED
@@ -2,9 +2,9 @@
2
  # This file is distributed under the same license as the Document Gallery package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Document Gallery 3.0\n"
6
  "Report-Msgid-Bugs-To: http://wordpress.org/support/plugin/document-gallery\n"
7
- "POT-Creation-Date: 2015-03-13 01:01:32+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -20,7 +20,7 @@ msgstr ""
20
  msgid "Thumbnail Management"
21
  msgstr ""
22
 
23
- #: admin/class-admin.php:32 admin/class-admin.php:1148
24
  msgid "Logging"
25
  msgstr ""
26
 
@@ -29,6 +29,7 @@ msgid "Advanced"
29
  msgstr ""
30
 
31
  #: admin/class-admin.php:44 admin/class-admin.php:98
 
32
  msgid "Document Gallery Settings"
33
  msgstr ""
34
 
@@ -40,318 +41,398 @@ msgstr ""
40
  msgid "Donate"
41
  msgstr ""
42
 
43
- #. #-#-#-#-# plugin.pot (Document Gallery 3.0) #-#-#-#-#
44
  #. Plugin Name of the plugin/theme
45
  #: admin/class-admin.php:99
46
  msgid "Document Gallery"
47
  msgstr ""
48
 
49
- #: admin/class-admin.php:148
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  msgid "Default Settings"
51
  msgstr ""
52
 
53
- #: admin/class-admin.php:152
54
  msgid "Thumbnail Generation"
55
  msgstr ""
56
 
57
- #: admin/class-admin.php:156
58
  msgid "Custom CSS"
59
  msgstr ""
60
 
61
- #: admin/class-admin.php:168
62
  msgid "Link to attachment page rather than to file"
63
  msgstr ""
64
 
65
- #: admin/class-admin.php:181
66
  msgid "The number of columns to display when not rendering descriptions."
67
  msgstr ""
68
 
69
- #: admin/class-admin.php:193
70
  msgid "Include document descriptions"
71
  msgstr ""
72
 
73
- #: admin/class-admin.php:205
74
  msgid "Use auto-generated document thumbnails"
75
  msgstr ""
76
 
77
- #: admin/class-admin.php:218
78
  msgid "Ascending or descending sorting of documents"
79
  msgstr ""
80
 
81
- #: admin/class-admin.php:231
82
  msgid "Which field to order documents by"
83
  msgstr ""
84
 
85
- #: admin/class-admin.php:244
86
  msgid ""
87
  "Whether matched documents must have all taxa_names (AND) or at least one (OR)"
88
  msgstr ""
89
 
90
- #: admin/class-admin.php:257
91
  msgid "Limit the number of documents included. -1 means no limit."
92
  msgstr ""
93
 
94
- #: admin/class-admin.php:270
95
  msgid ""
96
  "Comma-delimited list of <a href=\"http://en.wikipedia.org/wiki/"
97
  "Internet_media_type#List_of_common_media_types\">MIME types</a>."
98
  msgstr ""
99
 
100
- #: admin/class-admin.php:283
101
  msgid "Which post status to look for when querying documents."
102
  msgstr ""
103
 
104
- #: admin/class-admin.php:296
105
  msgid "Which post type to look for when querying documents."
106
  msgstr ""
107
 
108
- #: admin/class-admin.php:308
 
 
 
 
109
  msgid "Locally generate thumbnails for audio & video files."
110
  msgstr ""
111
 
112
- #: admin/class-admin.php:321
113
  msgid ""
114
  "Use <a href=\"http://www.ghostscript.com/\" target=\"_blank\">Ghostscript</"
115
  "a> for faster local PDF processing (compared to Imagick)."
116
  msgstr ""
117
 
118
- #: admin/class-admin.php:322
119
  msgid ""
120
  "Your server is not configured to run <a href=\"http://www.ghostscript.com/\" "
121
  "target=\"_blank\">Ghostscript</a>."
122
  msgstr ""
123
 
124
- #: admin/class-admin.php:336
125
  msgid ""
126
  "Use <a href=\"http://www.php.net/manual/en/book.imagick.php\" target=\"_blank"
127
  "\">Imagick</a> to handle lots of filetypes locally."
128
  msgstr ""
129
 
130
- #: admin/class-admin.php:337
131
  msgid ""
132
  "Your server is not configured to run <a href=\"http://www.php.net/manual/en/"
133
  "book.imagick.php\" target=\"_blank\">Imagick</a>."
134
  msgstr ""
135
 
136
- #: admin/class-admin.php:359
137
- msgid "The max width and height (in pixels) that thumbnails will be generated."
138
  msgstr ""
139
 
140
  #: admin/class-admin.php:388
 
 
 
 
141
  msgid "Advanced Thumbnail Generation"
142
  msgstr ""
143
 
144
- #: admin/class-admin.php:400
 
 
 
 
145
  msgid "Whether to log debug and error information related to Document Gallery."
146
  msgstr ""
147
 
148
- #: admin/class-admin.php:412
 
 
 
 
 
 
 
 
 
 
 
 
149
  msgid ""
150
  "Whether option structure should be validated before save. This is not "
151
  "generally necessary."
152
  msgstr ""
153
 
154
- #: admin/class-admin.php:425
 
 
 
 
155
  msgid ""
156
  "Max number of seconds to wait for thumbnail generation before defaulting to "
157
  "filetype icons."
158
  msgstr ""
159
 
160
- #: admin/class-admin.php:426
161
  msgid ""
162
  "Note that generation will continue where timeout happened next time the "
163
  "gallery is loaded."
164
  msgstr ""
165
 
166
- #: admin/class-admin.php:438
 
 
 
 
167
  msgid "Successfully auto-detected the location of Ghostscript."
168
  msgstr ""
169
 
170
- #: admin/class-admin.php:439
171
  msgid "Failed to auto-detect the location of Ghostscript."
172
  msgstr ""
173
 
174
- #: admin/class-admin.php:443
175
  msgid "Options Array Dump"
176
  msgstr ""
177
 
178
- #: admin/class-admin.php:490
179
  msgid "Invalid width given: "
180
  msgstr ""
181
 
182
- #: admin/class-admin.php:503
183
  msgid "Invalid height given: "
184
  msgstr ""
185
 
186
- #: admin/class-admin.php:658
187
  msgid "File extension doesn't match the MIME type of the image: "
188
  msgstr ""
189
 
190
- #: admin/class-admin.php:664
191
  msgid "Uploaded file size exceeds the allowable limit: "
192
  msgstr ""
193
 
194
- #: admin/class-admin.php:671
195
  msgid "Uploaded file is not an image: "
196
  msgstr ""
197
 
198
- #: admin/class-admin.php:680
199
  msgid "Failed to get uploaded file: "
200
  msgstr ""
201
 
202
- #: admin/class-admin.php:717
203
  msgid "Invalid Ghostscript path given: "
204
  msgstr ""
205
 
206
- #: admin/class-admin.php:728
207
  msgid "Invalid timeout given: "
208
  msgstr ""
209
 
210
- #: admin/class-admin.php:759
 
 
 
 
211
  msgid ""
212
  "The following values will be used by default in the shortcode. You can still "
213
  "manually set each of these values in each individual shortcode."
214
  msgstr ""
215
 
216
- #: admin/class-admin.php:766
217
  msgid "Select which tools to use when generating thumbnails."
218
  msgstr ""
219
 
220
- #: admin/class-admin.php:775
221
  msgid ""
222
  "Enter custom CSS styling for use with document galleries. To see which ids "
223
  "and classes you can style, take a look at <a href=\"%s\" target=\"_blank"
224
  "\">style.css</a>."
225
  msgstr ""
226
 
227
- #: admin/class-admin.php:793
228
  msgid ""
229
  "Unless you <em>really</em> know what you're doing, you should not touch "
230
  "these values."
231
  msgstr ""
232
 
233
- #: admin/class-admin.php:796
234
  msgid ""
235
  "NOTE: <code>exec()</code> is not accessible. Ghostscript will not function."
236
  msgstr ""
237
 
238
- #: admin/class-admin.php:807
239
  msgid ""
240
  "The following <em>readonly text</em> should be provided when <a href="
241
  "\"http://wordpress.org/support/plugin/document-gallery\" target=\"_blank"
242
  "\">reporting a bug</a>:"
243
  msgstr ""
244
 
245
- #: admin/class-admin.php:916
246
  msgid "Select All"
247
  msgstr ""
248
 
249
- #: admin/class-admin.php:919
250
  msgid "Thumbnail"
251
  msgstr ""
252
 
253
- #: admin/class-admin.php:920
254
  msgid "File name"
255
  msgstr ""
256
 
257
- #: admin/class-admin.php:921
258
  msgid "Description"
259
  msgstr ""
260
 
261
- #: admin/class-admin.php:923 admin/class-admin.php:1078
262
  msgid "Date"
263
  msgstr ""
264
 
265
- #: admin/class-admin.php:926
266
  msgid "Delete Selected"
267
  msgstr ""
268
 
269
- #: admin/class-admin.php:928
270
  msgid "item"
271
  msgid_plural "items"
272
  msgstr[0] ""
273
  msgstr[1] ""
274
 
275
- #: admin/class-admin.php:931
276
  msgid "Go to the first page"
277
  msgstr ""
278
 
279
- #: admin/class-admin.php:932
280
  msgid "Go to the previous page"
281
  msgstr ""
282
 
283
- #: admin/class-admin.php:934
284
  msgid "Current page"
285
  msgstr ""
286
 
287
- #: admin/class-admin.php:934
288
  msgid "of"
289
  msgstr ""
290
 
291
- #: admin/class-admin.php:935
292
  msgid "Go to the next page"
293
  msgstr ""
294
 
295
- #: admin/class-admin.php:936
296
  msgid "Go to the last page"
297
  msgstr ""
298
 
299
- #: admin/class-admin.php:938
300
  msgid "items per page"
301
  msgstr ""
302
 
303
- #: admin/class-admin.php:972
304
  msgid "View"
305
  msgstr ""
306
 
307
- #: admin/class-admin.php:973
308
  msgid "attachment page"
309
  msgstr ""
310
 
311
- #: admin/class-admin.php:973
312
  msgid "Attachment not found"
313
  msgstr ""
314
 
315
- #: admin/class-admin.php:1000
316
  msgid "<b>Thumbnail</b> for <i><b>Document Gallery</b></i>"
317
  msgstr ""
318
 
319
- #: admin/class-admin.php:1079
320
  msgid "Level"
321
  msgstr ""
322
 
323
- #: admin/class-admin.php:1080
324
  msgid "Message"
325
  msgstr ""
326
 
327
- #: admin/class-admin.php:1089
328
  msgid "Expand All"
329
  msgstr ""
330
 
331
- #: admin/class-admin.php:1092
332
  msgid "Collapse All"
333
  msgstr ""
334
 
335
- #: admin/class-admin.php:1141
336
  msgid "Clear Log"
337
  msgstr ""
338
 
339
- #: admin/class-admin.php:1148
340
  msgid "There are no log entries at this time."
341
  msgstr ""
342
 
343
- #: admin/class-admin.php:1148
344
  msgid "For Your information:"
345
  msgstr ""
346
 
347
- #: admin/class-admin.php:1148
348
  msgid "is turned ON"
349
  msgstr ""
350
 
351
- #: admin/class-admin.php:1148
352
  msgid "is turned OFF"
353
  msgstr ""
354
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
355
  #: inc/class-gallery.php:82
356
  msgid "Generated using Document Gallery. Get yours here: "
357
  msgstr ""
@@ -384,43 +465,43 @@ msgstr ""
384
  msgid "Failed to set Imagick page number"
385
  msgstr ""
386
 
387
- #: inc/class-thumber.php:81
388
  msgid "Attempting to generate thumbnail for attachment #%d with (%s)"
389
  msgstr ""
390
 
391
- #: inc/class-thumber.php:154
392
  msgid "Could not open file: "
393
  msgstr ""
394
 
395
- #: inc/class-thumber.php:159
396
  msgid "Could not write file: "
397
  msgstr ""
398
 
399
- #: inc/class-thumber.php:196
400
  msgid "Failed to open file in Imagick: "
401
  msgstr ""
402
 
403
- #: inc/class-thumber.php:207
404
  msgid "Failed to save image in Imagick: "
405
  msgstr ""
406
 
407
- #: inc/class-thumber.php:265
408
  msgid "Ghostscript failed: "
409
  msgstr ""
410
 
411
- #: inc/class-thumber.php:565
412
  msgid "Thumbnail Generators: "
413
  msgstr ""
414
 
415
- #: inc/class-thumber.php:576
416
  msgid "No thumbnail generators enabled."
417
  msgstr ""
418
 
419
- #: inc/class-thumber.php:626
420
  msgid "Failed to get image editor: "
421
  msgstr ""
422
 
423
- #: inc/class-thumber.php:638
424
  msgid "Failed to save image: "
425
  msgstr ""
426
 
2
  # This file is distributed under the same license as the Document Gallery package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Document Gallery 3.1\n"
6
  "Report-Msgid-Bugs-To: http://wordpress.org/support/plugin/document-gallery\n"
7
+ "POT-Creation-Date: 2015-05-17 00:41:05+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
20
  msgid "Thumbnail Management"
21
  msgstr ""
22
 
23
+ #: admin/class-admin.php:32 admin/class-admin.php:1216
24
  msgid "Logging"
25
  msgstr ""
26
 
29
  msgstr ""
30
 
31
  #: admin/class-admin.php:44 admin/class-admin.php:98
32
+ #: admin/media-manager-template.php:5
33
  msgid "Document Gallery Settings"
34
  msgstr ""
35
 
41
  msgid "Donate"
42
  msgstr ""
43
 
44
+ #. #-#-#-#-# plugin.pot (Document Gallery 3.1) #-#-#-#-#
45
  #. Plugin Name of the plugin/theme
46
  #: admin/class-admin.php:99
47
  msgid "Document Gallery"
48
  msgstr ""
49
 
50
+ #: admin/class-admin.php:126
51
+ msgid "Create Document Gallery"
52
+ msgstr ""
53
+
54
+ #: admin/class-admin.php:127
55
+ msgid "Create a new Document Gallery"
56
+ msgstr ""
57
+
58
+ #: admin/class-admin.php:128
59
+ msgid "&#8592; Cancel Document Gallery"
60
+ msgstr ""
61
+
62
+ #: admin/class-admin.php:129
63
+ msgid "Update Document Gallery"
64
+ msgstr ""
65
+
66
+ #: admin/class-admin.php:130
67
+ msgid "Insert Document Gallery"
68
+ msgstr ""
69
+
70
+ #: admin/class-admin.php:131 admin/class-admin.php:132
71
+ msgid "Add to Document Gallery"
72
+ msgstr ""
73
+
74
+ #: admin/class-admin.php:133
75
+ msgid "Edit Document Gallery"
76
+ msgstr ""
77
+
78
+ #: admin/class-admin.php:177
79
  msgid "Default Settings"
80
  msgstr ""
81
 
82
+ #: admin/class-admin.php:181
83
  msgid "Thumbnail Generation"
84
  msgstr ""
85
 
86
+ #: admin/class-admin.php:185
87
  msgid "Custom CSS"
88
  msgstr ""
89
 
90
+ #: admin/class-admin.php:197
91
  msgid "Link to attachment page rather than to file"
92
  msgstr ""
93
 
94
+ #: admin/class-admin.php:210
95
  msgid "The number of columns to display when not rendering descriptions."
96
  msgstr ""
97
 
98
+ #: admin/class-admin.php:222 admin/media-manager-template.php:43
99
  msgid "Include document descriptions"
100
  msgstr ""
101
 
102
+ #: admin/class-admin.php:234 admin/media-manager-template.php:50
103
  msgid "Use auto-generated document thumbnails"
104
  msgstr ""
105
 
106
+ #: admin/class-admin.php:247 admin/media-manager-template.php:72
107
  msgid "Ascending or descending sorting of documents"
108
  msgstr ""
109
 
110
+ #: admin/class-admin.php:260 admin/media-manager-template.php:57
111
  msgid "Which field to order documents by"
112
  msgstr ""
113
 
114
+ #: admin/class-admin.php:273
115
  msgid ""
116
  "Whether matched documents must have all taxa_names (AND) or at least one (OR)"
117
  msgstr ""
118
 
119
+ #: admin/class-admin.php:286
120
  msgid "Limit the number of documents included. -1 means no limit."
121
  msgstr ""
122
 
123
+ #: admin/class-admin.php:299
124
  msgid ""
125
  "Comma-delimited list of <a href=\"http://en.wikipedia.org/wiki/"
126
  "Internet_media_type#List_of_common_media_types\">MIME types</a>."
127
  msgstr ""
128
 
129
+ #: admin/class-admin.php:312
130
  msgid "Which post status to look for when querying documents."
131
  msgstr ""
132
 
133
+ #: admin/class-admin.php:325
134
  msgid "Which post type to look for when querying documents."
135
  msgstr ""
136
 
137
+ #: admin/class-admin.php:329
138
+ msgid "Audio/Video"
139
+ msgstr ""
140
+
141
+ #: admin/class-admin.php:337
142
  msgid "Locally generate thumbnails for audio & video files."
143
  msgstr ""
144
 
145
+ #: admin/class-admin.php:350
146
  msgid ""
147
  "Use <a href=\"http://www.ghostscript.com/\" target=\"_blank\">Ghostscript</"
148
  "a> for faster local PDF processing (compared to Imagick)."
149
  msgstr ""
150
 
151
+ #: admin/class-admin.php:351
152
  msgid ""
153
  "Your server is not configured to run <a href=\"http://www.ghostscript.com/\" "
154
  "target=\"_blank\">Ghostscript</a>."
155
  msgstr ""
156
 
157
+ #: admin/class-admin.php:365
158
  msgid ""
159
  "Use <a href=\"http://www.php.net/manual/en/book.imagick.php\" target=\"_blank"
160
  "\">Imagick</a> to handle lots of filetypes locally."
161
  msgstr ""
162
 
163
+ #: admin/class-admin.php:366
164
  msgid ""
165
  "Your server is not configured to run <a href=\"http://www.php.net/manual/en/"
166
  "book.imagick.php\" target=\"_blank\">Imagick</a>."
167
  msgstr ""
168
 
169
+ #: admin/class-admin.php:371
170
+ msgid "Max Thumbnail Dimensions"
171
  msgstr ""
172
 
173
  #: admin/class-admin.php:388
174
+ msgid "The max width and height (in pixels) that thumbnails will be generated."
175
+ msgstr ""
176
+
177
+ #: admin/class-admin.php:417
178
  msgid "Advanced Thumbnail Generation"
179
  msgstr ""
180
 
181
+ #: admin/class-admin.php:421
182
+ msgid "Logging Enabled"
183
+ msgstr ""
184
+
185
+ #: admin/class-admin.php:429
186
  msgid "Whether to log debug and error information related to Document Gallery."
187
  msgstr ""
188
 
189
+ #: admin/class-admin.php:433
190
+ msgid "Logging Purge Interval"
191
+ msgstr ""
192
+
193
+ #: admin/class-admin.php:442
194
+ msgid "Number of days to keep old log entries (0 disables purging)."
195
+ msgstr ""
196
+
197
+ #: admin/class-admin.php:446
198
+ msgid "Option Validation"
199
+ msgstr ""
200
+
201
+ #: admin/class-admin.php:454
202
  msgid ""
203
  "Whether option structure should be validated before save. This is not "
204
  "generally necessary."
205
  msgstr ""
206
 
207
+ #: admin/class-admin.php:458
208
+ msgid "Thumbnail Generation Timeout"
209
+ msgstr ""
210
+
211
+ #: admin/class-admin.php:467
212
  msgid ""
213
  "Max number of seconds to wait for thumbnail generation before defaulting to "
214
  "filetype icons."
215
  msgstr ""
216
 
217
+ #: admin/class-admin.php:468
218
  msgid ""
219
  "Note that generation will continue where timeout happened next time the "
220
  "gallery is loaded."
221
  msgstr ""
222
 
223
+ #: admin/class-admin.php:471
224
+ msgid "Ghostscript Absolute Path"
225
+ msgstr ""
226
+
227
+ #: admin/class-admin.php:480
228
  msgid "Successfully auto-detected the location of Ghostscript."
229
  msgstr ""
230
 
231
+ #: admin/class-admin.php:481
232
  msgid "Failed to auto-detect the location of Ghostscript."
233
  msgstr ""
234
 
235
+ #: admin/class-admin.php:485
236
  msgid "Options Array Dump"
237
  msgstr ""
238
 
239
+ #: admin/class-admin.php:541
240
  msgid "Invalid width given: "
241
  msgstr ""
242
 
243
+ #: admin/class-admin.php:554
244
  msgid "Invalid height given: "
245
  msgstr ""
246
 
247
+ #: admin/class-admin.php:709
248
  msgid "File extension doesn't match the MIME type of the image: "
249
  msgstr ""
250
 
251
+ #: admin/class-admin.php:715
252
  msgid "Uploaded file size exceeds the allowable limit: "
253
  msgstr ""
254
 
255
+ #: admin/class-admin.php:722
256
  msgid "Uploaded file is not an image: "
257
  msgstr ""
258
 
259
+ #: admin/class-admin.php:731
260
  msgid "Failed to get uploaded file: "
261
  msgstr ""
262
 
263
+ #: admin/class-admin.php:768
264
  msgid "Invalid Ghostscript path given: "
265
  msgstr ""
266
 
267
+ #: admin/class-admin.php:779
268
  msgid "Invalid timeout given: "
269
  msgstr ""
270
 
271
+ #: admin/class-admin.php:794
272
+ msgid "Invalid logging purge interval given: "
273
+ msgstr ""
274
+
275
+ #: admin/class-admin.php:819
276
  msgid ""
277
  "The following values will be used by default in the shortcode. You can still "
278
  "manually set each of these values in each individual shortcode."
279
  msgstr ""
280
 
281
+ #: admin/class-admin.php:826
282
  msgid "Select which tools to use when generating thumbnails."
283
  msgstr ""
284
 
285
+ #: admin/class-admin.php:835
286
  msgid ""
287
  "Enter custom CSS styling for use with document galleries. To see which ids "
288
  "and classes you can style, take a look at <a href=\"%s\" target=\"_blank"
289
  "\">style.css</a>."
290
  msgstr ""
291
 
292
+ #: admin/class-admin.php:853
293
  msgid ""
294
  "Unless you <em>really</em> know what you're doing, you should not touch "
295
  "these values."
296
  msgstr ""
297
 
298
+ #: admin/class-admin.php:856
299
  msgid ""
300
  "NOTE: <code>exec()</code> is not accessible. Ghostscript will not function."
301
  msgstr ""
302
 
303
+ #: admin/class-admin.php:867
304
  msgid ""
305
  "The following <em>readonly text</em> should be provided when <a href="
306
  "\"http://wordpress.org/support/plugin/document-gallery\" target=\"_blank"
307
  "\">reporting a bug</a>:"
308
  msgstr ""
309
 
310
+ #: admin/class-admin.php:976
311
  msgid "Select All"
312
  msgstr ""
313
 
314
+ #: admin/class-admin.php:979
315
  msgid "Thumbnail"
316
  msgstr ""
317
 
318
+ #: admin/class-admin.php:980
319
  msgid "File name"
320
  msgstr ""
321
 
322
+ #: admin/class-admin.php:981
323
  msgid "Description"
324
  msgstr ""
325
 
326
+ #: admin/class-admin.php:983 admin/class-admin.php:1147
327
  msgid "Date"
328
  msgstr ""
329
 
330
+ #: admin/class-admin.php:986
331
  msgid "Delete Selected"
332
  msgstr ""
333
 
334
+ #: admin/class-admin.php:988
335
  msgid "item"
336
  msgid_plural "items"
337
  msgstr[0] ""
338
  msgstr[1] ""
339
 
340
+ #: admin/class-admin.php:991
341
  msgid "Go to the first page"
342
  msgstr ""
343
 
344
+ #: admin/class-admin.php:992
345
  msgid "Go to the previous page"
346
  msgstr ""
347
 
348
+ #: admin/class-admin.php:994
349
  msgid "Current page"
350
  msgstr ""
351
 
352
+ #: admin/class-admin.php:994
353
  msgid "of"
354
  msgstr ""
355
 
356
+ #: admin/class-admin.php:995
357
  msgid "Go to the next page"
358
  msgstr ""
359
 
360
+ #: admin/class-admin.php:996
361
  msgid "Go to the last page"
362
  msgstr ""
363
 
364
+ #: admin/class-admin.php:998
365
  msgid "items per page"
366
  msgstr ""
367
 
368
+ #: admin/class-admin.php:1032
369
  msgid "View"
370
  msgstr ""
371
 
372
+ #: admin/class-admin.php:1033
373
  msgid "attachment page"
374
  msgstr ""
375
 
376
+ #: admin/class-admin.php:1033
377
  msgid "Attachment not found"
378
  msgstr ""
379
 
380
+ #: admin/class-admin.php:1060
381
  msgid "<b>Thumbnail</b> for <i><b>Document Gallery</b></i>"
382
  msgstr ""
383
 
384
+ #: admin/class-admin.php:1148
385
  msgid "Level"
386
  msgstr ""
387
 
388
+ #: admin/class-admin.php:1149
389
  msgid "Message"
390
  msgstr ""
391
 
392
+ #: admin/class-admin.php:1157
393
  msgid "Expand All"
394
  msgstr ""
395
 
396
+ #: admin/class-admin.php:1160
397
  msgid "Collapse All"
398
  msgstr ""
399
 
400
+ #: admin/class-admin.php:1209
401
  msgid "Clear Log"
402
  msgstr ""
403
 
404
+ #: admin/class-admin.php:1216
405
  msgid "There are no log entries at this time."
406
  msgstr ""
407
 
408
+ #: admin/class-admin.php:1216
409
  msgid "For Your information:"
410
  msgstr ""
411
 
412
+ #: admin/class-admin.php:1216
413
  msgid "is turned ON"
414
  msgstr ""
415
 
416
+ #: admin/class-admin.php:1216
417
  msgid "is turned OFF"
418
  msgstr ""
419
 
420
+ #: admin/media-manager-template.php:9
421
+ msgid "Link To"
422
+ msgstr ""
423
+
424
+ #: admin/media-manager-template.php:12
425
+ msgid "Media File"
426
+ msgstr ""
427
+
428
+ #: admin/media-manager-template.php:15
429
+ msgid "Attachment Page"
430
+ msgstr ""
431
+
432
+ #: admin/media-manager-template.php:23
433
+ msgid "Columns"
434
+ msgstr ""
435
+
436
  #: inc/class-gallery.php:82
437
  msgid "Generated using Document Gallery. Get yours here: "
438
  msgstr ""
465
  msgid "Failed to set Imagick page number"
466
  msgstr ""
467
 
468
+ #: inc/class-thumber.php:87
469
  msgid "Attempting to generate thumbnail for attachment #%d with (%s)"
470
  msgstr ""
471
 
472
+ #: inc/class-thumber.php:160
473
  msgid "Could not open file: "
474
  msgstr ""
475
 
476
+ #: inc/class-thumber.php:165
477
  msgid "Could not write file: "
478
  msgstr ""
479
 
480
+ #: inc/class-thumber.php:202
481
  msgid "Failed to open file in Imagick: "
482
  msgstr ""
483
 
484
+ #: inc/class-thumber.php:213
485
  msgid "Failed to save image in Imagick: "
486
  msgstr ""
487
 
488
+ #: inc/class-thumber.php:271
489
  msgid "Ghostscript failed: "
490
  msgstr ""
491
 
492
+ #: inc/class-thumber.php:571
493
  msgid "Thumbnail Generators: "
494
  msgstr ""
495
 
496
+ #: inc/class-thumber.php:582
497
  msgid "No thumbnail generators enabled."
498
  msgstr ""
499
 
500
+ #: inc/class-thumber.php:632
501
  msgid "Failed to get image editor: "
502
  msgstr ""
503
 
504
+ #: inc/class-thumber.php:644
505
  msgid "Failed to save image: "
506
  msgstr ""
507
 
screenshot-1.png CHANGED
Binary file
screenshot-2.png CHANGED
Binary file
screenshot-3.png CHANGED
Binary file
screenshot-4.png ADDED
Binary file
screenshot-5.png ADDED
Binary file